Skip to content

feat(gatekeeper): add optional exempt_paths input#55

Merged
ilyashatalov merged 1 commit into
mainfrom
feat/gatekeeper-exempt-paths
Jun 16, 2026
Merged

feat(gatekeeper): add optional exempt_paths input#55
ilyashatalov merged 1 commit into
mainfrom
feat/gatekeeper-exempt-paths

Conversation

@tejasbadadare

@tejasbadadare tejasbadadare commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

What

Adds an optional, backward-compatible exempt_paths input to the reusable Bot Proxy Gatekeeper workflow.

It's a newline-separated list of regular expressions matched (via jq's test()) against changed file paths. A bot-authored PR is exempt from the 2-human-approval requirement when every changed file matches either the existing built-in docs patterns or one of these expressions — the same all(...) semantics already used for docs-only changes.

Why

Consuming repos want to carve out low-risk paths from the double-human-review requirement (our motivating case: the apps/price-terminal web app in pyth-lazer) without forking this workflow. Since the exempt path is repo-specific, it belongs in the caller's wrapper as an input rather than hardcoded here.

A caller opts in like so:

jobs:
  gatekeeper:
    uses: pyth-network/shared-actions-public/.github/workflows/ai-gatekeeper.yaml@main
    with:
      exempt_paths: |
        ^apps/price-terminal/

Backward compatibility

  • exempt_paths defaults to "". Callers that pass nothing get the exact existing docs-only behavior (verified with unit tests of the jq predicate).
  • The internal step output docs_only is renamed to exempt (it now covers more than docs). These are step-local outputs only — not exposed via workflow_call.outputs — so no caller can depend on them.
  • The published check-run name (Bot Proxy Gatekeeper (Human Review)) and PR comment marker are unchanged, so existing required-status-check rulesets keep working.

Testing

Validated the jq exemption predicate against: price-terminal-only (exempt), mixed price-terminal + Rust (not exempt), docs-only (exempt), price-terminal + docs (exempt), non-exempt code (not exempt), empty file list (not exempt), and both docs-only and code-only with no exempt_paths set (back-compat: unchanged). All pass.

Follow-up

A companion PR in pyth-lazer will update its wrapper to pass exempt_paths: '^apps/price-terminal/'. That change must land after this merges to main, since the wrapper pins @main and passing an undeclared input would error.

🤖 Generated with Claude Code

Adds a backward-compatible `exempt_paths` input to the reusable gatekeeper
workflow: a newline-separated list of regexes matched against changed file
paths. A bot-authored PR is exempt from the 2-human-approval requirement when
every changed file matches either the built-in docs patterns or one of these
expressions.

Defaults to empty, so existing callers (docs-only exemption) are unaffected.
The internal `docs_only` signal is generalized to `exempt`. This lets consuming
repos carve out low-risk paths (e.g. a web app) without forking the workflow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f1ded9b094

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

echo "$PR_FILES" | jq -r '
EXTRA_PATTERNS=$(printf '%s' "${EXEMPT_PATHS:-}" | jq -R -s 'split("\n") | map(select(length > 0))')
EXEMPT=$(
echo "$PR_FILES" | jq --argjson extra "$EXTRA_PATTERNS" -r '

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Slurp paginated file pages before evaluating exemptions

When an exempt_paths PR spans more than one GitHub API page, this jq invocation processes each gh api --paginate page as a separate JSON array/object (the GitHub CLI docs for --paginate say to use --slurp to wrap all pages). An all-exempt changeset then sets EXEMPT to multiple lines such as true\ntrue, so the later [ "$EXEMPT" = "true" ] check fails and the bot PR still requires two approvals. This breaks the new exemption for large generated/app-only updates; slurp and flatten the paginated pages before applying all(...).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, but I believe this is a false positive. gh api --paginate already merges JSON-array responses into a single array, so jq runs once and EXEMPT is a single value — --slurp does the opposite (it nests pages into an array-of-pages).

Verified empirically against a 14-item array forced into 7 pages:

$ gh api ".../labels?per_page=2" --paginate | jq -r 'length'
14

If pages were emitted separately, that would print 2 seven times; instead jq sees one merged array of 14. The pre-existing docs-only exemption already relies on this same auto-merge, and this PR doesn't change the gh api --paginate fetch. So no change is needed here.

@ilyashatalov ilyashatalov merged commit 78ee825 into main Jun 16, 2026
6 checks passed
@ilyashatalov ilyashatalov deleted the feat/gatekeeper-exempt-paths branch June 16, 2026 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants