From 4f8443c6e5b3eb9307c552e9e432c76bf90b64cb Mon Sep 17 00:00:00 2001 From: Moshe Immerman Date: Fri, 1 May 2026 14:54:35 +0300 Subject: [PATCH] ci(workflows): migrate to gavel for test execution and add timeout limits Replace custom test execution with gavel action across all test workflows (test, e2e, e2e-blobs, migrate). Add explicit timeout-minutes to all jobs to prevent hanging workflows. Remove postgres 14 from test matrix. Drop gavel.yml workflow in favor of integrated gavel action usage. Add migration fixture for database schema testing. Simplify environment variable handling and remove conditional RLS disabling logic. BREAKING CHANGE: Test execution now uses gavel action instead of make targets; CI behavior and reporting format changes accordingly. --- .github/fixtures/.gitignore | 1 + .github/fixtures/migrate.fixture.md | 14 ++ .github/workflows/codeql.yml | 1 + .github/workflows/gavel.yml | 31 ---- .github/workflows/lint.yml | 1 + .github/workflows/release.yml | 2 + .github/workflows/scorecard.yml | 1 + .github/workflows/test.yaml | 204 +++++++++++++++++++----- .github/workflows/verify-generated.yaml | 1 + 9 files changed, 187 insertions(+), 69 deletions(-) create mode 100644 .github/fixtures/.gitignore create mode 100644 .github/fixtures/migrate.fixture.md delete mode 100644 .github/workflows/gavel.yml diff --git a/.github/fixtures/.gitignore b/.github/fixtures/.gitignore new file mode 100644 index 000000000..f77495be8 --- /dev/null +++ b/.github/fixtures/.gitignore @@ -0,0 +1 @@ +duty-migrate diff --git a/.github/fixtures/migrate.fixture.md b/.github/fixtures/migrate.fixture.md new file mode 100644 index 000000000..fa01d1695 --- /dev/null +++ b/.github/fixtures/migrate.fixture.md @@ -0,0 +1,14 @@ +--- +build: make -B tidy hack/migrate/go.mod && cd hack/migrate && go build -o ../../.github/fixtures/duty-migrate main.go +exec: ./duty-migrate +args: ["--db-url", "postgres://postgres:postgres@localhost:5432/test?sslmode=disable"] +timeout: 10m +--- + +## Apply migrations + +Drives `hack/migrate/main.go` against the matrix Postgres service. The CI workflow runs this fixture twice: once on the merge base (after `actions/checkout` with `ref: main`) and once on the PR head. + +| Name | Exit Code | +|----------------|-----------| +| apply | 0 | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3391954b0..0b1b361e3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -27,6 +27,7 @@ jobs: analyze: name: Analyze runs-on: ubuntu-latest + timeout-minutes: 30 if: ${{ github.actor != 'dependabot[bot]' }} permissions: actions: read diff --git a/.github/workflows/gavel.yml b/.github/workflows/gavel.yml deleted file mode 100644 index 2517329d7..000000000 --- a/.github/workflows/gavel.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Gavel -on: - pull_request: -permissions: - contents: read - checks: write - issues: write - pull-requests: write -jobs: - gavel: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6 - with: - go-version: 1.26.x - - - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4 - with: - path: | - ~/go/pkg/mod - ~/.cache/go-build - .bin - key: cache-go-1.26.x-${{ hashFiles('**/go.sum') }}-${{ hashFiles('.bin/*') }} - restore-keys: | - cache-go-1.26.x- - - - uses: flanksource/gavel@main - with: - fail-on-error: "true" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 37fff5be4..54866cc32 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,6 +12,7 @@ jobs: pull-requests: read # for golangci/golangci-lint-action to fetch pull requests name: lint runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5b0b0060c..55a5c8520 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,6 +11,7 @@ jobs: permissions: contents: write # for codfish/semantic-release-action to create release tags runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: codfish/semantic-release-action@6abd188d2458e2fd6c99073454f6cc49196362e8 # v5.0.0 @@ -23,6 +24,7 @@ jobs: bump-clients: runs-on: ubuntu-latest + timeout-minutes: 10 needs: [semantic-release] if: needs.semantic-release.outputs.new-release-published == 'true' strategy: diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c70b945f3..2f092c783 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -21,6 +21,7 @@ jobs: analysis: name: Scorecard analysis runs-on: ubuntu-latest + timeout-minutes: 15 permissions: # Needed to upload the results to code-scanning dashboard. security-events: write diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f81a1049a..35cab3f5f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -5,14 +5,20 @@ on: pull_request: name: Test +permissions: + contents: read + checks: write + issues: write + pull-requests: write + jobs: test: runs-on: ubuntu-latest + timeout-minutes: 45 strategy: fail-fast: false matrix: postgres-version: - - { tag: "14", sha: "sha256:bbcaba1d74865ee6d6318b5e297d0df73d1f6b6d995cd892b60a2cf1440b716a" } - { tag: "15", sha: "sha256:f57a3bdbf044f0b213fdc99f35a0d21c401608bf41f063176ec00c51df9655f7" } - { tag: "16", sha: "sha256:47053cd4ee3f096afc744e53e3280de7b29b3670d2f2196c2acc0c6470923c99" } services: @@ -23,7 +29,6 @@ jobs: env: POSTGRES_PASSWORD: password POSTGRES_DB: test - # Set health checks to wait until postgres has started options: >- --health-cmd pg_isready --health-interval 10s @@ -43,7 +48,7 @@ jobs: uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: 1.26.x - cache: false # Using custom cache action below for .bin directory + cache: false - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 @@ -55,15 +60,46 @@ jobs: key: cache-${{ hashFiles('**/go.sum') }}-${{ hashFiles('.bin/*') }} restore-keys: | cache- - - name: Test - run: make test + - name: Build gavel from feat/action-flag-fix + run: | + set -euo pipefail + mkdir -p "$HOME/.local/bin" + tmp="$(mktemp -d)" + git clone --depth=1 --branch feat/action-flag-fix https://github.com/flanksource/gavel "$tmp/gavel" + cd "$tmp/gavel" + # Stub embedded UI bundles so `go build` doesn't require npm/Vite. + mkdir -p testrunner/ui/dist pr/ui/dist + : > testrunner/ui/dist/testui.js + : > pr/ui/dist/prui.js + # Pull in any missing modules referenced by source but absent from go.mod. + go mod tidy + go build -o "$HOME/.local/bin/gavel" ./cmd/gavel + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + "$HOME/.local/bin/gavel" version || true + - uses: flanksource/gavel@feat/action-flag-fix + with: + version: source + args: >- + test --lint --timeout 30m --test-timeout 15m + --ignore ./bench + --ignore ./hack + --ignore ./specs + --ignore ./tests/e2e + --ignore ./tests/e2e-blobs + ./... + artifact-name: gavel-test-pg${{ matrix.postgres-version.tag }} + comment-header: gavel-test-pg${{ matrix.postgres-version.tag }} + fail-on-error: "true" + github-token: ${{ secrets.GITHUB_TOKEN }} env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} DUTY_DB_URL: postgres://postgres:password@localhost:5432/test?sslmode=disable DUTY_DB_CREATE: "false" - DUTY_DB_DISABLE_RLS: ${{ matrix.postgres-version.tag == '14' && 'true' || 'false' }} + DUTY_DB_DISABLE_RLS: "false" e2e: runs-on: ubuntu-latest + timeout-minutes: 45 services: loki: image: grafana/loki:3.5.1@sha256:3a4e80320df38087263e9d450fd812010ee57e1e0b0679465672c0e227441f43 @@ -79,7 +115,7 @@ jobs: uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: 1.26.x - cache: false # Using custom cache action below for .bin directory + cache: false - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 @@ -91,16 +127,41 @@ jobs: key: cache-${{ hashFiles('**/go.sum') }}-${{ hashFiles('.bin/*') }} restore-keys: | cache- - - name: E2E Test + - name: Build gavel from feat/action-flag-fix run: | - make ginkgo - ginkgo -r tests/e2e/ + set -euo pipefail + mkdir -p "$HOME/.local/bin" + tmp="$(mktemp -d)" + git clone --depth=1 --branch feat/action-flag-fix https://github.com/flanksource/gavel "$tmp/gavel" + cd "$tmp/gavel" + # Stub embedded UI bundles so `go build` doesn't require npm/Vite. + mkdir -p testrunner/ui/dist pr/ui/dist + : > testrunner/ui/dist/testui.js + : > pr/ui/dist/prui.js + # Pull in any missing modules referenced by source but absent from go.mod. + go mod tidy + go build -o "$HOME/.local/bin/gavel" ./cmd/gavel + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + "$HOME/.local/bin/gavel" version || true + - uses: flanksource/gavel@feat/action-flag-fix + with: + version: source + args: >- + test --timeout 30m --test-timeout 15m + --extra-args=--ginkgo.label-filter=e2e + ./tests/e2e + artifact-name: gavel-e2e + comment-header: gavel-e2e + fail-on-error: "true" + github-token: ${{ secrets.GITHUB_TOKEN }} env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} DUTY_DB_DISABLE_RLS: "true" LOKI_URL: http://localhost:3100 e2e-blobs: runs-on: ubuntu-latest + timeout-minutes: 45 steps: - name: Install Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 @@ -118,31 +179,65 @@ jobs: key: cache-${{ hashFiles('**/go.sum') }}-${{ hashFiles('.bin/*') }} restore-keys: | cache- - - name: E2E Blob Store Tests - run: make test-e2e-blobs + - name: Build gavel from feat/action-flag-fix + run: | + set -euo pipefail + mkdir -p "$HOME/.local/bin" + tmp="$(mktemp -d)" + git clone --depth=1 --branch feat/action-flag-fix https://github.com/flanksource/gavel "$tmp/gavel" + cd "$tmp/gavel" + # Stub embedded UI bundles so `go build` doesn't require npm/Vite. + mkdir -p testrunner/ui/dist pr/ui/dist + : > testrunner/ui/dist/testui.js + : > pr/ui/dist/prui.js + # Pull in any missing modules referenced by source but absent from go.mod. + go mod tidy + go build -o "$HOME/.local/bin/gavel" ./cmd/gavel + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + "$HOME/.local/bin/gavel" version || true + - uses: flanksource/gavel@feat/action-flag-fix + with: + version: source + args: >- + test --timeout 30m --test-timeout 15m + --extra-args=--ginkgo.label-filter=e2e + ./tests/e2e-blobs + artifact-name: gavel-e2e-blobs + comment-header: gavel-e2e-blobs + fail-on-error: "true" + github-token: ${{ secrets.GITHUB_TOKEN }} env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} DUTY_DB_DISABLE_RLS: "true" migrate: runs-on: ubuntu-latest + timeout-minutes: 30 strategy: fail-fast: false matrix: postgres-version: - - { tag: "14", sha: "sha256:bbcaba1d74865ee6d6318b5e297d0df73d1f6b6d995cd892b60a2cf1440b716a" } - { tag: "15", sha: "sha256:f57a3bdbf044f0b213fdc99f35a0d21c401608bf41f063176ec00c51df9655f7" } - { tag: "16", sha: "sha256:47053cd4ee3f096afc744e53e3280de7b29b3670d2f2196c2acc0c6470923c99" } - env: - migrate_command: > - make -B tidy hack/migrate/go.mod && - cd hack/migrate && - go build main.go && ./main --db-url 'postgres://postgres:postgres@localhost:5432/test?sslmode=disable' + services: + postgres: + image: postgres:${{ matrix.postgres-version.tag }}@${{ matrix.postgres-version.sha }} + ports: + - 5432:5432 + env: + POSTGRES_PASSWORD: postgres + POSTGRES_DB: test + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - name: Install Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: 1.26.x - cache: false # Using custom cache action below for .bin directory + cache: false - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | @@ -152,34 +247,67 @@ jobs: key: cache-${{ hashFiles('**/go.sum') }}-${{ hashFiles('.bin/*') }} restore-keys: | cache- + - name: Build gavel from feat/action-flag-fix + run: | + set -euo pipefail + mkdir -p "$HOME/.local/bin" + tmp="$(mktemp -d)" + git clone --depth=1 --branch feat/action-flag-fix https://github.com/flanksource/gavel "$tmp/gavel" + cd "$tmp/gavel" + # Stub embedded UI bundles so `go build` doesn't require npm/Vite. + mkdir -p testrunner/ui/dist pr/ui/dist + : > testrunner/ui/dist/testui.js + : > pr/ui/dist/prui.js + # Pull in any missing modules referenced by source but absent from go.mod. + go mod tidy + go build -o "$HOME/.local/bin/gavel" ./cmd/gavel + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + "$HOME/.local/bin/gavel" version || true + - name: Stage migrate fixture from PR head into RUNNER_TEMP + run: | + set -euo pipefail + mkdir -p "$RUNNER_TEMP/duty-fixtures" + curl -fsSL \ + -H "Authorization: Bearer $GH_TOKEN" \ + -H "Accept: application/vnd.github.v3.raw" \ + "https://api.github.com/repos/${GITHUB_REPOSITORY}/contents/.github/fixtures/migrate.fixture.md?ref=${GITHUB_SHA}" \ + -o "$RUNNER_TEMP/duty-fixtures/migrate.fixture.md" + ls -la "$RUNNER_TEMP/duty-fixtures" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Check out main branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: main - + - name: Restore migrate fixture + run: | + mkdir -p .github/fixtures + cp "$RUNNER_TEMP/duty-fixtures/migrate.fixture.md" .github/fixtures/migrate.fixture.md - name: Apply base migrations - run: ${{ env.migrate_command }} + uses: flanksource/gavel@feat/action-flag-fix + with: + version: source + args: fixtures .github/fixtures/migrate.fixture.md + artifact-name: gavel-migrate-base-pg${{ matrix.postgres-version.tag }} + comment-header: gavel-migrate-base-pg${{ matrix.postgres-version.tag }} + fail-on-error: "true" + github-token: ${{ secrets.GITHUB_TOKEN }} env: - DUTY_DB_DISABLE_RLS: ${{ matrix.postgres-version.tag == '14' && 'true' || 'false' }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DUTY_DB_DISABLE_RLS: "false" - name: Check out current branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Apply new migrations - run: ${{ env.migrate_command }} - env: - DUTY_DB_DISABLE_RLS: ${{ matrix.postgres-version.tag == '14' && 'true' || 'false' }} - services: - postgres: - image: postgres:${{ matrix.postgres-version.tag }}@${{ matrix.postgres-version.sha }} - ports: - - 5432:5432 + uses: flanksource/gavel@feat/action-flag-fix + with: + version: source + args: fixtures .github/fixtures/migrate.fixture.md + artifact-name: gavel-migrate-head-pg${{ matrix.postgres-version.tag }} + comment-header: gavel-migrate-head-pg${{ matrix.postgres-version.tag }} + fail-on-error: "true" + github-token: ${{ secrets.GITHUB_TOKEN }} env: - POSTGRES_PASSWORD: postgres - POSTGRES_DB: test - # Set health checks to wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DUTY_DB_DISABLE_RLS: "false" diff --git a/.github/workflows/verify-generated.yaml b/.github/workflows/verify-generated.yaml index 8963b6d9e..3b0adcd7d 100644 --- a/.github/workflows/verify-generated.yaml +++ b/.github/workflows/verify-generated.yaml @@ -8,6 +8,7 @@ name: Verify Generated Artifacts jobs: verify-generated: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Install Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0