Skip to content
72 changes: 62 additions & 10 deletions .github/workflows/deploy-backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@

name: Deploy Backend to EC2

permissions:
contents: read

on:
push:
branches: ['dev', 'main']
Expand Down Expand Up @@ -259,9 +262,9 @@ jobs:
# force_smoke_failure test path.
deployed_sha: ${{ (inputs.force_smoke_failure == true && 'forced-failure-sentinel') || github.sha }}
min_passed: ${{ inputs.force_smoke_failure && 999 || 1 }}
# provider-smoke creates datasets/use cases with the test account, so
# prod deploys run only the read-only api and consumer suites.
skip_provider: ${{ github.ref_name == 'main' }}
# main: only the readonly allowlist ever runs against prod.
# dev: stage 1 of 2 -- functional-tests runs only if this passes.
suite: ${{ github.ref_name == 'main' && 'readonly' || 'smoke' }}
secrets:
# This job can't see environment-scoped secrets, and the repo-level
# HOME_URL_DEV is the dev site -- passing it on main smoke-tested dev
Expand All @@ -277,14 +280,56 @@ jobs:
# and the job fails its preflight.
KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }}

functional-tests:
name: Functional Tests
needs: smoke-tests
# dev only, stage 2: runs only once smoke has passed. Functional tests
# write (datasets, use cases), so they never run against prod.
if: github.ref_name != 'main'
uses: CivicDataLab/CivicDataSpace-test/.github/workflows/run-smoke.yml@CI
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 }}
TEST_PASSWORD_1: ${{ secrets.TEST_PASSWORD_1 }}
TEST_EMAIL_2: ${{ secrets.TEST_EMAIL_2 }}
TEST_PASSWORD_2: ${{ secrets.TEST_PASSWORD_2 }}
KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }}

provider-functional-report:
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
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
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 }}

rollback-on-smoke-failure:
name: Rollback (smoke tests failed)
# `deploy` must be in needs: for needs.deploy.result to resolve here.
needs: [deploy, smoke-tests]
# failure()/success() builtins rather than needs.smoke-tests.result --
# both are false on cancellation, which is the behaviour we want;
# if: always() would ignore cancellation entirely.
if: failure() && needs.deploy.result == 'success'
# 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.
if: >-
${{ !cancelled() && needs.deploy.result == 'success' &&
(needs.smoke-tests.result == 'failure' || needs.functional-tests.result == 'failure') }}
runs-on: ubuntu-latest
environment: ${{ github.ref_name == 'main' && 'production' || 'development' }}
# 50m: must comfortably exceed the Restore previous image step's own
Expand Down Expand Up @@ -331,8 +376,15 @@ jobs:

finalize-deploy:
name: Finalize Deploy
needs: [deploy, smoke-tests]
if: success()
# 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.
if: >-
${{ !cancelled() && needs.deploy.result == 'success' &&
needs.smoke-tests.result == 'success' &&
(needs.functional-tests.result == 'success' || needs.functional-tests.result == 'skipped') }}
runs-on: ubuntu-latest
environment: ${{ github.ref_name == 'main' && 'production' || 'development' }}
timeout-minutes: 10
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# 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.
name: PR Gate

permissions: {}

on:
pull_request:
branches: [main]

permissions:
contents: read
pull-requests: read

concurrency:
group: pr-gate-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
full-suite:
name: Full Suite (dev)
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:
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 }}
KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }}

provider-report:
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
name: Provider Full Suite (report-only)
uses: CivicDataLab/CivicDataSpace-test/.github/workflows/run-smoke.yml@CI
with:
suite: full
only_provider: true
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 }}
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Loading