diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0539d2fe7..45a1adde4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -75,11 +75,13 @@ jobs: - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 - dependency-review: - runs-on: ubuntu-latest - steps: - - name: 'Checkout Repository' - uses: actions/checkout@v5 - - name: 'Dependency Review' - uses: actions/dependency-review-action@v4 + # Disabled for now because dependency review is unsupported until the + # repository dependency graph is enabled. + # dependency-review: + # runs-on: ubuntu-latest + # steps: + # - name: 'Checkout Repository' + # uses: actions/checkout@v5 + # - name: 'Dependency Review' + # uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/rerun-ci.yml b/.github/workflows/rerun-ci.yml new file mode 100644 index 000000000..1d8938317 --- /dev/null +++ b/.github/workflows/rerun-ci.yml @@ -0,0 +1,133 @@ +name: "Rerun CI" + +on: + workflow_run: + workflows: + - "Computer CI" + types: + - completed + +permissions: {} + +env: + MAX_RERUNS: '2' + RETRY_DELAY_SECONDS: '180' + +jobs: + decide-rerun-action: + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + runs-on: ubuntu-latest + outputs: + action: ${{ steps.decision.outputs.action }} + steps: + - name: Decide rerun action + id: decision + env: + WORKFLOW_NAME: ${{ github.event.workflow_run.name }} + RUN_ID: ${{ github.event.workflow_run.id }} + RUN_ATTEMPT: ${{ github.event.workflow_run.run_attempt }} + EVENT_NAME: ${{ github.event.workflow_run.event }} + HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} + run: | + set -euo pipefail + + action="skip" + reason="unsupported event: $EVENT_NAME" + + if [[ "$EVENT_NAME" == "push" || "$EVENT_NAME" == "pull_request" ]]; then + if (( RUN_ATTEMPT > MAX_RERUNS )); then + reason="retry limit reached" + else + action="rerun" + reason="within retry limit" + fi + fi + + { + echo "action=$action" + echo "reason=$reason" + } >> "$GITHUB_OUTPUT" + + { + echo "### Rerun CI decision" + echo "" + echo "- Workflow: $WORKFLOW_NAME" + echo "- Source event: $EVENT_NAME" + echo "- Head branch: $HEAD_BRANCH" + echo "- Run ID: $RUN_ID" + echo "- Current attempt: $RUN_ATTEMPT" + echo "- Max automatic reruns: $MAX_RERUNS" + echo "- Delay seconds: $RETRY_DELAY_SECONDS" + echo "- Action: $action" + echo "- Reason: $reason" + } >> "$GITHUB_STEP_SUMMARY" + + rerun-failed-jobs: + needs: decide-rerun-action + if: needs.decide-rerun-action.outputs.action == 'rerun' + permissions: + actions: write + contents: read + runs-on: ubuntu-latest + steps: + - name: Wait before rerun + run: | + sleep "$RETRY_DELAY_SECONDS" + + - name: Check source branch freshness + id: freshness + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + HEAD_REPOSITORY: ${{ github.event.workflow_run.head_repository.full_name }} + HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + WORKFLOW_NAME: ${{ github.event.workflow_run.name }} + RUN_ID: ${{ github.event.workflow_run.id }} + run: | + set -euo pipefail + + action="rerun" + latest_head_sha="$HEAD_SHA" + reason="head unchanged" + + if [[ -z "$HEAD_REPOSITORY" || -z "$HEAD_BRANCH" || -z "$HEAD_SHA" ]]; then + action="skip" + reason="missing head repository metadata" + else + latest_head_sha="$(gh api "repos/$HEAD_REPOSITORY/commits" -f sha="$HEAD_BRANCH" -F per_page=1 --jq '.[0].sha' 2>/dev/null || true)" + + if [[ -z "$latest_head_sha" || "$latest_head_sha" == "null" ]]; then + action="skip" + reason="head branch no longer available" + elif [[ "$latest_head_sha" != "$HEAD_SHA" ]]; then + action="skip" + reason="head moved to $latest_head_sha" + fi + fi + + { + echo "action=$action" + echo "latest_head_sha=$latest_head_sha" + echo "reason=$reason" + } >> "$GITHUB_OUTPUT" + + { + echo "### Rerun CI freshness check" + echo "" + echo "- Workflow: $WORKFLOW_NAME" + echo "- Run ID: $RUN_ID" + echo "- Head repository: $HEAD_REPOSITORY" + echo "- Head branch: $HEAD_BRANCH" + echo "- Failed run head SHA: $HEAD_SHA" + echo "- Current branch tip SHA: $latest_head_sha" + echo "- Action: $action" + echo "- Reason: $reason" + } >> "$GITHUB_STEP_SUMMARY" + + - name: Rerun failed jobs + if: steps.freshness.outputs.action == 'rerun' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + run: | + gh run rerun ${{ github.event.workflow_run.id }} --failed