Repository navigation
feat: implement issue #836 — Make initiative-driver / pr-auto-review / feature-ideation standard deployable shims (+ canonical-PAT migration) #837
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
b4dda90
feat: implement issue #836 — Make initiative-driver / pr-auto-review …
donpetry-bot c2c9484
fix(reviews): address review comments [skip ci-relay]
donpetry-bot f2d4a29
chore: dev-lead update (review-changes) [skip ci-relay]
donpetry-bot 8251142
Merge branch 'main' into dev-lead/issue-836-20260721-0145
don-petry 195ffc4
chore: dev-lead update (review-changes) [skip ci-relay]
donpetry-bot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
test/scripts/deploy-standard-workflows/feature-ideation-seed-repin.bats
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| #!/usr/bin/env bats | ||
| # Issue #836, Part B — the three newly-deployable standard workflows: | ||
| # initiative-driver.yml — self-contained dispatcher (no reusable) → verbatim add. | ||
| # pr-auto-review.yml — ring reusable → straight add, re-pinned to repo tier. | ||
| # feature-ideation.yml — ring reusable BUT carries a per-repo project_context, | ||
| # so it deploys SEED-IF-ABSENT + RE-PIN-IN-PLACE and must | ||
| # never overwrite an existing tuned body from the template. | ||
| # | ||
| # All runs are --dry-run (no mutating gh calls), single --repo/--workflow for | ||
| # determinism. A fake `gh` returns the reusable's release tags (major derivation) | ||
| # and, when set, the target repo's existing stub content. | ||
|
|
||
| setup() { | ||
| TT_TMP="$(mktemp -d "$BATS_TEST_TMPDIR/stub.XXXXXX")" | ||
| REPO_ROOT="$(cd -- "${BATS_TEST_DIRNAME}/../../.." && pwd)" | ||
| SCRIPT="${REPO_ROOT}/scripts/deploy-standard-workflows.sh" | ||
| } | ||
|
|
||
| teardown() { rm -rf "$TT_TMP"; } | ||
|
|
||
| # Fake gh: | ||
| # GH_RELEASE_REFS newline-separated `refs/tags/<agent>/vX.Y.Z` for matching-refs | ||
| # (unset/empty → no release → bare-tier form). | ||
| # GH_CONTENT_B64 base64 of the existing stub (unset → contents 404 = absent). | ||
| install_gh_stub() { | ||
| local bin="${TT_TMP}/bin" | ||
| mkdir -p "$bin" | ||
| cat > "$bin/gh" <<'STUB' | ||
| #!/usr/bin/env bash | ||
| if [ "${1:-}" = "api" ]; then | ||
| case "$2" in | ||
| *matching-refs/tags/*) | ||
| [ -n "${GH_RELEASE_REFS:-}" ] && printf '%s\n' "${GH_RELEASE_REFS}" | ||
| exit 0 ;; | ||
| *contents*) | ||
| if [ -n "${GH_CONTENT_B64:-}" ]; then | ||
| printf '{"sha":"abc123","content":"%s"}' "$GH_CONTENT_B64" | ||
| exit 0 | ||
| fi | ||
| exit 1 ;; # simulate 404 — stub absent | ||
| esac | ||
| fi | ||
| exit 0 | ||
| STUB | ||
| chmod +x "$bin/gh" | ||
| PATH="${bin}:${PATH}"; export PATH | ||
| } | ||
|
|
||
| # A feature-ideation stub with a TUNED project_context sentinel, pinned at <ref>. | ||
| fi_stub_pinning() { # <ref> | ||
| local body="jobs: | ||
| ideate: | ||
| uses: petry-projects/.github/.github/workflows/feature-ideation-reusable.yml@$1 | ||
| with: | ||
| project_context: | | ||
| TUNED-REPO-CONTEXT-SENTINEL | ||
| secrets: | ||
| CLAUDE_CODE_OAUTH_TOKEN: \${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}" | ||
| base64 -w 0 <<<"$body" 2>/dev/null || base64 -b 0 <<<"$body" | ||
| } | ||
|
|
||
| # ── feature-ideation: SEED-IF-ABSENT ─────────────────────────────────────────── | ||
|
|
||
| @test "feature-ideation: a repo WITHOUT the stub gets a fresh seed from the template" { | ||
| export GH_RELEASE_REFS="refs/tags/feature-ideation/v1.0.0" | ||
| install_gh_stub # no GH_CONTENT_B64 → 404 → stub absent | ||
| run env GH_TOKEN=x bash "$SCRIPT" --dry-run --repo markets --workflow feature-ideation.yml | ||
| [ "$status" -eq 0 ] | ||
| echo "$output" | grep -qF 'seed-if-absent: seeding fresh from template' | ||
| # markets is stable tier → v1 major line → @feature-ideation/v1-stable | ||
| echo "$output" | grep -qF '@feature-ideation/v1-stable' | ||
| echo "$output" | grep -qE 'Would open PR for markets .* feature-ideation.yml' | ||
| # must NOT take the re-pin-in-place path | ||
| ! echo "$output" | grep -qF 're-pin uses in place' | ||
| } | ||
|
|
||
| # ── feature-ideation: RE-PIN-IN-PLACE (no clobber of project_context) ─────────── | ||
|
|
||
| @test "feature-ideation: a repo WITH a tuned stub is re-pinned in place, body preserved" { | ||
| export GH_RELEASE_REFS="refs/tags/feature-ideation/v1.0.0" | ||
| # Existing tuned stub, still on the bare-tier channel. --force so the bare-tier | ||
| # migration grace does not short-circuit it as already-compliant. | ||
| GH_CONTENT_B64="$(fi_stub_pinning feature-ideation/stable)"; export GH_CONTENT_B64 | ||
| install_gh_stub | ||
| run env GH_TOKEN=x bash "$SCRIPT" --dry-run --force --repo markets --workflow feature-ideation.yml | ||
| [ "$status" -eq 0 ] | ||
| echo "$output" | grep -qF 're-pin uses in place — existing body/project_context preserved' | ||
| echo "$output" | grep -qF '@feature-ideation/v1-stable' | ||
| echo "$output" | grep -qE 'Would open PR for markets .* feature-ideation.yml' | ||
| # must NOT take the seed path (that would overwrite project_context) | ||
| ! echo "$output" | grep -qF 'seeding fresh from template' | ||
| } | ||
|
|
||
| @test "feature-ideation: an already-compliant tuned stub is left untouched (no PR)" { | ||
| # A stub already at the tier-correct v-form is compliant → no re-pin, no clobber. | ||
| export GH_RELEASE_REFS="refs/tags/feature-ideation/v1.0.0" | ||
| GH_CONTENT_B64="$(fi_stub_pinning feature-ideation/v1-stable)"; export GH_CONTENT_B64 | ||
| install_gh_stub | ||
| run env GH_TOKEN=x bash "$SCRIPT" --dry-run --repo markets --workflow feature-ideation.yml | ||
| [ "$status" -eq 0 ] | ||
| echo "$output" | grep -q 'already compliant' | ||
| ! echo "$output" | grep -q 'Would open PR' | ||
| } | ||
|
|
||
| # ── initiative-driver: verbatim add (no reusable → no pin) ────────────────────── | ||
|
|
||
| @test "initiative-driver: deploys verbatim to the fleet with no uses: pin" { | ||
| install_gh_stub # 404 → stub absent → verbatim seed | ||
| run env GH_TOKEN=x bash "$SCRIPT" --dry-run --repo markets --workflow initiative-driver.yml | ||
| [ "$status" -eq 0 ] | ||
| echo "$output" | grep -qE 'Would open PR for markets .* initiative-driver.yml' | ||
| # self-contained dispatcher: no reusable uses: → nothing to pin | ||
| ! echo "$output" | grep -qF 'would pin @' | ||
| ! echo "$output" | grep -qF 'seed-if-absent' | ||
| } | ||
|
|
||
| # ── pr-auto-review: ring add, re-pinned to the repo's tier ────────────────────── | ||
|
|
||
| @test "pr-auto-review: deploys pinned to the repo's ring tier" { | ||
| export GH_RELEASE_REFS="refs/tags/pr-auto-review/v2.1.0" | ||
| install_gh_stub # 404 → stub absent → seed + re-pin from template | ||
| run env GH_TOKEN=x bash "$SCRIPT" --dry-run --repo TalkTerm --workflow pr-auto-review.yml | ||
| [ "$status" -eq 0 ] | ||
| # TalkTerm is ring1 tier → v2 major line → @pr-auto-review/v2-ring1 | ||
| echo "$output" | grep -qF '@pr-auto-review/v2-ring1' | ||
| echo "$output" | grep -qE 'Would open PR for TalkTerm .* pr-auto-review.yml' | ||
| # pr-auto-review body is identical fleet-wide — not body-preserving | ||
| ! echo "$output" | grep -qF 'seed-if-absent' | ||
| ! echo "$output" | grep -qF 're-pin uses in place' | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| #!/usr/bin/env bats | ||
| # Tests for the credential wiring of the canonical caller stub | ||
| # standards/workflows/feature-ideation.yml (issue #836, Part A). | ||
| # | ||
| # The GH_PAT_WORKFLOWS retirement (.github-private#1326) adds the canonical org | ||
| # secret GH_PAT_DON_PETRY, keeping the old name as a `||` transition fallback. | ||
| # The two redispatch-guard `GH_TOKEN:` refs must prefer GH_PAT_DON_PETRY. | ||
| # The reusable `secrets:` block passes CLAUDE_CODE_OAUTH_TOKEN (not the PAT) and | ||
| # MUST stay untouched. | ||
|
|
||
| load 'helpers/setup' | ||
|
|
||
| STUB="${TT_REPO_ROOT}/standards/workflows/feature-ideation.yml" | ||
|
|
||
| CHAIN='${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}' | ||
|
|
||
| @test "stub: redispatch PAT-present guard GH_TOKEN uses the canonical-first fallback" { | ||
| run yq -r '.jobs.redispatch.steps[] | select(.name == "Guard — PAT present") | .env.GH_TOKEN' "$STUB" | ||
| [ "$status" -eq 0 ] | ||
| [ "$output" = "$CHAIN" ] | ||
| } | ||
|
|
||
| @test "stub: re-dispatch step GH_TOKEN uses the canonical-first fallback" { | ||
| run yq -r '.jobs.redispatch.steps[] | select(.name == "Re-dispatch under workflow_dispatch") | .env.GH_TOKEN' "$STUB" | ||
| [ "$status" -eq 0 ] | ||
| [ "$output" = "$CHAIN" ] | ||
| } | ||
|
|
||
| @test "stub: no bare secrets.GH_PAT_WORKFLOWS runtime ref remains" { | ||
| run grep -nE 'secrets\.GH_PAT_WORKFLOWS' "$STUB" | ||
| [ "$status" -eq 0 ] | ||
| while IFS= read -r line; do | ||
| [[ "$line" == *"GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS"* ]] | ||
| done <<< "$output" | ||
|
don-petry marked this conversation as resolved.
Resolved
|
||
| } | ||
|
|
||
| @test "stub: reusable secrets block still passes CLAUDE_CODE_OAUTH_TOKEN unchanged" { | ||
| run yq -r '.jobs.ideate.secrets.CLAUDE_CODE_OAUTH_TOKEN' "$STUB" | ||
| [ "$status" -eq 0 ] | ||
| [ "$output" = '${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}' ] | ||
| } | ||
|
|
||
| @test "stub: reusable secrets block carries no GH_PAT ref (PAT is not passed to the reusable)" { | ||
| run yq -r '.jobs.ideate.secrets | keys | .[]' "$STUB" | ||
| [ "$status" -eq 0 ] | ||
| [ "$output" = 'CLAUDE_CODE_OAUTH_TOKEN' ] | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| #!/usr/bin/env bats | ||
| # Tests for the credential wiring of the canonical caller stub | ||
| # standards/workflows/initiative-driver.yml (issue #836, Part A). | ||
| # | ||
| # The GH_PAT_WORKFLOWS retirement (.github-private#1326) adds the canonical org | ||
| # secret GH_PAT_DON_PETRY, keeping the old name as a `||` transition fallback. | ||
| # The two `GH_TOKEN:` guard/dispatch refs must prefer GH_PAT_DON_PETRY. | ||
| # Referenced inside a `||` the canonical secret needs no workflow_call.secrets | ||
| # declaration (this stub is a self-contained dispatcher — no reusable). | ||
|
|
||
| TT_REPO_ROOT="$(cd -- "$(dirname -- "${BATS_TEST_DIRNAME}")/../.." && pwd)" | ||
| STUB="${TT_REPO_ROOT}/standards/workflows/initiative-driver.yml" | ||
|
don-petry marked this conversation as resolved.
Resolved
|
||
|
|
||
| CHAIN='${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}' | ||
|
|
||
| @test "stub: PAT-present guard GH_TOKEN uses the canonical-first fallback" { | ||
| run yq -r '.jobs.dispatch.steps[] | select(.name == "Guard — PAT present") | .env.GH_TOKEN' "$STUB" | ||
| [ "$status" -eq 0 ] | ||
| [ "$output" = "$CHAIN" ] | ||
| } | ||
|
|
||
| @test "stub: dispatch-step GH_TOKEN uses the canonical-first fallback" { | ||
| run yq -r '.jobs.dispatch.steps[] | select(.name == "Dispatch central initiative-driver") | .env.GH_TOKEN' "$STUB" | ||
| [ "$status" -eq 0 ] | ||
| [ "$output" = "$CHAIN" ] | ||
| } | ||
|
|
||
| @test "stub: no bare secrets.GH_PAT_WORKFLOWS runtime ref remains" { | ||
| # Every GH_PAT_WORKFLOWS occurrence must be inside the canonical-first chain. | ||
| run grep -nE 'secrets\.GH_PAT_WORKFLOWS' "$STUB" | ||
| [ "$status" -eq 0 ] | ||
| while IFS= read -r line; do | ||
| [[ "$line" == *"GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS"* ]] | ||
| done <<< "$output" | ||
|
don-petry marked this conversation as resolved.
Resolved
|
||
| } | ||
|
|
||
| @test "stub: adds no workflow_call.secrets block (self-contained dispatcher)" { | ||
| run yq -r '.on.workflow_call // "absent"' "$STUB" | ||
| [ "$output" = 'absent' ] | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.