Repository navigation
feat: implement issue #860 — [#850 Phase 1a] Re-pin 13 caller-stub templates to validated major-scoped v<M>-stable channels #862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # Quality gate for the caller-stub templates under standards/workflows/. | ||
| # | ||
| # Triggered on any PR that touches: | ||
| # - standards/workflows/** (a template pin changed) | ||
| # - test/scripts/standards-templates/** (the guard itself changed) | ||
| # | ||
| # Gate: bats — every deployable template pins its major-scoped | ||
| # `<agent>/v<M>-stable` channel and never the bare `<agent>/stable` form. | ||
|
|
||
| name: Standards Templates Tests | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - 'standards/workflows/**' | ||
| - 'test/scripts/standards-templates/**' | ||
| - '.github/workflows/standards-templates-tests.yml' | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - 'standards/workflows/**' | ||
| - 'test/scripts/standards-templates/**' | ||
| - '.github/workflows/standards-templates-tests.yml' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: standards-templates-tests-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| test: | ||
| name: bats | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
| with: | ||
| fetch-depth: 1 | ||
|
|
||
| - name: Install bats | ||
| run: | | ||
| set -euo pipefail | ||
| sudo apt-get update -qq | ||
| sudo apt-get install -y --no-install-recommends bats | ||
|
|
||
| - name: Run bats suite | ||
| run: bats --print-output-on-failure test/scripts/standards-templates/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| #!/usr/bin/env bats | ||
| # Template-guard for the caller-stub templates under standards/workflows/ (#860). | ||
| # | ||
| # A "deployable" template is one that pins a first-party reusable through a | ||
| # channel ref — the `uses:` line carrying the inline | ||
| # # NOSONAR(githubactions:S7637) first-party channel ref | ||
| # marker. Every such pin must use the major-scoped `<agent>/v<M>-stable` channel | ||
| # and never the bare `<agent>/stable` form (a bare pin cannot be migrated by the | ||
| # major-scope tooling and silently rides whatever the tip of the channel is). | ||
| # | ||
| # The 4 verbatim templates (ci, copilot-setup-steps, initiative-driver, | ||
| # sonarcloud) have no first-party reusable `uses:` line and are exempt. | ||
|
|
||
| REPO_ROOT="$(cd -- "${BATS_TEST_DIRNAME}/../../.." && pwd)" | ||
|
don-petry marked this conversation as resolved.
|
||
| WF_DIR="${REPO_ROOT}/standards/workflows" | ||
|
|
||
| # The templates that carry no first-party channel-ref `uses:` line. | ||
| VERBATIM="ci.yml copilot-setup-steps.yml initiative-driver.yml sonarcloud.yml" | ||
|
|
||
| # Emit each first-party channel-ref line in a file (marker-tagged uses lines). | ||
| channel_ref_lines() { | ||
| grep -nE 'S7637\) first-party channel ref' "$1" || true | ||
| } | ||
|
|
||
| # Extract the `@<ref>` channel from a `uses: …-reusable.yml@<ref> # …` line. | ||
| ref_of() { | ||
| sed -E 's/.*-reusable\.yml@([^[:space:]]+).*/\1/' <<<"$1" | ||
|
Comment on lines
+20
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Inspect active reusable
Proposed direction-channel_ref_lines() {
- grep -nE 'S7637\) first-party channel ref' "$1" || true
+reusable_uses_lines() {
+ grep -nE '^[[:space:]]*uses:[[:space:]]+petry-projects/\.github(-private)?/\.github/workflows/[^[:space:]@]+-reusable\.yml@[^[:space:]]+' "$1" || true
}Use 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| @test "every deployable template pins <agent>/v<M>-stable, never bare <agent>/stable" { | ||
| local violations=() | ||
| local f name lines line ref | ||
| for f in "${WF_DIR}"/*.yml; do | ||
| name="$(basename "$f")" | ||
| lines="$(channel_ref_lines "$f")" | ||
| [ -n "$lines" ] || continue | ||
|
don-petry marked this conversation as resolved.
|
||
| while IFS= read -r line; do | ||
| ref="$(ref_of "$line")" | ||
| # Must be the major-scoped v-form: <agent>/v<M>-stable. | ||
| if [[ ! "$ref" =~ ^[a-z0-9-]+/v[0-9]+-stable$ ]]; then | ||
| violations+=("${name}: '${ref}' is not <agent>/v<M>-stable") | ||
| fi | ||
| done <<<"$lines" | ||
| done | ||
| if [ "${#violations[@]}" -ne 0 ]; then | ||
| printf 'bad pin -> %s\n' "${violations[@]}" | ||
| return 1 | ||
| fi | ||
| } | ||
|
|
||
| @test "agent_ref is byte-equal to the uses: channel where present" { | ||
|
don-petry marked this conversation as resolved.
|
||
| local f name uses_ref agent_ref | ||
| for f in "${WF_DIR}"/*.yml; do | ||
| name="$(basename "$f")" | ||
| grep -qE '^[[:space:]]*agent_ref:' "$f" || continue | ||
| uses_ref="$(ref_of "$(channel_ref_lines "$f")")" | ||
| agent_ref="$(grep -oE 'agent_ref:[[:space:]]*[^[:space:]]+' "$f" | sed -E 's/agent_ref:[[:space:]]*//')" | ||
| [ "$agent_ref" = "$uses_ref" ] || { | ||
| echo "${name}: agent_ref='${agent_ref}' != uses channel='${uses_ref}'" | ||
| return 1 | ||
| } | ||
| done | ||
| } | ||
|
|
||
| @test "the 4 verbatim templates carry no first-party channel-ref line" { | ||
| local name lines | ||
| for name in $VERBATIM; do | ||
| [ -f "${WF_DIR}/${name}" ] || { echo "missing ${name}"; return 1; } | ||
| lines="$(channel_ref_lines "${WF_DIR}/${name}")" | ||
| [ -z "$lines" ] || { echo "${name} unexpectedly has a channel-ref line"; return 1; } | ||
| done | ||
| } | ||
|
|
||
| @test "every non-verbatim template HAS a marker-tagged channel-ref line" { | ||
| # Guards against a deployable template silently losing its channel pin (or the | ||
| # NOSONAR marker): without this, the first test's `[ -n "$lines" ] || continue` | ||
| # would skip an unmarked file and pass. Any non-verbatim template must carry a | ||
| # first-party channel-ref line so it stays under the v-form pin check. | ||
| local f name missing=() | ||
| for f in "${WF_DIR}"/*.yml; do | ||
| name="$(basename "$f")" | ||
| case " $VERBATIM " in *" $name "*) continue ;; esac | ||
| [ -n "$(channel_ref_lines "$f")" ] || missing+=("$name") | ||
| done | ||
| if [ "${#missing[@]}" -ne 0 ]; then | ||
| printf 'non-verbatim template missing a first-party channel-ref line -> %s\n' "${missing[@]}" | ||
| return 1 | ||
| fi | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -25,8 +25,8 @@ CHAIN='${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}' | |||||||||||||||||||||
| [ "$output" = 'GH_PAT_WORKFLOWS' ] | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @test "stub: keeps the @pr-auto-review/stable channel pin in the uses: line" { | ||||||||||||||||||||||
| @test "stub: keeps the @pr-auto-review/v1-stable channel pin in the uses: line" { | ||||||||||||||||||||||
| run yq -r '.jobs.pr-auto-review.uses' "$STUB" | ||||||||||||||||||||||
| [ "$status" -eq 0 ] | ||||||||||||||||||||||
| [[ "$output" == *'@pr-auto-review/stable'* ]] | ||||||||||||||||||||||
| [[ "$output" == *'@pr-auto-review/v1-stable'* ]] | ||||||||||||||||||||||
|
don-petry marked this conversation as resolved.
Comment on lines
+28
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Assert the complete channel contract, including rejection of the bare pin. This assertion only checks for a substring, so malformed refs could pass and Suggested test change `@test` "stub: keeps the `@pr-auto-review/v1-stable` channel pin in the uses: line" {
run yq -r '.jobs.pr-auto-review.uses' "$STUB"
[ "$status" -eq 0 ]
- [[ "$output" == *'`@pr-auto-review/v1-stable`'* ]]
+ [[ "$output" =~ `@pr-auto-review/v`[0-9]+-stable$ ]]
+ [[ "$output" != *'`@pr-auto-review/stable`'* ]]
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| } | ||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.