Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/dev-lead-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,9 @@ jobs:
ISSUE_NUMBER: ${{ env.INTENT_ISSUE_NUMBER }}
REPO: ${{ github.repository }}
REVIEW_ENGINE: ${{ env.DEV_LEAD_ENGINE }}
# Runtime override for the org-wide automation open-PR cap read by the
# PR-limit admission gate (#2018); empty/undefined → cap from pr-limits.json.
PR_LIMITS_ORG_CAP: ${{ vars.PR_LIMITS_ORG_CAP }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
GEMINI_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/gh-aw-cross-org.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ jobs:
PROMPTS_DIR: ${{ github.workspace }}/dotgithub-private/prompts/dev-lead
REVIEW_ENGINE: ${{ env.DEV_LEAD_ENGINE }}
GH_TOKEN: ${{ secrets.GH_PAT_DON_PETRY || secrets.GH_PAT_WORKFLOWS }}
# Runtime override for the org-wide automation open-PR cap read by the
# PR-limit admission gate (#2018); empty/undefined → cap from pr-limits.json.
PR_LIMITS_ORG_CAP: ${{ vars.PR_LIMITS_ORG_CAP }}
Comment thread
don-petry marked this conversation as resolved.
working-directory: target-repo
run: bash ${{ github.workspace }}/dotgithub-private/scripts/dev-lead-fix-issue.sh

Expand Down
80 changes: 80 additions & 0 deletions tests/dev-lead/unit/test_fix_issue_pr_limit_gate.bats
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,83 @@ teardown() {
[[ "$output" == *"::warning::"* ]]
[[ "$output" == *"failing open"* ]]
}

# ── PR_LIMITS_ORG_CAP wiring (#2018) ─────────────────────────────────────────
# The shared guard's plg_effective_org_cap (petry-projects/.github#1221) reads
# PR_LIMITS_ORG_CAP as a runtime override for the org-wide cap. The org variable
# only takes effect if every workflow step that runs the gate maps it into env.

# Overwrite the fake guard with one that records the PR_LIMITS_ORG_CAP it sees
# ("<unset>" when absent) so tests can assert the value reaches the gate.
_install_cap_recording_guard() {
CAP_SEEN_FILE="$(mktemp)" || { echo "Failed to create temp file" >&2; return 1; }
Comment thread
don-petry marked this conversation as resolved.
export CAP_SEEN_FILE
cat > "$PLG_STANDARDS_DIR/scripts/lib/pr-limit-gate.sh" <<'GUARDEOF'
#!/usr/bin/env bash
plg_admission_gate() {
printf '%s' "${PR_LIMITS_ORG_CAP-<unset>}" > "$CAP_SEEN_FILE"
return 0
}
GUARDEOF
}

@test "pr-limit gate: PR_LIMITS_ORG_CAP from step env reaches plg_admission_gate" {
export DEV_LEAD_DRY_RUN="false"
export PR_LIMITS_ORG_CAP="42"
_install_cap_recording_guard

run bash "$FIX_ISSUE_SCRIPT"

[ "$status" -eq 0 ]
[ "$(cat "$CAP_SEEN_FILE")" = "42" ]
rm -f "$CAP_SEEN_FILE"
}

@test "pr-limit gate: PR_LIMITS_ORG_CAP unset → script does not inject a cap" {
export DEV_LEAD_DRY_RUN="false"
unset PR_LIMITS_ORG_CAP
_install_cap_recording_guard

run bash "$FIX_ISSUE_SCRIPT"

[ "$status" -eq 0 ]
[ "$(cat "$CAP_SEEN_FILE")" = "<unset>" ]
rm -f "$CAP_SEEN_FILE"
}

# In workflows, ${{ vars.PR_LIMITS_ORG_CAP }} renders as "" (set-but-empty) when the
# org variable is undefined, so that is the production "no override" path.
@test "pr-limit gate: PR_LIMITS_ORG_CAP empty (undefined org var) → passed through as empty" {
export DEV_LEAD_DRY_RUN="false"
export PR_LIMITS_ORG_CAP=""
_install_cap_recording_guard

run bash "$FIX_ISSUE_SCRIPT"

[ "$status" -eq 0 ]
[ "$(cat "$CAP_SEEN_FILE")" = "" ]
rm -f "$CAP_SEEN_FILE"
}

@test "pr-limit gate: every workflow step running dev-lead-fix-issue.sh maps vars.PR_LIMITS_ORG_CAP" {
# yq is preinstalled on GitHub-hosted runners; never let this regression check
Comment thread
don-petry marked this conversation as resolved.
# silently vanish from CI (skip is for local runs only).
if ! command -v yq >/dev/null; then
[ -z "${CI:-}" ] || { echo "yq is required in CI" >&2; return 1; }
skip "yq not installed"
fi
local wf count bad_steps found=0
for wf in "$SCRIPT_DIR"/.github/workflows/*.yml; do
count=$(yq -r '[.jobs[].steps[]? | select((.run // "") | test("dev-lead-fix-issue\\.sh"))] | length' "$wf")
[ "$count" -gt 0 ] || continue
found=$((found + count))
# Steps running the script that do not map the variable (unnamed-safe).
bad_steps=$(yq -r '.jobs[].steps[]? | select((.run // "") | test("dev-lead-fix-issue\\.sh")) | select(.env.PR_LIMITS_ORG_CAP != "${{ vars.PR_LIMITS_ORG_CAP }}") | (.name // "unnamed step")' "$wf")
[ -z "$bad_steps" ] || {
echo "$(basename "$wf"): steps lacking PR_LIMITS_ORG_CAP: $bad_steps" >&2
return 1
}
done
# Guard against the selector silently matching nothing.
[ "$found" -ge 2 ]
}
Loading