From 16f4b49c436a1017afc308b006cadc451002b5e6 Mon Sep 17 00:00:00 2001 From: Bianca Henderson Date: Fri, 29 May 2026 17:31:39 -0400 Subject: [PATCH] Manual backport of SonarQube configuration to stable-5 branch (#1137) --- .github/workflows/all_green_check.yaml | 142 +++++++++++++++++++++++ .github/workflows/linters.yaml | 1 + .github/workflows/sanity-tests.yaml | 1 + .github/workflows/sonarcloud.yml | 68 +++++++++++ .github/workflows/unit-tests.yaml | 1 + .gitignore | 3 + CI.md | 37 ++++++ README.md | 154 +++++++++++++------------ SONARCLOUD.md | 32 +++++ sonar-project.properties | 14 +++ tests/unit/requirements.txt | 1 + 11 files changed, 383 insertions(+), 71 deletions(-) create mode 100644 .github/workflows/all_green_check.yaml create mode 100644 .github/workflows/sonarcloud.yml create mode 100644 CI.md create mode 100644 SONARCLOUD.md create mode 100644 sonar-project.properties diff --git a/.github/workflows/all_green_check.yaml b/.github/workflows/all_green_check.yaml new file mode 100644 index 00000000..3b301ac9 --- /dev/null +++ b/.github/workflows/all_green_check.yaml @@ -0,0 +1,142 @@ +--- +name: all_green + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +on: # yamllint disable-line rule:truthy + pull_request: + types: + - opened + - reopened + - synchronize + branches: + - main + - stable-* + push: + branches: + - main + - stable-* + +jobs: + linters: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/linters.yaml + + sanity: + uses: ./.github/workflows/sanity-tests.yaml + + units: + uses: ./.github/workflows/unit-tests.yaml + + coverage: + name: Unit test coverage + runs-on: ubuntu-latest + needs: + - sanity + - units + env: + # stable-5 is tested against ansible-core stable-2.18 (see integration-tests.yaml). + ANSIBLE_CORE_REF: "stable-2.18" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Ansible (ansible-test) + run: | + python -m pip install --upgrade pip + python -m pip install "https://github.com/ansible/ansible/archive/${ANSIBLE_CORE_REF}.tar.gz" + + - name: Run unit tests with coverage + run: ansible-test units --venv --coverage --python 3.12 --requirements + + - name: Combine and emit coverage XML + run: | + ansible-test coverage combine --venv --python 3.12 --requirements + ansible-test coverage xml --venv --python 3.12 --requirements + + - name: Prepare coverage.xml for SonarCloud + run: | + set -euo pipefail + mkdir -p "${GITHUB_WORKSPACE}" + xml=$(find tests/output/reports -maxdepth 1 -name '*.xml' ! -name '*powershell*' | head -1) + test -n "${xml}" + cp "${xml}" "${GITHUB_WORKSPACE}/coverage.xml" + # Strip workspace prefix so Sonar sees repo-relative paths (same idea as amazon.aws path rewrite) + sed -i "s#${GITHUB_WORKSPACE}/##g" "${GITHUB_WORKSPACE}/coverage.xml" + + - name: Upload coverage artifact + uses: actions/upload-artifact@v4 + with: + name: coverage + path: ${{ github.workspace }}/coverage.xml + + all_green: + if: ${{ always() }} + needs: + - linters + - sanity + - units + - coverage + runs-on: ubuntu-latest + steps: + - run: | + python -c " + import sys + + required = ['sanity', 'units', 'coverage'] + if '${{ github.event_name }}' == 'pull_request': + required = ['linters', 'sanity', 'units', 'coverage'] + results = { + 'linters': '${{ needs.linters.result }}', + 'sanity': '${{ needs.sanity.result }}', + 'units': '${{ needs.units.result }}', + 'coverage': '${{ needs.coverage.result }}', + } + + for name in required: + if results[name] == 'failure': + print(f'all_green: required job failed: {name} results={results}', file=sys.stderr) + sys.exit(1) + + # cancel-in-progress superseded this run; do not fail (newer run is authoritative) + if any(v == 'cancelled' for v in results.values()): + print( + 'all_green: one or more jobs cancelled (usually concurrency); skipping strict gate.', + results, + ) + sys.exit(0) + + not_ok = [j for j in required if results[j] != 'success'] + if not_ok: + print(f'all_green: required jobs not success: {not_ok} results={results}', file=sys.stderr) + sys.exit(1) + + for job, status in results.items(): + if job not in required and status not in ('success', 'skipped'): + print(f'all_green: unexpected {job}={status} results={results}', file=sys.stderr) + sys.exit(1) + + print('all_green OK', results) + " + + sonarcloud: + name: SonarCloud scan + needs: + - all_green + - coverage + if: >- + ${{ needs.all_green.result == 'success' + && secrets.ANSIBLE_COLLECTIONS_ORG_SONAR_TOKEN_CICD_BOT != '' + && (github.event_name == 'push' + || (github.event_name == 'pull_request' + && github.event.pull_request.head.repo.full_name == github.repository)) }} + uses: ./.github/workflows/sonarcloud.yml + secrets: + ANSIBLE_COLLECTIONS_ORG_SONAR_TOKEN_CICD_BOT: ${{ secrets.ANSIBLE_COLLECTIONS_ORG_SONAR_TOKEN_CICD_BOT }} diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index d185054e..3c308a60 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -5,6 +5,7 @@ concurrency: cancel-in-progress: true on: + workflow_call: pull_request: branches: - main diff --git a/.github/workflows/sanity-tests.yaml b/.github/workflows/sanity-tests.yaml index 044f6def..c442c793 100644 --- a/.github/workflows/sanity-tests.yaml +++ b/.github/workflows/sanity-tests.yaml @@ -5,6 +5,7 @@ concurrency: cancel-in-progress: true on: + workflow_call: pull_request: branches: - main diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml new file mode 100644 index 00000000..40521911 --- /dev/null +++ b/.github/workflows/sonarcloud.yml @@ -0,0 +1,68 @@ +## SonarCloud scan (reusable) +# +# Invoked from **all_green** after the aggregate gate and **coverage** succeed. Uses the **caller's** +# **pull_request** / **push** event so **actions/checkout** can use **github.event.pull_request.head.sha** +# on PRs (Sonar-compliant). Not triggered by **workflow_run** + **workflow_run.head_sha** checkout. + +--- +name: SonarCloud + +on: + workflow_call: + secrets: + ANSIBLE_COLLECTIONS_ORG_SONAR_TOKEN_CICD_BOT: + required: true + +permissions: + contents: read + pull-requests: read + +jobs: + scan: + name: SonarCloud scan + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + fetch-depth: 0 + show-progress: false + + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: coverage + path: . + + - name: Set coverage report paths + run: | + coverage_files=$(find . -name "coverage*.xml" -type f 2>/dev/null | tr '\n' ',' | sed 's/,$//') + echo "Found coverage files: ${coverage_files:-none}" + echo "COVERAGE_PATHS=${coverage_files}" >> "$GITHUB_ENV" + + - name: Prepare SonarCloud args + env: + COMMIT_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + EVENT_NAME: ${{ github.event_name }} + PR_NUMBER: ${{ github.event_name == 'pull_request' && github.event.pull_request.number || '' }} + PR_HEAD_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || '' }} + PR_BASE_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || '' }} + run: | + SONAR_ARGS="-Dsonar.scm.revision=\"${COMMIT_SHA}\"" + if [[ "${EVENT_NAME}" == "pull_request" ]]; then + SONAR_ARGS="${SONAR_ARGS} -Dsonar.pullrequest.key=${PR_NUMBER}" + SONAR_ARGS="${SONAR_ARGS} -Dsonar.pullrequest.branch=${PR_HEAD_REF}" + SONAR_ARGS="${SONAR_ARGS} -Dsonar.pullrequest.base=${PR_BASE_REF}" + fi + if [[ -n "${COVERAGE_PATHS:-}" ]]; then + SONAR_ARGS="${SONAR_ARGS} -Dsonar.python.coverage.reportPaths=${COVERAGE_PATHS}" + fi + echo "SONAR_ARGS=${SONAR_ARGS}" >> "$GITHUB_ENV" + + - name: SonarCloud Scan + uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9 + env: + SONAR_TOKEN: ${{ secrets.ANSIBLE_COLLECTIONS_ORG_SONAR_TOKEN_CICD_BOT }} + with: + args: ${{ env.SONAR_ARGS }} diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 19c8519b..988905a0 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -4,6 +4,7 @@ concurrency: cancel-in-progress: true on: + workflow_call: pull_request: branches: - main diff --git a/.gitignore b/.gitignore index 78177c01..a570eae9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ tests/integration/*-*.yml # VS Code settings .vscode/ + +# Root coverage report for SonarCloud (generated locally or in CI) +/coverage.xml diff --git a/CI.md b/CI.md new file mode 100644 index 00000000..70104c24 --- /dev/null +++ b/CI.md @@ -0,0 +1,37 @@ +# Continuous Integration (CI) + +## Kubernetes Upstream Testing + +GitHub Actions are used to run the CI for the kubernetes.core collection. The workflows used for the CI can be found in the [.github/workflows](.github/workflows) directory. + +### PR Testing Workflows + +The following tests run on every pull request: + +| Job | Description | Python Versions | ansible-core Versions | +| --- | ----------- | --------------- | --------------------- | +| [Changelog](.github/workflows/changelog.yaml) | Checks for the presence of changelog fragments | 3.12 | devel | +| [Linters](.github/workflows/linters.yaml) | Runs `black`, `flake8`, `isort`, `yamllint`, and `ansible-lint` on plugins and tests | 3.10 | devel | +| [Sanity](.github/workflows/sanity-tests.yaml) | Runs ansible sanity checks | See compatibility table below | devel, stable-2.18, stable-2.19, stable-2.20 | +| [Unit tests](.github/workflows/unit-tests.yaml) | Executes unit test cases | See compatibility table below | devel, stable-2.16, stable-2.17, stable-2.18, stable-2.19, stable-2.20 | +| [Integration](.github/workflows/integration-tests.yaml) | Executes integration test suites using KinD cluster (split across 8 jobs, tests with Turbo mode enabled/disabled) | 3.12 | milestone | +| [all_green](.github/workflows/all_green_check.yaml) | Linters (PR only), sanity, units, coverage XML, aggregate gate, and SonarCloud scan (same-repo PR / push when org secret is set) | (see jobs) | (see jobs) | + +**Note:** Integration tests require a KinD (Kubernetes in Docker) cluster and test both with Turbo mode enabled and disabled. + +### Python Version Compatibility by ansible-core Version + +These are outlined in the collection's [tox.ini](tox.ini) file (`envlist`) and GitHub Actions workflow exclusions. + +| ansible-core Version | Sanity Tests | Unit Tests | +| -------------------- | ------------ | ---------- | +| devel | 3.12, 3.13, 3.14 | 3.12, 3.13 | +| stable-2.20 | 3.12, 3.13, 3.14 | 3.12, 3.13, 3.14 | +| stable-2.19 | 3.11, 3.12, 3.13 | 3.11, 3.12, 3.13 | +| stable-2.18 | 3.11, 3.12, 3.13 | 3.11, 3.12, 3.13 | +| stable-2.17 | 3.10, 3.11, 3.12 | 3.10, 3.11, 3.12 | +| stable-2.16 | 3.10, 3.11 | 3.10, 3.11 | + +## SonarCloud + +SonarCloud analysis runs from **[`all_green_check.yaml`](.github/workflows/all_green_check.yaml)** via the **`sonarcloud`** job, which calls **[`sonarcloud.yml`](.github/workflows/sonarcloud.yml)** (**`workflow_call`**) after the **`all_green`** gate and **coverage** succeed. The reusable workflow checks out the PR head or push SHA, downloads the **`coverage`** artifact, and runs the pinned **SonarSource** scan action. Same-repo **`pull_request`** and **`push`** only (fork PRs skip Sonar when the org secret is unavailable). Details: [SONARCLOUD.md](SONARCLOUD.md). diff --git a/README.md b/README.md index 4b81e44f..94d8d803 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ansible-collections_kubernetes.core&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ansible-collections_kubernetes.core) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ansible-collections_kubernetes.core&metric=coverage)](https://sonarcloud.io/summary/new_code?id=ansible-collections_kubernetes.core) +[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=ansible-collections_kubernetes.core&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=ansible-collections_kubernetes.core) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=ansible-collections_kubernetes.core&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=ansible-collections_kubernetes.core) +[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=ansible-collections_kubernetes.core&metric=bugs)](https://sonarcloud.io/summary/new_code?id=ansible-collections_kubernetes.core) +[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=ansible-collections_kubernetes.core&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=ansible-collections_kubernetes.core) +[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=ansible-collections_kubernetes.core&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=ansible-collections_kubernetes.core) + # Kubernetes Collection for Ansible This repository hosts the `kubernetes.core` (formerly known as `community.kubernetes`) Ansible Collection. @@ -6,46 +14,6 @@ This repository hosts the `kubernetes.core` (formerly known as `community.kubern The collection includes a variety of Ansible content to help automate the management of applications in Kubernetes and OpenShift clusters, as well as the provisioning and maintenance of clusters themselves. -## Communication - -* Join the Ansible forum: - * [Get Help](https://forum.ansible.com/c/help/6): get help or help others. - * [Posts tagged with 'kubernetes'](https://forum.ansible.com/tag/kubernetes): subscribe to participate in collection-related conversations. - * [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts. - * [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social events. - -* The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): used to announce releases and important changes. - -For more information about communication, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html). - -## Requirements - - -## Ansible Version Compatibility - -This collection has been tested against following Ansible versions: **>=2.15.0**. - -For collections that support Ansible 2.9, please ensure you update your `network_os` to use the -fully qualified collection name (for example, `cisco.ios.ios`). -Plugins and modules within a collection may be tested with only specific Ansible versions. -A collection may contain metadata that identifies these versions. -PEP440 is the schema used to describe the versions of Ansible. - - -### Helm Version Compatibility - -Helm modules in this collection are compatible with Helm v3.x and are not yet compatible with Helm v4. Individual modules and their parameters may support a more specific range of Helm versions. - -### Python Support - -* Collection supports 3.9+ - -Note: Python2 is deprecated from [1st January 2020](https://www.python.org/doc/sunset-python-2/). Please switch to Python3. - -### Kubernetes Version Support - -This collection supports Kubernetes versions >= 1.24. - ### Included Content Click on the name of a plugin or module to view that content's documentation: @@ -98,6 +66,34 @@ Name | Description +## Requirements + + +### Ansible version compatibility + +This collection has been tested against the following Ansible versions: **>=2.15.0**. + +For collections that support Ansible 2.9, please ensure you update your `network_os` to use the +fully qualified collection name (for example, `cisco.ios.ios`). +Plugins and modules within a collection may be tested with only specific Ansible versions. +A collection may contain metadata that identifies these versions. +PEP440 is the schema used to describe the versions of Ansible. + + +### Helm Version Compatibility + +Helm modules in this collection are compatible with Helm v3.x and are not yet compatible with Helm v4. Individual modules and their parameters may support a more specific range of Helm versions. + +### Python Support + +* Collection supports 3.9+ + +Note: Python2 is deprecated from [1st January 2020](https://www.python.org/doc/sunset-python-2/). Please switch to Python3. + +### Kubernetes Version Support + +This collection supports Kubernetes versions >= 1.24. + ## Installation Before using the Kubernetes collection, you need to install it with the Ansible Galaxy CLI: @@ -117,7 +113,9 @@ collections: Content in this collection requires the [Kubernetes Python client](https://pypi.org/project/kubernetes/) to interact with Kubernetes' APIs. You can install it with: - pip3 install kubernetes +```bash +pip3 install kubernetes +``` ## Use Cases @@ -205,12 +203,6 @@ defined in the playbook using `environment` keyword as above, you must set it us Please read more about Ansible Turbo mode - [here](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/ansible_turbo_mode.rst). -## Contributing to this Collection - -If you want to develop new content for this collection or improve what's already here, the easiest way to work on the collection is to clone it into one of the configured [`COLLECTIONS_PATHS`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths), and work on it there. - -See [Contributing to kubernetes.core](CONTRIBUTING.md). - ## Testing [![Linters](https://img.shields.io/github/actions/workflow/status/ansible-collections/kubernetes.core/linters.yaml?label=linters)](https://github.com/ansible-collections/kubernetes.core/actions/workflows/linters.yaml) [![Integration tests](https://img.shields.io/github/actions/workflow/status/ansible-collections/kubernetes.core/integration-tests.yaml?label=integration%20tests)](https://github.com/ansible-collections/kubernetes.core/actions/workflows/integration-tests.yaml) [![Sanity tests](https://img.shields.io/github/actions/workflow/status/ansible-collections/kubernetes.core/sanity-tests.yaml?label=sanity%20tests)](https://github.com/ansible-collections/kubernetes.core/actions/workflows/sanity-tests.yaml) [![Unit tests](https://img.shields.io/github/actions/workflow/status/ansible-collections/kubernetes.core/unit-tests.yaml?label=unit%20tests)](https://github.com/ansible-collections/kubernetes.core/actions/workflows/unit-tests.yaml) [![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/kubernetes.core)](https://app.codecov.io/gh/ansible-collections/kubernetes.core) @@ -232,7 +224,40 @@ There are also integration tests in the `molecule` directory which are meant to kind create cluster make test-molecule -## Publishing New Versions +## Contributing to this Collection + +If you want to develop new content for this collection or improve what is already here, clone the Git repository into one of the configured [`COLLECTIONS_PATHS`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths) and work on it there. + +See [Contributing to kubernetes.core](https://github.com/ansible-collections/kubernetes.core/blob/stable-5/CONTRIBUTING.md). + +Join the Ansible community: + +* [Get Help](https://forum.ansible.com/c/help/6) +* [Posts tagged with 'kubernetes'](https://forum.ansible.com/tag/kubernetes) +* [Social Spaces](https://forum.ansible.com/c/chat/4) +* [News & Announcements](https://forum.ansible.com/c/news/5) + +The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn) announces releases and important changes. For more information, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html). + +### Code of Conduct + +This project follows the [Ansible Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html). If you encounter abusive behavior, see the [policy violations](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html#policy-violations) section for how to raise a complaint. + +## Support + +As Red Hat Ansible Certified Content, this collection is entitled to support through the Ansible Automation Platform (AAP) using the **Create issue** button on the top right corner. If a support case cannot be opened with Red Hat and the collection has been obtained either from Galaxy or GitHub, there may be community help available on the [Ansible Forum](https://forum.ansible.com/). + +> **Note:** The `stable-4` branch (all `4.x.y` releases) is no longer supported. No backports or releases are performed on `stable-4`. + +We announce releases and important changes through Ansible's [The Bullhorn newsletter](https://github.com/ansible/community/wiki/News#the-bullhorn). Subscribe via [this link](https://eepurl.com/gZmiEP). + +We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit). Track The Bullhorn and join when announced. + +For the latest supported versions, see [Release Notes and Roadmap](https://github.com/ansible-collections/kubernetes.core/blob/stable-5/README.md#release-notes-and-roadmap). + +Report bugs, request features, or ask questions by opening an issue in the [GitHub repository](https://github.com/ansible-collections/kubernetes.core/). + +## Release Notes and Roadmap Releases are automatically built and pushed to Ansible Galaxy for any new tag. Before tagging a release, make sure to do the following: @@ -249,37 +274,24 @@ Releases are automatically built and pushed to Ansible Galaxy for any new tag. B After the version is published, verify it exists on the [Kubernetes Collection Galaxy page](https://galaxy.ansible.com/kubernetes/core). -The process for uploading a supported release to Automation Hub is documented separately. +The process for [uploading a supported release to Automation Hub](https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.1/html/uploading_content_to_red_hat_automation_hub/proc-upload-collection) is documented separately. -## Support +## Related Information - +* [Using Ansible collections](https://docs.ansible.com/ansible/devel/user_guide/collections_using.html) +* [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html) +* [Continuous integration (CI) overview](https://github.com/ansible-collections/kubernetes.core/blob/stable-5/CI.md) +* [SonarCloud integration](https://github.com/ansible-collections/kubernetes.core/blob/stable-5/SONARCLOUD.md) +* [Ansible Turbo mode (tech preview)](https://github.com/ansible-collections/kubernetes.core/blob/stable-5/docs/ansible_turbo_mode.rst) -> **Note:** The `stable-4` branch, which handles all `4.x.y` releases of this collection, is no longer supported. This means that no backports nor releases will be performed on the `stable-4` branch. - -We announce releases and important changes through Ansible's [The Bullhorn newsletter](https://github.com/ansible/community/wiki/News#the-bullhorn). Be sure you are [subscribed](https://eepurl.com/gZmiEP). - -We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://eepurl.com/gZmiEP) and join us. - -For more information about communication, refer to the [Ansible Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html). - -For the latest supported versions, refer to the release notes below. - -If you encounter issues or have questions, you can submit a support request through the following channels: - - GitHub Issues: Report bugs, request features, or ask questions by opening an issue in the [GitHub repository](https://github.com/ansible-collections/kubernetes.core/). - -## Release Notes - -See the [raw generated changelog](https://github.com/ansible-collections/kubernetes.core/blob/main/CHANGELOG.rst). - -## Code of Conduct +### Code of conduct We follow the [Ansible Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html) in all our interactions within this project. If you encounter abusive behavior, please refer to the [policy violations](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html#policy-violations) section of the Code for information on how to raise a complaint. -## License +## License Information GNU General Public License v3.0 or later -See LICENSE to see the full text. +See [LICENSE](https://github.com/ansible-collections/kubernetes.core/blob/stable-5/LICENSE) to see the full text. diff --git a/SONARCLOUD.md b/SONARCLOUD.md new file mode 100644 index 00000000..277c24d6 --- /dev/null +++ b/SONARCLOUD.md @@ -0,0 +1,32 @@ +# SonarCloud + +Dashboard: + +[SonarCloud project overview](https://sonarcloud.io/project/overview?id=ansible-collections_kubernetes.core) + +## CI integration + +Sonar analysis is implemented in **[.github/workflows/sonarcloud.yml](.github/workflows/sonarcloud.yml)** as a **reusable workflow** (`on: workflow_call` only). It is **not** triggered by `workflow_run`. + +**[.github/workflows/all_green_check.yaml](.github/workflows/all_green_check.yaml)** runs **linters** (on pull requests), **sanity**, **units**, and **coverage**, passes the aggregate **`all_green`** gate, then calls **`sonarcloud.yml`** via a **`sonarcloud`** job when the conditions below are met. The **coverage** job uploads a **`coverage`** artifact; the Sonar job downloads it in the **same** workflow run. + +The caller runs on **`pull_request`** or **`push`**, so the reusable workflow inherits that **`github.event`**. **`actions/checkout`** uses **`github.event.pull_request.head.sha`** on pull requests and **`github.sha`** on push (Sonar-friendly checkout). PR parameters (**`sonar.pullrequest.*`**) are taken from **`github.event.pull_request`** (no `gh` API calls in **`sonarcloud.yml`**). + +The scan step uses **`SonarSource/sonarqube-scan-action`** (pinned SHA in the workflow file) with **`sonar.python.coverage.reportPaths`** set from any **`coverage*.xml`** files found under the workspace after the artifact download. The overall flow (coverage in CI, then Sonar with XML) follows the same idea as [ansible-collections/amazon.aws#2871](https://github.com/ansible-collections/amazon.aws/pull/2871), using **`workflow_call`** from **`all_green`** instead of a separate **`workflow_run`** finalize workflow. + +Workflow files: + +- [.github/workflows/all_green_check.yaml](.github/workflows/all_green_check.yaml) -- **`all_green`** gate, **coverage** artifact upload, and **`sonarcloud`** job (**`uses: ./.github/workflows/sonarcloud.yml`**, passing only **`ANSIBLE_COLLECTIONS_ORG_SONAR_TOKEN_CICD_BOT`**) after **`all_green`** and **`coverage`** succeed, gated for **`push`** and same-repo **`pull_request`** when that secret is set. +- [.github/workflows/sonarcloud.yml](.github/workflows/sonarcloud.yml) -- **`scan`** job: checkout, download **`coverage`**, **`SONAR_ARGS`**, SonarCloud scan. + +Scanner configuration lives in [sonar-project.properties](sonar-project.properties). + +The **coverage** job (in **`all_green`**) uses **`ansible-test`** (`units --coverage`, then **`coverage combine`** / **`coverage xml`**) with **ansible-core `stable-2.18`** on **`stable-5`**, then writes **`coverage.xml`** with workspace paths normalized for Sonar. **`pytest-cov`** is listed in **`tests/unit/requirements.txt`** for parity and any direct pytest runs; **`ansible-test`** still owns the coverage data used in CI. + +**`sonarcloud.yml`** declares a required secret **`ANSIBLE_COLLECTIONS_ORG_SONAR_TOKEN_CICD_BOT`** and **`permissions: contents: read`**, **`pull-requests: read`**. + +Org secrets and fork PR behavior follow GitHub's [secrets in Actions](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) documentation. The **`sonarcloud`** job is **`if:`**-gated so the org token is not used for fork-head checkouts; fork PRs still run **`all_green`** for CI without running Sonar. + +## Branch protection (repository settings) + +If **`SonarCloud scan`** or **`all_green`** should block merges, add them under **Settings** > **Branches** > **Required status checks** for the protected branch. That is not configured in YAML. diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 00000000..39244934 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,14 @@ +# SonarCloud project configuration for kubernetes.core +# Parameters: https://docs.sonarqube.org/latest/analysis/analysis-parameters/ + +sonar.projectKey=ansible-collections_kubernetes.core +sonar.organization=ansible-collections +sonar.sources=. +sonar.projectName=kubernetes.core +sonar.python.coverage.reportPaths=coverage.xml + +sonar.tests=tests/unit,tests/integration +sonar.python.version=3.12 +sonar.newCode.referenceBranch=stable-5 + +sonar.exclusions=tests/**,.tox/** diff --git a/tests/unit/requirements.txt b/tests/unit/requirements.txt index 55c7255f..8ab6cef6 100644 --- a/tests/unit/requirements.txt +++ b/tests/unit/requirements.txt @@ -1,3 +1,4 @@ pytest +pytest-cov PyYAML kubernetes