From 80a9b7b2d731c4484ca7bebe23837327a47a5685 Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Thu, 8 Jan 2026 14:07:17 +0100 Subject: [PATCH 01/10] Added GitHub action that runs macOS QA and ITs on a nightly basis. --- .github/workflows/MacOsNightly.yml | 88 ++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 .github/workflows/MacOsNightly.yml diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml new file mode 100644 index 00000000..770bf532 --- /dev/null +++ b/.github/workflows/MacOsNightly.yml @@ -0,0 +1,88 @@ +name: macOS Nightly Build + +on: + schedule: + # Run at 3:00 AM UTC every day (5:00 AM CEST / 4:00 AM CET) + - cron: "0 3 * * *" + workflow_dispatch: + inputs: + skip_its: + description: "Skip integration tests" + required: false + default: false + type: boolean + +# Only allow one instance of this workflow to run at a time +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +jobs: + qa-macos: + name: "Test macOS Python ${{ matrix.python-version }}" + runs-on: github-macos-large + permissions: + id-token: write + contents: read + strategy: + fail-fast: false + matrix: + python-version: ["3.9.18", "3.10.13", "3.11.7", "3.12.1", "3.13.2"] + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + + - name: Configure poetry + uses: ./.github/actions/config-poetry + with: + python-version: ${{ matrix.python-version }} + + - name: Execute the test suite + run: poetry run pytest tests/ + + its-macos: + name: "macOS Integration Tests" + runs-on: github-macos-large + if: ${{ !inputs.skip_its }} + permissions: + id-token: write + contents: read + env: + SONARQUBE_VERSION: 25.3.0.104237 + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + + - name: Cache SonarQube + uses: SonarSource/ci-github-actions/cache@v1 + id: sonarqube-cache + with: + path: sonarqube_cache/ + key: sonarqube-macos-${{ env.SONARQUBE_VERSION }} + restore-keys: sonarqube-macos- + + - name: Download SonarQube + if: ${{ !steps.sonarqube-cache.outputs.cache-hit }} + run: | + mkdir -p sonarqube_cache + if [ ! -f sonarqube_cache/sonarqube.zip ]; then + wget -q https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-$SONARQUBE_VERSION.zip -O sonarqube_cache/sonarqube.zip + fi + + - name: Configure poetry + uses: ./.github/actions/config-poetry + + - name: Execute the integration tests + run: ./.github/scripts/run_its.sh + + notify-on-failure: + name: "Notify on Failure" + runs-on: github-ubuntu-latest-s + needs: [qa-macos, its-macos] + if: failure() && github.event_name == 'schedule' + steps: + - name: Notify team about nightly failure + run: | + echo "macOS nightly build failed. Check the workflow run for details." + echo "Workflow URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + From d67b0e8a3aa2f67b8337340cf04632117683ac41 Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Fri, 9 Jan 2026 12:52:44 +0100 Subject: [PATCH 02/10] SCANPY-220 Addressed reviewer's comments. Added temporary trigger for testing. --- .github/workflows/MacOsNightly.yml | 35 +++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml index 770bf532..59bb37a5 100644 --- a/.github/workflows/MacOsNightly.yml +++ b/.github/workflows/MacOsNightly.yml @@ -1,6 +1,10 @@ name: macOS Nightly Build on: + # TODO: Remove this trigger before merging to master + push: + branches: + - MJ/SCANPY-220 schedule: # Run at 3:00 AM UTC every day (5:00 AM CEST / 4:00 AM CET) - cron: "0 3 * * *" @@ -20,7 +24,7 @@ concurrency: jobs: qa-macos: name: "Test macOS Python ${{ matrix.python-version }}" - runs-on: github-macos-large + runs-on: macos-latest-xlarge permissions: id-token: write contents: read @@ -32,6 +36,9 @@ jobs: - name: Checkout repository uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Setup Cloudflare WARP + uses: SonarSource/gh-action_setup-cloudflare-warp@v1 + - name: Configure poetry uses: ./.github/actions/config-poetry with: @@ -42,7 +49,7 @@ jobs: its-macos: name: "macOS Integration Tests" - runs-on: github-macos-large + runs-on: macos-latest-xlarge if: ${{ !inputs.skip_its }} permissions: id-token: write @@ -53,6 +60,9 @@ jobs: - name: Checkout repository uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Setup Cloudflare WARP + uses: SonarSource/gh-action_setup-cloudflare-warp@v1 + - name: Cache SonarQube uses: SonarSource/ci-github-actions/cache@v1 id: sonarqube-cache @@ -77,12 +87,25 @@ jobs: notify-on-failure: name: "Notify on Failure" - runs-on: github-ubuntu-latest-s + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read needs: [qa-macos, its-macos] if: failure() && github.event_name == 'schedule' steps: - - name: Notify team about nightly failure + - name: Write failure summary run: | - echo "macOS nightly build failed. Check the workflow run for details." - echo "Workflow URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + echo "## macOS Nightly Build Failed" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "The scheduled macOS nightly build has failed." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Workflow Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY + + - name: Send Slack notification + uses: SonarSource/gh-action_slack-notify@1.0.1 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + slackChannel: squad-python-notifs From 7f189394480937ac35fea4456d82bec8c65923b5 Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Fri, 9 Jan 2026 14:00:29 +0100 Subject: [PATCH 03/10] SCANPY-220 ITs now use locally-started SQ instance. --- .github/workflows/MacOsNightly.yml | 1 + tests/its/conftest.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml index 59bb37a5..00a22a2f 100644 --- a/.github/workflows/MacOsNightly.yml +++ b/.github/workflows/MacOsNightly.yml @@ -56,6 +56,7 @@ jobs: contents: read env: SONARQUBE_VERSION: 25.3.0.104237 + SKIP_DOCKER: true # Use locally-started SonarQube instead of Docker steps: - name: Checkout repository uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 diff --git a/tests/its/conftest.py b/tests/its/conftest.py index 79aff3d1..3eca9849 100644 --- a/tests/its/conftest.py +++ b/tests/its/conftest.py @@ -38,7 +38,7 @@ def check_health(sonarqube_client: SonarQubeClient) -> bool: return False -if "CIRRUS_OS" in os.environ: +if "SKIP_DOCKER" in os.environ: from time import sleep @pytest.fixture(scope="session") From 33988d75e4209d21e31ea84391bdb11ab307913b Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Fri, 9 Jan 2026 14:14:16 +0100 Subject: [PATCH 04/10] SCANPY-220 Build action now also uses locally-started SQ instance. --- .github/workflows/MacOsNightly.yml | 2 +- .github/workflows/build.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml index 00a22a2f..3d059abe 100644 --- a/.github/workflows/MacOsNightly.yml +++ b/.github/workflows/MacOsNightly.yml @@ -56,7 +56,7 @@ jobs: contents: read env: SONARQUBE_VERSION: 25.3.0.104237 - SKIP_DOCKER: true # Use locally-started SonarQube instead of Docker + SKIP_DOCKER: true steps: - name: Checkout repository uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a7c05e8f..cd791410 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -174,6 +174,7 @@ jobs: contents: write env: SONARQUBE_VERSION: 25.3.0.104237 + SKIP_DOCKER: true steps: - name: Checkout repository uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 From d4051b8c969a8ad1c5c48f27856e847430b7af4c Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Fri, 9 Jan 2026 14:21:03 +0100 Subject: [PATCH 05/10] SCANPY-220 Migrated to using gh-action_cache as suggested by warning messages. Fixed race condition w.r.t. cache. --- .github/actions/config-poetry/action.yml | 8 +++++--- .github/workflows/MacOsNightly.yml | 2 +- .github/workflows/build.yml | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/actions/config-poetry/action.yml b/.github/actions/config-poetry/action.yml index 67069dd7..811cfa43 100644 --- a/.github/actions/config-poetry/action.yml +++ b/.github/actions/config-poetry/action.yml @@ -37,11 +37,13 @@ runs: - uses: SonarSource/ci-github-actions/get-build-number@v1 id: get_build_number - name: Cache local Poetry cache - uses: SonarSource/ci-github-actions/cache@v1 + uses: SonarSource/gh-action_cache@v1 with: path: ${{ inputs.poetry-cache-dir }} - key: poetry-${{ runner.os }}-${{ hashFiles('poetry.lock') }} - restore-keys: poetry-${{ runner.os }}- + key: poetry-${{ runner.os }}-${{ inputs.python-version }}-${{ hashFiles('poetry.lock') }} + restore-keys: | + poetry-${{ runner.os }}-${{ inputs.python-version }}- + poetry-${{ runner.os }}- # python needs to be installed before jfrog and poetry # (see https://xtranet-sonarsource.atlassian.net/wiki/spaces/Platform/pages/4344217683/Mise+Poetry+Install+-+GitHub) diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml index 3d059abe..35e7dc5e 100644 --- a/.github/workflows/MacOsNightly.yml +++ b/.github/workflows/MacOsNightly.yml @@ -65,7 +65,7 @@ jobs: uses: SonarSource/gh-action_setup-cloudflare-warp@v1 - name: Cache SonarQube - uses: SonarSource/ci-github-actions/cache@v1 + uses: SonarSource/gh-action_cache@v1 id: sonarqube-cache with: path: sonarqube_cache/ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd791410..bc1722d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -179,12 +179,12 @@ jobs: - name: Checkout repository uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: Cache SonarQube - uses: SonarSource/ci-github-actions/cache@v1 + uses: SonarSource/gh-action_cache@v1 id: sonarqube-cache with: path: sonarqube_cache/ - key: sonarqube-25.3.0.104237 - restore-keys: cache-${{ runner.os }}- + key: sonarqube-${{ env.SONARQUBE_VERSION }} + restore-keys: sonarqube- - name: Download SonarQube if: ${{ !steps.sonarqube-cache.outputs.cache-hit }} run: | From d730f33ae3a29ff160803baca316fd70589ec20f Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Fri, 9 Jan 2026 15:54:00 +0100 Subject: [PATCH 06/10] Trigger workflow run From 94a7cc1f88a9a3365d30d29a86792912605a0bf6 Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Fri, 9 Jan 2026 16:41:18 +0100 Subject: [PATCH 07/10] SCANPY-220 Removed temporary trigger that was used for testing. --- .github/workflows/MacOsNightly.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml index 35e7dc5e..b331ed94 100644 --- a/.github/workflows/MacOsNightly.yml +++ b/.github/workflows/MacOsNightly.yml @@ -1,10 +1,6 @@ name: macOS Nightly Build on: - # TODO: Remove this trigger before merging to master - push: - branches: - - MJ/SCANPY-220 schedule: # Run at 3:00 AM UTC every day (5:00 AM CEST / 4:00 AM CET) - cron: "0 3 * * *" From 42f2921fc38c8c011c96bf15dbcda07d2e98c2a1 Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Mon, 19 Jan 2026 15:23:20 +0100 Subject: [PATCH 08/10] SCANPY-220 Fixed Slack notification on build failure. Added option to test if a Slack message is sent. --- .github/workflows/MacOsNightly.yml | 31 +++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml index b331ed94..98ba2384 100644 --- a/.github/workflows/MacOsNightly.yml +++ b/.github/workflows/MacOsNightly.yml @@ -11,6 +11,11 @@ on: required: false default: false type: boolean + test_failure_notification: + description: "Force a failure to test the Slack notification" + required: false + default: false + type: boolean # Only allow one instance of this workflow to run at a time concurrency: @@ -43,6 +48,10 @@ jobs: - name: Execute the test suite run: poetry run pytest tests/ + - name: "[Debug] Force failure to test Slack notification" + if: ${{ inputs.test_failure_notification }} + run: exit 1 + its-macos: name: "macOS Integration Tests" runs-on: macos-latest-xlarge @@ -89,7 +98,7 @@ jobs: id-token: write contents: read needs: [qa-macos, its-macos] - if: failure() && github.event_name == 'schedule' + if: failure() && (github.event_name == 'schedule' || inputs.test_failure_notification) steps: - name: Write failure summary run: | @@ -99,10 +108,22 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY echo "**Workflow Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY + - name: Vault Secrets + id: secrets + uses: SonarSource/vault-action-wrapper@v3 + with: + secrets: | + development/kv/data/slack token | SLACK_TOKEN; + - name: Send Slack notification - uses: SonarSource/gh-action_slack-notify@1.0.1 + uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3 env: - GITHUB_TOKEN: ${{ github.token }} - with: - slackChannel: squad-python-notifs + SLACK_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).SLACK_TOKEN }} + SLACK_CHANNEL: squad-python-notifs + SLACK_COLOR: danger + SLACK_TITLE: Build Failed + SLACK_MESSAGE: | + Workflow failed in ${{ github.repository }} 🚨 + ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + SLACK_USERNAME: BuildBot From b86ded291d1fc08cd06494462c3ffd5f32bea192 Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Mon, 19 Jan 2026 15:32:11 +0100 Subject: [PATCH 09/10] SCANPY-220 Added temporary push trigger to test Slack notification. --- .github/workflows/MacOsNightly.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml index 98ba2384..db8c5fa5 100644 --- a/.github/workflows/MacOsNightly.yml +++ b/.github/workflows/MacOsNightly.yml @@ -1,6 +1,10 @@ name: macOS Nightly Build on: + # TODO: Remove this trigger before merging + push: + branches: + - MJ/SCANPY-220 schedule: # Run at 3:00 AM UTC every day (5:00 AM CEST / 4:00 AM CET) - cron: "0 3 * * *" @@ -49,7 +53,8 @@ jobs: run: poetry run pytest tests/ - name: "[Debug] Force failure to test Slack notification" - if: ${{ inputs.test_failure_notification }} + # TODO: Remove 'push' condition before merging + if: ${{ inputs.test_failure_notification || github.event_name == 'push' }} run: exit 1 its-macos: @@ -98,7 +103,8 @@ jobs: id-token: write contents: read needs: [qa-macos, its-macos] - if: failure() && (github.event_name == 'schedule' || inputs.test_failure_notification) + # TODO: Remove 'push' condition before merging + if: failure() && (github.event_name == 'schedule' || github.event_name == 'push' || inputs.test_failure_notification) steps: - name: Write failure summary run: | From 71115fd2178b7dcb7fddaaf88b8f4801dc78e040 Mon Sep 17 00:00:00 2001 From: Marc Jasper Date: Mon, 19 Jan 2026 15:40:29 +0100 Subject: [PATCH 10/10] SCANPY-220 Removed temporary push trigger, and also the option to manually trigger the Slack notification. --- .github/workflows/MacOsNightly.yml | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/.github/workflows/MacOsNightly.yml b/.github/workflows/MacOsNightly.yml index db8c5fa5..3ef7d49e 100644 --- a/.github/workflows/MacOsNightly.yml +++ b/.github/workflows/MacOsNightly.yml @@ -1,10 +1,6 @@ name: macOS Nightly Build on: - # TODO: Remove this trigger before merging - push: - branches: - - MJ/SCANPY-220 schedule: # Run at 3:00 AM UTC every day (5:00 AM CEST / 4:00 AM CET) - cron: "0 3 * * *" @@ -15,11 +11,6 @@ on: required: false default: false type: boolean - test_failure_notification: - description: "Force a failure to test the Slack notification" - required: false - default: false - type: boolean # Only allow one instance of this workflow to run at a time concurrency: @@ -52,11 +43,6 @@ jobs: - name: Execute the test suite run: poetry run pytest tests/ - - name: "[Debug] Force failure to test Slack notification" - # TODO: Remove 'push' condition before merging - if: ${{ inputs.test_failure_notification || github.event_name == 'push' }} - run: exit 1 - its-macos: name: "macOS Integration Tests" runs-on: macos-latest-xlarge @@ -103,8 +89,7 @@ jobs: id-token: write contents: read needs: [qa-macos, its-macos] - # TODO: Remove 'push' condition before merging - if: failure() && (github.event_name == 'schedule' || github.event_name == 'push' || inputs.test_failure_notification) + if: failure() && github.event_name == 'schedule' steps: - name: Write failure summary run: |