Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
78 changes: 78 additions & 0 deletions .github/scripts/autorevert.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash
# Deterministic autorevert. Every exit prints one DECISION line.
set -euo pipefail
say() { echo "DECISION $*"; }
run=$(gh api "repos/$REPO/actions/runs/$RUN_ID")
j() { jq -r "$1" <<<"$run"; }
name=$(j .name); event=$(j .event); branch=$(j .head_branch)
sha=$(j .head_sha); attempt=$(j .run_attempt); concl=$(j .conclusion)
wf=$(j .workflow_id); created=$(j .created_at)

if [ "$name" = "Release" ]; then

Check failure on line 11 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoyy&open=AaF27_PP7_chgvKftoyy&pullRequest=114
say "release-failure run=$RUN_ID sha=$sha action=issue"
[ "$DRY" = true ] && exit 0

Check failure on line 13 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoyz&open=AaF27_PP7_chgvKftoyz&pullRequest=114
t="Autorevert: Release failed at ${sha:0:7}"
gh issue list -R "$REPO" --state open --search "\"$t\" in:title" --json number --jq length | grep -qx 0 &&
gh issue create -R "$REPO" --title "$t" --body "Release run $(j .html_url) failed. Release commits and tags are never auto-reverted; a box agent triages." >/dev/null
exit 0
fi
[ "$event" = push ] && [ "$branch" = "$MAIN" ] || { say "skip not-main-push"; exit 0; }

Check failure on line 19 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy0&open=AaF27_PP7_chgvKftoy0&pullRequest=114

Check failure on line 19 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy1&open=AaF27_PP7_chgvKftoy1&pullRequest=114
[ "$concl" = failure ] || { say "skip conclusion=$concl"; exit 0; }

Check failure on line 20 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy2&open=AaF27_PP7_chgvKftoy2&pullRequest=114

# Kill switch: open pause issue, or 2 autoreverts in 24h, stops everything.
if [ "$(gh issue list -R "$REPO" --state open --label autorevert-paused --json number --jq length)" != 0 ]; then

Check failure on line 23 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy3&open=AaF27_PP7_chgvKftoy3&pullRequest=114
say "skip kill-switch-open"; exit 0; fi

# Flake guard: first failure reruns failed jobs once; the rerun's completion re-triggers us.
if [ "$attempt" = 1 ]; then

Check failure on line 27 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy4&open=AaF27_PP7_chgvKftoy4&pullRequest=114
say "rerun-failed run=$RUN_ID sha=$sha"
[ "$DRY" = true ] || gh run rerun "$RUN_ID" -R "$REPO" --failed

Check failure on line 29 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy5&open=AaF27_PP7_chgvKftoy5&pullRequest=114
exit 0
fi

# Culprit: the previous completed push run on main must be green, else main was already red.
prev=$(gh api "repos/$REPO/actions/workflows/$wf/runs?branch=$MAIN&event=push&status=completed&per_page=20" \
--jq "[.workflow_runs[] | select(.created_at < \"$created\")][0] | .conclusion // \"none\"")
[ "$prev" = success ] || { say "skip previous=$prev sha=$sha"; exit 0; }

Check failure on line 36 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy6&open=AaF27_PP7_chgvKftoy6&pullRequest=114

git fetch -q origin "$MAIN"
[ "$(git cat-file -t "$sha" 2>/dev/null)" = commit ] || { say "skip sha-not-found $sha"; exit 0; }

Check failure on line 39 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy7&open=AaF27_PP7_chgvKftoy7&pullRequest=114
git merge-base --is-ancestor "$sha" "origin/$MAIN" || { say "skip not-on-main $sha"; exit 0; }
subj=$(git log -1 --format=%s "$sha")
case "$subj" in Revert*|*autorevert*) say "skip is-revert $sha"; exit 0;; esac
if printf '%s' "$subj" | grep -Eiq '^(release|chore\(release\))'; then say "skip release-commit $sha"; exit 0; fi
if git diff-tree --no-commit-id --name-only -r "$sha" | grep -Eq '^\.github/workflows/(release|autorevert)'; then
say "skip touches-release-or-autorevert $sha"; exit 0; fi

