Repository navigation
feat: implement issue #1115 — [bug] dismiss-stale-bot-reviews is missing from this repo — a stale bot CHANGES_REQUESTED blocks PRs forever (blocking #1094) #1116
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
base: main
Are you sure you want to change the base?
Changes from all commits
e9c710a
1628c70
db1af86
effd39d
abda840
10492b4
cb91a6d
87297c4
a93eb82
68cc8c3
77e22f5
23db64f
d238628
4646d9e
b066763
bf344fd
f33a9fe
0edfd81
60b66b7
973a5ec
522a345
bad8d40
a75c5ee
6c9693d
862f740
1cfc5a2
97215dc
74f0541
acd9c9c
9430b1d
3226728
6cde664
16310da
a011198
6f5c527
827c781
2943068
fdb1fce
9af00bd
7547c1c
0e42039
a95d647
8cedb84
6f32f0c
fc5b3f5
60828c1
6913e37
d713392
fad23c6
21b03fc
1d4be55
c6eb356
873545c
4112475
9fc41e5
dd0b14f
d610496
76bfe4b
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,71 @@ | ||
| # Quality gate for the dismiss-stale-bot-reviews decision core (#1115). | ||
| # | ||
| # Triggered on any PR that touches: | ||
| # - scripts/dismiss-stale-bot-reviews.sh (orchestrator glue) | ||
| # - scripts/lib/dismiss-stale-bot-reviews.sh (pure decision core) | ||
| # - test/workflows/dismiss-stale-bot-reviews/** (the tests themselves) | ||
| # - .github/workflows/dismiss-stale-bot-reviews*.yml | ||
| # - standards/workflows/dismiss-stale-bot-reviews.yml | ||
| # | ||
| # Gate: bats — the decision matrix (dismiss an allow-listed bot's | ||
| # CHANGES_REQUESTED on a superseded commit; keep it on the current head; | ||
| # never touch human or non-allow-listed reviews). | ||
|
|
||
| name: Dismiss Stale Bot Reviews Tests | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - 'scripts/dismiss-stale-bot-reviews.sh' | ||
| - 'scripts/lib/dismiss-stale-bot-reviews.sh' | ||
| - 'test/workflows/dismiss-stale-bot-reviews/**' | ||
| - '.github/workflows/dismiss-stale-bot-reviews*.yml' | ||
| - 'standards/workflows/dismiss-stale-bot-reviews.yml' | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - 'scripts/dismiss-stale-bot-reviews.sh' | ||
| - 'scripts/lib/dismiss-stale-bot-reviews.sh' | ||
| - 'test/workflows/dismiss-stale-bot-reviews/**' | ||
| - '.github/workflows/dismiss-stale-bot-reviews*.yml' | ||
| - 'standards/workflows/dismiss-stale-bot-reviews.yml' | ||
|
|
||
| permissions: {} | ||
|
|
||
| concurrency: | ||
| group: dismiss-stale-bot-reviews-tests-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| test: | ||
| name: bats | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| fetch-depth: 1 | ||
| persist-credentials: false | ||
|
|
||
| - name: Install bats and jq | ||
| run: | | ||
| set -euo pipefail | ||
| max_retries=3 | ||
| for attempt in $(seq 1 "$max_retries"); do | ||
| if sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends bats jq; then | ||
| exit 0 | ||
| fi | ||
| if [ "$attempt" -lt "$max_retries" ]; then | ||
| backoff=$((2 ** (attempt - 1))) | ||
| echo "::warning::apt failed (attempt $attempt/$max_retries); retrying in ${backoff}s…" >&2 | ||
| sleep "$backoff" | ||
| fi | ||
| done | ||
| exit 1 | ||
|
|
||
| - name: Run bats suite | ||
| run: bats --print-output-on-failure test/workflows/dismiss-stale-bot-reviews/ | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,100 @@ | ||||||||||||||||
| # ───────────────────────────────────────────────────────────────────────────── | ||||||||||||||||
| # SOURCE OF TRUTH: combsmith/.github/standards/workflows/dismiss-stale-bot-reviews.yml | ||||||||||||||||
| # Standard: combsmith/.github/standards/ci-standards.md | ||||||||||||||||
| # Decision core: combsmith/.github/scripts/lib/dismiss-stale-bot-reviews.sh | ||||||||||||||||
| # combsmith/.github/scripts/dismiss-stale-bot-reviews.sh | ||||||||||||||||
| # | ||||||||||||||||
| # AGENTS — READ BEFORE EDITING: | ||||||||||||||||
| # • This file is a SELF-CONTAINED verbatim stub (the initiative-driver class), | ||||||||||||||||
| # NOT a thin caller for a reusable. A bot's CHANGES_REQUESTED review is NOT | ||||||||||||||||
| # cleared by GitHub's dismiss_stale_reviews_on_push (that only dismisses stale | ||||||||||||||||
| # *approvals*), so it persists on a superseded commit and blocks reviewDecision | ||||||||||||||||
| # forever (#617 blocker 3). This workflow dismisses such reviews once a NEWER | ||||||||||||||||
| # commit has been pushed. | ||||||||||||||||
| # • All dismiss/keep decision logic lives in the decision core above, which is | ||||||||||||||||
| # unit-tested by bats in combsmith/.github. This stub fetches that core | ||||||||||||||||
| # from combsmith/.github@v1 at runtime and runs it — the same runtime | ||||||||||||||||
| # tooling-checkout pattern initiative-driver uses for the rate-limit gate. | ||||||||||||||||
| # • You MUST NOT change: the trigger event types (synchronize + submitted), the | ||||||||||||||||
| # fork guard, or the job-level `permissions:` block (pull-requests: write is | ||||||||||||||||
| # required to dismiss a review; removing it breaks the dismissal). | ||||||||||||||||
| # • BOT-ONLY by design: human reviews are never dismissed. To change the bot | ||||||||||||||||
| # allow-list, set the DSBR_BOT_ALLOWLIST repo/org variable (comma-separated | ||||||||||||||||
| # logins) — it REPLACES the default list. Do not fork the decision logic here. | ||||||||||||||||
| # • If you need different behaviour, open a PR against the decision core in | ||||||||||||||||
| # combsmith/.github — the change propagates everywhere on next run. | ||||||||||||||||
| # ───────────────────────────────────────────────────────────────────────────── | ||||||||||||||||
| # | ||||||||||||||||
| # Dismiss stale bot reviews — self-contained org-standard workflow. | ||||||||||||||||
| # To adopt: copy this file verbatim to .github/workflows/dismiss-stale-bot-reviews.yml. | ||||||||||||||||
| # No secrets required — uses GITHUB_TOKEN only (pull-requests: write). | ||||||||||||||||
| name: Dismiss stale bot reviews | ||||||||||||||||
|
|
||||||||||||||||
| on: | ||||||||||||||||
| # A new push advances the head; a bot's CHANGES_REQUESTED now sits on a | ||||||||||||||||
| # superseded commit and must be cleared. | ||||||||||||||||
| pull_request: | ||||||||||||||||
| types: [synchronize] | ||||||||||||||||
|
Comment on lines
+36
to
+37
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.
This workflow only runs for a future Useful? React with 👍 / 👎.
Contributor
Author
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. Skipping this one — a code change here would conflict with the workflow's own hard constraints. The stub carries an explicit The stated blocker (the stale review on #1094) clears through the designed mechanism — the next
Contributor
Author
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. Skipping — re-confirmed this pass. A backfill/ The stated blocker (the stale review on #1094) clears through the designed mechanism: the next
Contributor
Author
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. Skipping — re-verified this pass against the current file. A backfill/
The stated blocker (the stale review on #1094) clears through the designed mechanism: the next
Contributor
Author
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. Skipping — re-confirmed this pass (unchanged from prior passes). A backfill/ |
||||||||||||||||
| # A bot may also submit a review on an already-superseded commit (race); the | ||||||||||||||||
| # decision core keeps it only when it is on the current head. | ||||||||||||||||
| pull_request_review: | ||||||||||||||||
| types: [submitted] | ||||||||||||||||
|
|
||||||||||||||||
| permissions: {} | ||||||||||||||||
|
|
||||||||||||||||
| concurrency: | ||||||||||||||||
| # One lane per PR so a push burst does not fan out duplicate dismissals; the | ||||||||||||||||
| # latest head wins. | ||||||||||||||||
| group: dismiss-stale-bot-reviews-${{ github.event.pull_request.number }} | ||||||||||||||||
| cancel-in-progress: true | ||||||||||||||||
|
|
||||||||||||||||
| jobs: | ||||||||||||||||
| dismiss: | ||||||||||||||||
| # Same-repo PRs only: a fork PR's GITHUB_TOKEN is read-only, so the dismissal | ||||||||||||||||
| # mutation would fail. Forked-PR stale reviews are left for human handling. | ||||||||||||||||
| if: github.event.pull_request.head.repo.full_name == github.repository | ||||||||||||||||
|
Comment on lines
+53
to
+55
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.
Dependabot branches live in the same repository, so they pass this fork guard, but GitHub runs workflows for Dependabot-authored pull requests with a read-only Useful? React with 👍 / 👎.
Contributor
Author
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. Skipping — the concern (Dependabot PRs run with a read-only |
||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||
| timeout-minutes: 5 | ||||||||||||||||
| permissions: | ||||||||||||||||
| pull-requests: write # dismissPullRequestReview via GITHUB_TOKEN | ||||||||||||||||
| contents: read # checkout | ||||||||||||||||
| steps: | ||||||||||||||||
| - name: Checkout decision-core tooling from combsmith/.github | ||||||||||||||||
| # The decision core lives in combsmith/.github; a consumer repo does | ||||||||||||||||
| # not carry it, so fetch it read-only at the pinned v1 tag into a scratch | ||||||||||||||||
| # path. combsmith/.github is public, so GITHUB_TOKEN suffices. | ||||||||||||||||
| # continue-on-error: a tooling-checkout outage must never fail the PR — the | ||||||||||||||||
| # run step then finds no script and no-ops (fail-closed: nothing dismissed). | ||||||||||||||||
| continue-on-error: true | ||||||||||||||||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||||||||||||||||
| with: | ||||||||||||||||
| repository: combsmith/.github | ||||||||||||||||
| ref: v1 | ||||||||||||||||
| path: .dsbr-tooling | ||||||||||||||||
| fetch-depth: 1 | ||||||||||||||||
| persist-credentials: false | ||||||||||||||||
|
|
||||||||||||||||
| - name: Dismiss stale allow-listed bot reviews on superseded commits | ||||||||||||||||
| env: | ||||||||||||||||
| GH_TOKEN: ${{ github.token }} | ||||||||||||||||
| # Optional wholesale override of the bot allow-list (comma-separated | ||||||||||||||||
| # logins). Unset → the decision core's built-in CodeRabbit/Copilot list. | ||||||||||||||||
| DSBR_BOT_ALLOWLIST: ${{ vars.DSBR_BOT_ALLOWLIST }} | ||||||||||||||||
| # Optional dry-run mode (set to "true" to preview without dismissing). | ||||||||||||||||
| DSBR_DRY_RUN: ${{ vars.DSBR_DRY_RUN }} | ||||||||||||||||
| run: | | ||||||||||||||||
| set -euo pipefail | ||||||||||||||||
| core=".dsbr-tooling/scripts/dismiss-stale-bot-reviews.sh" | ||||||||||||||||
| if [ ! -f "$core" ]; then | ||||||||||||||||
| echo "::warning::decision-core tooling unavailable (checkout failed); skipping — nothing dismissed" | ||||||||||||||||
| exit 0 | ||||||||||||||||
| fi | ||||||||||||||||
| args=( | ||||||||||||||||
| --owner "${{ github.repository_owner }}" | ||||||||||||||||
| --name "${{ github.event.repository.name }}" | ||||||||||||||||
| --pr "${{ github.event.pull_request.number }}" | ||||||||||||||||
|
cubic-dev-ai[bot] marked this conversation as resolved.
|
||||||||||||||||
| ) | ||||||||||||||||
| if [ "$DSBR_DRY_RUN" != "true" ]; then | ||||||||||||||||
| args+=(--apply) | ||||||||||||||||
| fi | ||||||||||||||||
|
Comment on lines
+97
to
+99
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. Logic error: Default behavior is reversed - will dismiss reviews instead of dry-run When However, the orchestrator script (line 51) explicitly states "dry-run is the default", and # Fix: Only add --apply when explicitly requested
if [ "$DSBR_DRY_RUN" = "false" ]; then
args+=(--apply)
fiOr alternatively: # Default to dry-run, only apply when explicitly enabled
if [ "${DSBR_DRY_RUN:-true}" != "true" ]; then
args+=(--apply)
fiWithout this fix, the workflow will immediately start dismissing bot reviews in production when deployed, rather than running safely in preview mode by default.
Suggested change
Spotted by Graphite |
||||||||||||||||
| bash "$core" "${args[@]}" | ||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.