From 48028ea9612210bb5e89ed36165ce6a4f199fdac Mon Sep 17 00:00:00 2001 From: Derek Roberts Date: Thu, 15 Oct 2026 21:08:24 -0700 Subject: [PATCH 1/2] ci: narrow workflow triggers and skip Markdown-only changes PG Upgrade, oc-runner commands, Test Crunchy and Test Image Import now gate on job-level diff-triggers, so docs-only changes skip them while their checks still report. PG Upgrade matches only the oc-runner login it depends on. cert-expiry paths and the Route TLS filter ignore *.md. --- .github/workflows/cert-expiry-tests.yml | 2 + .github/workflows/oc-runner-commands.yml | 39 +++++++++++++++++ .github/workflows/pg-upgrade.yml | 55 +++++++++++++++++++----- .github/workflows/pr-open.yml | 55 +++++++++++++++++++++++- 4 files changed, 140 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cert-expiry-tests.yml b/.github/workflows/cert-expiry-tests.yml index 2d67944..fb80bde 100644 --- a/.github/workflows/cert-expiry-tests.yml +++ b/.github/workflows/cert-expiry-tests.yml @@ -11,6 +11,7 @@ on: - .github/tests/cert-expiry/** - .github/workflows/cert-expiry-tests.yml - cert-expiry/** + - "!**/*.md" push: branches: - main @@ -18,6 +19,7 @@ on: - .github/tests/cert-expiry/** - .github/workflows/cert-expiry-tests.yml - cert-expiry/** + - "!**/*.md" concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} diff --git a/.github/workflows/oc-runner-commands.yml b/.github/workflows/oc-runner-commands.yml index 344b100..18bf441 100644 --- a/.github/workflows/oc-runner-commands.yml +++ b/.github/workflows/oc-runner-commands.yml @@ -13,8 +13,45 @@ concurrency: permissions: {} jobs: + changes: + name: oc-runner (changes) + permissions: + contents: read + runs-on: ubuntu-26.04 + timeout-minutes: 5 + outputs: + triggered: ${{ steps.diff.outputs.triggered }} + steps: + # diff-triggers compares against the base branch tip. The merge base keeps a + # newer main change out of this pull request's diff. Push events use HEAD^. + - name: Find the pull request merge base + id: base + if: github.event_name == 'pull_request' + env: + GH_TOKEN: ${{ github.token }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + set -euo pipefail + sha="$(gh api "repos/${GITHUB_REPOSITORY}/compare/${BASE_SHA}...${HEAD_SHA}" --jq '.merge_base_commit.sha')" + [[ "$sha" =~ ^[0-9a-f]{40}$ ]] || { echo "::error::No merge base for ${BASE_SHA}...${HEAD_SHA}"; exit 1; } + echo "Merge base: ${sha}" + echo "sha=${sha}" >> "$GITHUB_OUTPUT" + + - id: diff + uses: bcgov/actions/diff-triggers@4026bfd276b8a5839029106099b13edfb594b2c3 # v0.8.0 + with: + ref: ${{ steps.base.outputs.sha }} + triggers: | + oc-runner/ + .github/tests/oc-runner/ + .github/workflows/oc-runner-commands.yml + !*.md + commands: name: Test oc-runner commands + needs: changes + if: needs.changes.outputs.triggered == 'true' permissions: {} runs-on: ubuntu-26.04 steps: @@ -31,6 +68,8 @@ jobs: unreachable-api: name: Test oc-runner blocked output + needs: changes + if: needs.changes.outputs.triggered == 'true' # No credentials: silver's API name points at a non-routable address on this runner, so # pre-flight times out while the real silver router still answers. The action must fail # with blocked=true (unreachable=true if the router is down too), and the composite diff --git a/.github/workflows/pg-upgrade.yml b/.github/workflows/pg-upgrade.yml index 8963c59..2c7c01a 100644 --- a/.github/workflows/pg-upgrade.yml +++ b/.github/workflows/pg-upgrade.yml @@ -2,21 +2,14 @@ name: PG Upgrade # pg-upgrade's own tests: unit tests, and every supported source major upgraded to # quickstart-openshift's major and to the newest postgres major on Docker Hub (versions.sh), in containers. +# Every pull request and main push runs the cheap path filter; the unit and container jobs +# run only when pg-upgrade or the oc-runner login it calls changed (Markdown excluded), +# so their checks still report, as skipped, instead of disappearing. on: pull_request: - paths: - - pg-upgrade/** - - oc-runner/** - - .github/tests/pg-upgrade/** - - .github/workflows/pg-upgrade.yml push: branches: - main - paths: - - pg-upgrade/** - - oc-runner/** - - .github/tests/pg-upgrade/** - - .github/workflows/pg-upgrade.yml concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.number }} @@ -25,8 +18,48 @@ concurrency: permissions: {} jobs: + changes: + name: PG Upgrade (changes) + permissions: + contents: read + runs-on: ubuntu-26.04 + timeout-minutes: 5 + outputs: + triggered: ${{ steps.diff.outputs.triggered }} + steps: + # diff-triggers compares against the base branch tip. The merge base keeps a + # newer main change out of this pull request's diff. Push events use HEAD^. + - name: Find the pull request merge base + id: base + if: github.event_name == 'pull_request' + env: + GH_TOKEN: ${{ github.token }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + set -euo pipefail + sha="$(gh api "repos/${GITHUB_REPOSITORY}/compare/${BASE_SHA}...${HEAD_SHA}" --jq '.merge_base_commit.sha')" + [[ "$sha" =~ ^[0-9a-f]{40}$ ]] || { echo "::error::No merge base for ${BASE_SHA}...${HEAD_SHA}"; exit 1; } + echo "Merge base: ${sha}" + echo "sha=${sha}" >> "$GITHUB_OUTPUT" + + - id: diff + uses: bcgov/actions/diff-triggers@4026bfd276b8a5839029106099b13edfb594b2c3 # v0.8.0 + with: + ref: ${{ steps.base.outputs.sha }} + # pg-upgrade/action.yml calls oc-runner only to log in + triggers: | + pg-upgrade/ + .github/tests/pg-upgrade/ + .github/workflows/pg-upgrade.yml + oc-runner/action.yml + oc-runner/scripts/login.sh + !*.md + versions: name: PG Upgrade (versions) + needs: changes + if: needs.changes.outputs.triggered == 'true' permissions: contents: read runs-on: ubuntu-26.04 @@ -44,6 +77,8 @@ jobs: unit: name: PG Upgrade (unit) + needs: changes + if: needs.changes.outputs.triggered == 'true' permissions: contents: read runs-on: ubuntu-26.04 diff --git a/.github/workflows/pr-open.yml b/.github/workflows/pr-open.yml index b8c7bc8..fd4901e 100644 --- a/.github/workflows/pr-open.yml +++ b/.github/workflows/pr-open.yml @@ -111,8 +111,57 @@ jobs: fi echo "No template leak found" + # Path filters for the jobs below that do not need every pull request + changes: + name: Path filters + permissions: + contents: read + runs-on: ubuntu-26.04 + timeout-minutes: 5 + outputs: + changes: ${{ steps.diff.outputs.changes }} + steps: + # diff-triggers compares against the base branch tip. The merge base keeps a + # newer main change out of this pull request's diff. Push events use HEAD^. + - name: Find the pull request merge base + id: base + if: github.event_name == 'pull_request' + env: + GH_TOKEN: ${{ github.token }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + set -euo pipefail + sha="$(gh api "repos/${GITHUB_REPOSITORY}/compare/${BASE_SHA}...${HEAD_SHA}" --jq '.merge_base_commit.sha')" + [[ "$sha" =~ ^[0-9a-f]{40}$ ]] || { echo "::error::No merge base for ${BASE_SHA}...${HEAD_SHA}"; exit 1; } + echo "Merge base: ${sha}" + echo "sha=${sha}" >> "$GITHUB_OUTPUT" + + - id: diff + uses: bcgov/actions/diff-triggers@4026bfd276b8a5839029106099b13edfb594b2c3 # v0.8.0 + with: + ref: ${{ steps.base.outputs.sha }} + filters: | + crunchy: + - crunchy/ + - .github/tests/crunchy/ + - .github/tests/route-tls/ + - .github/tests/image-import/ + - route-tls/ + - image-import/ + - .github/workflows/pr-open.yml + - "!*.md" + image-import: + - image-import/ + - oc-runner/action.yml + - oc-runner/scripts/ + - .github/workflows/pr-open.yml + - "!*.md" + test-crunchy: name: Test Crunchy + needs: changes + if: contains(fromJSON(needs.changes.outputs.changes || '[]'), 'crunchy') permissions: {} runs-on: ubuntu-26.04 steps: @@ -221,6 +270,7 @@ jobs: route-tls/ oc-runner/ .github/workflows/pr-open.yml + !*.md test-route-tls: name: Test Route TLS @@ -559,8 +609,11 @@ jobs: test-image-import: name: Test Image Import + needs: changes # Needs OpenShift credentials: same-repo PRs only - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository + if: >- + github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository + && contains(fromJSON(needs.changes.outputs.changes || '[]'), 'image-import') permissions: contents: read packages: read From 83169727c807f2658c175a150a2528239d6a1e80 Mon Sep 17 00:00:00 2001 From: Derek Roberts Date: Thu, 15 Oct 2026 21:08:46 -0700 Subject: [PATCH 2/2] docs: add PR trigger rule to AGENTS.md --- AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AGENTS.md b/AGENTS.md index f2589ea..e1b77f2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,7 @@ Repository facts and constraints for automated coding assistants. - `TLS_CA_CERTIFICATE`: issuing intermediate only (`Entrust OV TLS Issuing RSA CA 2.pem`). Exclude root CAs and `.csr`. - **Runtime**: Choose bash or JavaScript from the action's job. Bash calls `oc` and `openssl`. JavaScript or TypeScript fits a GitHub API client, pagination, or JSON assembly. Pick whichever implementation is smaller. - **Pinning**: Pin third-party actions to full 40-character commit SHAs with `# vX.Y.Z` trailing comments. Never pin `@main`. Pin bcgov shared actions (`bcgov/actions/*`, `bcgov/action-*`) to a published release SHA with a `# vX.Y.Z` comment. +- **PR triggers**: PR workflows must not fire unnecessarily. Gate heavy jobs (matrices, container tests, deploys) with job-level `bcgov/actions/diff-triggers` or path filters that list only the files each job depends on, never a whole action folder with its README. Markdown and docs-only changes never start heavy jobs. Skipped jobs still report through `bcgov/actions/workflow-results` with the standard job names and no `title`, so required checks stay stable; a top-level `paths` filter hides the whole workflow, so avoid it where checks are required. ## README usage examples