br="autorevert/$sha"
if [ "$(gh pr list -R "$REPO" --state all --head "$br" --json number --jq length)" != 0 ]; then

Check failure on line 48 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy8&open=AaF27_PP7_chgvKftoy8&pullRequest=114
say "skip pr-exists $br"; exit 0; fi

since=$(date -u -d '-24 hours' +%Y-%m-%dT%H:%M:%SZ)
n=$(gh pr list -R "$REPO" --state all --label autorevert --search "created:>=$since" --json number --jq length)
if [ "$n" -ge 2 ]; then

Check failure on line 53 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy9&open=AaF27_PP7_chgvKftoy9&pullRequest=114
say "kill-switch count=$n sha=$sha"
[ "$DRY" = true ] && exit 0

Check failure on line 55 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy-&open=AaF27_PP7_chgvKftoy-&pullRequest=114
gh label create autorevert-paused -R "$REPO" --color B60205 -f >/dev/null
gh issue create -R "$REPO" --label autorevert-paused --title "Autorevert paused: $n reverts in 24h" \
--body "Main CI red at $sha ($(j .html_url)). Kill switch tripped; close this issue to re-arm." >/dev/null
exit 0
fi

say "revert sha=$sha subj=$(printf '%q' "$subj")"
[ "$DRY" = true ] && exit 0

Check failure on line 63 in .github/scripts/autorevert.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ashlrai_ashlr-stack&issues=AaF27_PP7_chgvKftoy_&open=AaF27_PP7_chgvKftoy_&pullRequest=114
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git checkout -q -b "$br" "origin/$MAIN"
if ! git revert --no-edit "$sha"; then
gh issue create -R "$REPO" --title "Autorevert: revert of ${sha:0:7} conflicts" --body "Main CI red: $(j .html_url)" >/dev/null
say "conflict $sha"; exit 0
fi
git push -q origin "$br"
gh label create autorevert -R "$REPO" --color D93F0B -f >/dev/null
url=$(gh pr create -R "$REPO" --base "$MAIN" --head "$br" --label autorevert \
--title "Revert \"$subj\" (autorevert)" \
--body "Main CI failed twice at $sha: $(j .html_url). Required checks run via workflow_dispatch on this branch.")
gh pr merge "$url" --auto --squash
gh workflow run "$wf" -R "$REPO" --ref "$br"
say "opened $url"
53 changes: 53 additions & 0 deletions .github/workflows/autorevert.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Autorevert

# RQ-AUTOREVERT pilot. Deterministic, no model, no new secrets.
# When CI on a push to main fails twice (one automatic rerun of the failed
# jobs rules out flakes), open a revert PR of the culprit commit, enable
# auto-merge and dispatch CI on the revert branch so the required checks
# report (GITHUB_TOKEN events do not start pull_request runs, but
# workflow_dispatch is the documented exception). Release failures open an
# issue only. Spec: phantom-work/ci-efficiency/autorevert-spec.md.

on:
workflow_run:
workflows: [CI, Release]
types: [completed]
workflow_dispatch:
inputs:
run_id:
description: CI run id to evaluate (dry run prints the decision, opens nothing)
required: true

concurrency:
group: autorevert
cancel-in-progress: false

permissions: {}

jobs:
autorevert:
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event.workflow_run.conclusion == 'failure' &&
github.event.workflow_run.head_repository.full_name == github.repository &&
(github.event.workflow_run.event == 'push' || github.event.workflow_run.name == 'Release'))
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
actions: write # rerun failed jobs once, dispatch CI on the revert branch
contents: write # push the autorevert/<sha> branch
pull-requests: write # open the revert PR and enable auto-merge
issues: write # kill switch and release-failure issues
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
MAIN: ${{ github.event.repository.default_branch }}
DRY: ${{ github.event_name == 'workflow_dispatch' }}
RUN_ID: ${{ inputs.run_id || github.event.workflow_run.id }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 100
persist-credentials: true
- name: Decide and act
run: bash .github/scripts/autorevert.sh
Loading