From 47c8430f1ce44b9347848869000648e0d3d8d24c Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 17 Sep 2026 13:01:45 +0530 Subject: [PATCH 1/3] ci: gate dev deploys on the provider suite Provider functional ran report-only while it was flaky against dev. After the sidebar, autosave and upload fixes in CivicDataSpace-test, three full provider runs passed with no retries, so a provider failure now rolls back the deploy like any other functional failure. --- .github/workflows/deploy-backend.yml | 41 ++++------------------------ 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/.github/workflows/deploy-backend.yml b/.github/workflows/deploy-backend.yml index 52540c4..38ea4df 100644 --- a/.github/workflows/deploy-backend.yml +++ b/.github/workflows/deploy-backend.yml @@ -287,9 +287,6 @@ jobs: with: suite: functional api_base_url: ${{ vars.DEV_API_BASE_URL }} - # Provider functional is flaky against dev, so it runs report-only in - # provider-functional-report instead of gating the deploy. - skip_provider: true secrets: HOME_URL_DEV: ${{ secrets.HOME_URL_DEV }} TEST_EMAIL_1: ${{ secrets.TEST_EMAIL_1 }} @@ -298,36 +295,12 @@ jobs: TEST_PASSWORD_2: ${{ secrets.TEST_PASSWORD_2 }} KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} - provider-functional-report: - name: Provider Functional (report-only) - needs: smoke-tests - # Report-only: rollback and finalize do not list this job in needs, so - # its result never rolls back or blocks a dev deploy. Promote it to a - # gate once the provider suite is stable against dev. - if: github.ref_name != 'main' - uses: CivicDataLab/CivicDataSpace-test/.github/workflows/run-smoke.yml@CI - with: - suite: functional - only_provider: true - api_base_url: ${{ vars.DEV_API_BASE_URL }} - secrets: - HOME_URL_DEV: ${{ secrets.HOME_URL_DEV }} - TEST_EMAIL_1: ${{ secrets.TEST_EMAIL_1 }} - TEST_PASSWORD_1: ${{ secrets.TEST_PASSWORD_1 }} - TEST_EMAIL_2: ${{ secrets.TEST_EMAIL_2 }} - TEST_PASSWORD_2: ${{ secrets.TEST_PASSWORD_2 }} - # org_add_permission needs a token to check canAdd; without this every - # org-create test skips on both workers and the report is hollow. - KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} - rollback-on-smoke-failure: name: Rollback (smoke tests failed) # `deploy` must be in needs: for needs.deploy.result to resolve here. - # provider-functional-report is listed so this waits for every test to - # finish, but its result is deliberately not checked (report-only). - needs: [deploy, smoke-tests, functional-tests, provider-functional-report] - # Explicit gating results, not failure(): failure() would also count the - # report-only provider job. !cancelled() keeps cancellation a no-op. + needs: [deploy, smoke-tests, functional-tests] + # Explicit results rather than failure(), so that a skipped functional stage + # on main never reads as a failure. !cancelled() keeps cancellation a no-op. if: >- ${{ !cancelled() && needs.deploy.result == 'success' && (needs.smoke-tests.result == 'failure' || needs.functional-tests.result == 'failure') }} @@ -377,11 +350,9 @@ jobs: finalize-deploy: name: Finalize Deploy - # provider-functional-report is listed so this waits for every test to - # finish, but its result is deliberately not checked (report-only). - needs: [deploy, smoke-tests, functional-tests, provider-functional-report] - # Explicit gating results, not success()/!failure(): on main the functional - # jobs are skipped by design, and the provider job must not block. + needs: [deploy, smoke-tests, functional-tests] + # Explicit results, not success()/!failure(): on main the functional stage + # is skipped by design. if: >- ${{ !cancelled() && needs.deploy.result == 'success' && needs.smoke-tests.result == 'success' && From aa6a17ded7441eb5a7380f3c9a44de480d27d472 Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 17 Sep 2026 13:01:45 +0530 Subject: [PATCH 2/3] ci: run the provider suite inside the PR gate's full suite It ran as a separate report-only job that branch protection ignored. Folding it into Full Suite makes a provider failure block the release PR. --- .github/workflows/pr-gate.yml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/.github/workflows/pr-gate.yml b/.github/workflows/pr-gate.yml index 3a804c1..d6d9da0 100644 --- a/.github/workflows/pr-gate.yml +++ b/.github/workflows/pr-gate.yml @@ -27,9 +27,6 @@ jobs: uses: CivicDataLab/CivicDataSpace-test/.github/workflows/run-smoke.yml@CI with: suite: full - # Provider is flaky against dev: it reports in provider-report below, which - # branch protection does not require. - skip_provider: true api_base_url: ${{ vars.DEV_API_BASE_URL }} deployed_sha: ${{ github.event.pull_request.head.sha }} secrets: @@ -39,20 +36,3 @@ jobs: TEST_EMAIL_2: ${{ secrets.TEST_EMAIL_2 }} TEST_PASSWORD_2: ${{ secrets.TEST_PASSWORD_2 }} KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} - - provider-report: - name: Provider Full Suite (report-only) - uses: CivicDataLab/CivicDataSpace-test/.github/workflows/run-smoke.yml@CI - with: - suite: full - only_provider: true - api_base_url: ${{ vars.DEV_API_BASE_URL }} - secrets: - HOME_URL_DEV: ${{ secrets.HOME_URL_DEV }} - TEST_EMAIL_1: ${{ secrets.TEST_EMAIL_1 }} - TEST_PASSWORD_1: ${{ secrets.TEST_PASSWORD_1 }} - TEST_EMAIL_2: ${{ secrets.TEST_EMAIL_2 }} - TEST_PASSWORD_2: ${{ secrets.TEST_PASSWORD_2 }} - # org_add_permission needs a token to check canAdd; without this every - # org-create test skips on both workers and the report is hollow. - KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} From f75057f4a4f272dd355770daaecc408c465992de Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 17 Sep 2026 13:01:45 +0530 Subject: [PATCH 3/3] ci: check dev is running dev's head, not the PR head The deployed-SHA check compared dev's live git_sha against the PR head, so any release PR not opened straight from dev failed it by construction (#191). Resolve dev's head in a small job and check against that instead. Fixes #195. --- .github/workflows/pr-gate.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-gate.yml b/.github/workflows/pr-gate.yml index d6d9da0..5a9f6ce 100644 --- a/.github/workflows/pr-gate.yml +++ b/.github/workflows/pr-gate.yml @@ -1,7 +1,8 @@ # Full test suite against dev for every PR into main. Required by branch # protection on main, so a PR merges (and prod deploys) only once it's green. -# dev already runs the PR's code (it was merged to dev first); deployed_sha -# makes the suite fail if dev is running anything else. +# Releases come from dev, so the suite checks that dev is running dev's head: +# not the PR head, which is a different commit whenever a release is built as +# a merge to resolve conflicts. name: PR Gate on: @@ -22,13 +23,25 @@ jobs: name: Django Tests uses: ./.github/workflows/django-tests.yml + dev-head: + name: Resolve dev head + runs-on: ubuntu-latest + outputs: + sha: ${{ steps.dev.outputs.sha }} + steps: + - id: dev + env: + GH_TOKEN: ${{ github.token }} + run: echo "sha=$(gh api repos/${{ github.repository }}/commits/dev --jq .sha)" >> "$GITHUB_OUTPUT" + full-suite: name: Full Suite (dev) + needs: dev-head uses: CivicDataLab/CivicDataSpace-test/.github/workflows/run-smoke.yml@CI with: suite: full api_base_url: ${{ vars.DEV_API_BASE_URL }} - deployed_sha: ${{ github.event.pull_request.head.sha }} + deployed_sha: ${{ needs.dev-head.outputs.sha }} secrets: HOME_URL_DEV: ${{ secrets.HOME_URL_DEV }} TEST_EMAIL_1: ${{ secrets.TEST_EMAIL_1 }}