From b8c97776f7b4b5e54f3650865e59c3d76fd20afe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 18:58:24 +0000 Subject: [PATCH 1/4] Initial plan From 9d41d083abef531c763da90d7d09422f030f0d55 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 19:09:29 +0000 Subject: [PATCH 2/4] Add no-op early exit guard to Hourly CI Cleaner - Remove exit 1 from CI check step to allow graceful continuation - Add conditional execution (if: env.CI_NEEDS_FIX == 'true') to all setup steps - Update workflow description to mention early exit behavior - Add comments explaining early exit guard mechanism - Update agent prompt to check CI status and exit early if passing - Prevents token consumption when CI is healthy Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- .github/workflows/hourly-ci-cleaner.lock.yml | 30 ++++++++++++++------ .github/workflows/hourly-ci-cleaner.md | 18 ++++++++++-- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/.github/workflows/hourly-ci-cleaner.lock.yml b/.github/workflows/hourly-ci-cleaner.lock.yml index ea69bedc75c..289bf890784 100644 --- a/.github/workflows/hourly-ci-cleaner.lock.yml +++ b/.github/workflows/hourly-ci-cleaner.lock.yml @@ -19,7 +19,7 @@ # gh aw compile # For more information: https://github.com/githubnext/gh-aw/blob/main/.github/aw/github-agentic-workflows.md # -# CI cleaner that fixes format, lint, and test issues when CI fails on main branch. Runs every 2 hours during peak hours (9 AM - 5 PM UTC) and every 3 hours during off-peak hours to optimize token spend. +# CI cleaner that fixes format, lint, and test issues when CI fails on main branch. Runs every 2 hours during peak hours (9 AM - 5 PM UTC) and every 3 hours during off-peak hours to optimize token spend. Includes early exit when CI is passing to prevent unnecessary token consumption. # # Resolved workflow manifest: # Imports: @@ -175,20 +175,24 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} id: ci_check name: Check last CI workflow run status on main branch - run: "# Get the last CI workflow run on main branch, excluding pending and cancelled runs\nLAST_RUN=$(gh run list --workflow=ci.yml --branch=main --limit 50 --json conclusion,status,databaseId \\\n | jq -r '[.[] | select(.status == \"completed\" and (.conclusion == \"success\" or .conclusion == \"failure\"))] | .[0]')\n\nCONCLUSION=$(echo \"$LAST_RUN\" | jq -r '.conclusion')\nRUN_ID=$(echo \"$LAST_RUN\" | jq -r '.databaseId')\n\necho \"Last CI run conclusion: ${CONCLUSION}\"\necho \"Run ID: ${RUN_ID}\"\n\n# Write to environment and step summary\necho \"CI_STATUS=${CONCLUSION}\" >> \"$GITHUB_ENV\"\necho \"CI_RUN_ID=${RUN_ID}\" >> \"$GITHUB_ENV\"\n\nif [ \"$CONCLUSION\" = \"success\" ]; then\n echo \"✅ CI is passing on main branch - no action needed\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"CI_NEEDS_FIX=false\" >> \"$GITHUB_ENV\"\n exit 1\nelse\n echo \"❌ CI is failing on main branch - agent will attempt to fix\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"Run ID: ${RUN_ID}\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"CI_NEEDS_FIX=true\" >> \"$GITHUB_ENV\"\nfi\n" - - name: Install Make + run: "# Get the last CI workflow run on main branch, excluding pending and cancelled runs\nLAST_RUN=$(gh run list --workflow=ci.yml --branch=main --limit 50 --json conclusion,status,databaseId \\\n | jq -r '[.[] | select(.status == \"completed\" and (.conclusion == \"success\" or .conclusion == \"failure\"))] | .[0]')\n\nCONCLUSION=$(echo \"$LAST_RUN\" | jq -r '.conclusion')\nRUN_ID=$(echo \"$LAST_RUN\" | jq -r '.databaseId')\n\necho \"Last CI run conclusion: ${CONCLUSION}\"\necho \"Run ID: ${RUN_ID}\"\n\n# Write to environment and step summary\necho \"CI_STATUS=${CONCLUSION}\" >> \"$GITHUB_ENV\"\necho \"CI_RUN_ID=${RUN_ID}\" >> \"$GITHUB_ENV\"\n\nif [ \"$CONCLUSION\" = \"success\" ]; then\n echo \"✅ CI is passing on main branch - no action needed\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"CI_NEEDS_FIX=false\" >> \"$GITHUB_ENV\"\nelse\n echo \"❌ CI is failing on main branch - agent will attempt to fix\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"Run ID: ${RUN_ID}\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"CI_NEEDS_FIX=true\" >> \"$GITHUB_ENV\"\nfi\n" + - if: env.CI_NEEDS_FIX == 'true' + name: Install Make run: | sudo apt-get update sudo apt-get install -y make - - name: Setup Go + - if: env.CI_NEEDS_FIX == 'true' + name: Setup Go uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c with: cache: true go-version-file: go.mod - - name: Install npm dependencies + - if: env.CI_NEEDS_FIX == 'true' + name: Install npm dependencies run: npm ci working-directory: ./pkg/workflow/js - - name: Install dev dependencies + - if: env.CI_NEEDS_FIX == 'true' + name: Install dev dependencies run: make deps-dev - name: Configure Git credentials @@ -1952,6 +1956,7 @@ jobs: env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} + GH_AW_ENV_CI_NEEDS_FIX: ${{ env.CI_NEEDS_FIX }} GH_AW_ENV_CI_STATUS: ${{ env.CI_STATUS }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_NUMBER: ${{ github.run_number }} @@ -2254,7 +2259,13 @@ jobs: ## Your Task - The CI workflow has failed on the main branch. Follow the instructions from the ci-cleaner agent to: + **IMPORTANT**: Check the CI status first: + - **CI Status**: __GH_AW_ENV_CI_STATUS__ + - **CI Needs Fix**: __GH_AW_ENV_CI_NEEDS_FIX__ + + If `CI_NEEDS_FIX` is `false` or `CI_STATUS` is `success`, then **CI is passing and no action is needed**. Simply report that CI is healthy and exit successfully without making any changes. + + If CI has failed on the main branch, follow the instructions from the ci-cleaner agent to: 1. **Format sources** - Run `make fmt` to format all code 2. **Run linters** - Run `make lint` and fix any issues @@ -2299,6 +2310,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ENV_CI_NEEDS_FIX: ${{ env.CI_NEEDS_FIX }} GH_AW_ENV_CI_STATUS: ${{ env.CI_STATUS }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_NUMBER: ${{ github.run_number }} @@ -2331,6 +2343,7 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { + GH_AW_ENV_CI_NEEDS_FIX: process.env.GH_AW_ENV_CI_NEEDS_FIX, GH_AW_ENV_CI_STATUS: process.env.GH_AW_ENV_CI_STATUS, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_NUMBER: process.env.GH_AW_GITHUB_RUN_NUMBER @@ -2500,6 +2513,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ENV_CI_NEEDS_FIX: ${{ env.CI_NEEDS_FIX }} GH_AW_ENV_CI_STATUS: ${{ env.CI_STATUS }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_NUMBER: ${{ github.run_number }} @@ -6516,7 +6530,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: WORKFLOW_NAME: "CI Cleaner" - WORKFLOW_DESCRIPTION: "CI cleaner that fixes format, lint, and test issues when CI fails on main branch. Runs every 2 hours during peak hours (9 AM - 5 PM UTC) and every 3 hours during off-peak hours to optimize token spend." + WORKFLOW_DESCRIPTION: "CI cleaner that fixes format, lint, and test issues when CI fails on main branch. Runs every 2 hours during peak hours (9 AM - 5 PM UTC) and every 3 hours during off-peak hours to optimize token spend. Includes early exit when CI is passing to prevent unnecessary token consumption." with: script: | const fs = require('fs'); diff --git a/.github/workflows/hourly-ci-cleaner.md b/.github/workflows/hourly-ci-cleaner.md index fea3078673e..1afba324df6 100644 --- a/.github/workflows/hourly-ci-cleaner.md +++ b/.github/workflows/hourly-ci-cleaner.md @@ -1,5 +1,5 @@ --- -description: CI cleaner that fixes format, lint, and test issues when CI fails on main branch. Runs every 2 hours during peak hours (9 AM - 5 PM UTC) and every 3 hours during off-peak hours to optimize token spend. +description: CI cleaner that fixes format, lint, and test issues when CI fails on main branch. Runs every 2 hours during peak hours (9 AM - 5 PM UTC) and every 3 hours during off-peak hours to optimize token spend. Includes early exit when CI is passing to prevent unnecessary token consumption. on: schedule: # Peak hours (9 AM - 5 PM UTC): Every 2 hours @@ -31,6 +31,8 @@ sandbox: - "/usr/local/lib/node_modules:/usr/local/lib/node_modules:ro" - "/opt/hostedtoolcache/go:/opt/hostedtoolcache/go:ro" steps: + # Early exit guard: Check if there's work to do before consuming tokens + # If CI is passing, the workflow exits early without running the agent - name: Check last CI workflow run status on main branch id: ci_check env: @@ -53,31 +55,35 @@ steps: if [ "$CONCLUSION" = "success" ]; then echo "✅ CI is passing on main branch - no action needed" >> "$GITHUB_STEP_SUMMARY" echo "CI_NEEDS_FIX=false" >> "$GITHUB_ENV" - exit 1 else echo "❌ CI is failing on main branch - agent will attempt to fix" >> "$GITHUB_STEP_SUMMARY" echo "Run ID: ${RUN_ID}" >> "$GITHUB_STEP_SUMMARY" echo "CI_NEEDS_FIX=true" >> "$GITHUB_ENV" fi - name: Install Make + if: env.CI_NEEDS_FIX == 'true' run: | sudo apt-get update sudo apt-get install -y make - name: Setup Go + if: env.CI_NEEDS_FIX == 'true' uses: actions/setup-go@v6 with: go-version-file: go.mod cache: true - name: Set up Node.js + if: env.CI_NEEDS_FIX == 'true' uses: actions/setup-node@v6 with: node-version: "24" cache: npm cache-dependency-path: pkg/workflow/js/package-lock.json - name: Install npm dependencies + if: env.CI_NEEDS_FIX == 'true' run: npm ci working-directory: ./pkg/workflow/js - name: Install dev dependencies + if: env.CI_NEEDS_FIX == 'true' run: make deps-dev safe-outputs: create-pull-request: @@ -107,7 +113,13 @@ When CI fails on the main branch, automatically diagnose and fix the issues by: ## Your Task -The CI workflow has failed on the main branch. Follow the instructions from the ci-cleaner agent to: +**IMPORTANT**: Check the CI status first: +- **CI Status**: ${{ env.CI_STATUS }} +- **CI Needs Fix**: ${{ env.CI_NEEDS_FIX }} + +If `CI_NEEDS_FIX` is `false` or `CI_STATUS` is `success`, then **CI is passing and no action is needed**. Simply report that CI is healthy and exit successfully without making any changes. + +If CI has failed on the main branch, follow the instructions from the ci-cleaner agent to: 1. **Format sources** - Run `make fmt` to format all code 2. **Run linters** - Run `make lint` and fix any issues From b84323ffad596685b8a3526ec55bc958c35131b8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 19:13:36 +0000 Subject: [PATCH 3/4] Complete: Add no-op early exit guard to Hourly CI Cleaner - all tests passing Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- .github/workflows/issue-classifier.lock.yml | 2 +- .github/workflows/release.lock.yml | 6 +++--- .github/workflows/stale-repo-identifier.lock.yml | 2 +- .github/workflows/super-linter.lock.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml index 733eb8392fa..ddfc3f26710 100644 --- a/.github/workflows/issue-classifier.lock.yml +++ b/.github/workflows/issue-classifier.lock.yml @@ -2999,7 +2999,7 @@ jobs: path: /tmp/gh-aw/aw_info.json if-no-files-found: warn - name: Run AI Inference - uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v1 + uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 env: GH_AW_MCP_CONFIG: /tmp/gh-aw/mcp-config/mcp-servers.json GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index e854eb4eeac..b6f5612fe73 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6502,13 +6502,13 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.spdx.json format: spdx-json output-file: sbom.spdx.json - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.cdx.json format: cyclonedx-json @@ -6698,7 +6698,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2 + uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 with: build_script_override: scripts/build-release.sh go_version_file: go.mod diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index 62826fd0598..d3b0dba4e86 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -231,7 +231,7 @@ jobs: ORGANIZATION: ${{ env.ORGANIZATION }} id: stale-repos name: Run stale_repos tool - uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3 + uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3.0.2 - env: INACTIVE_REPOS: ${{ steps.stale-repos.outputs.inactiveRepos }} name: Save stale repos output diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index b8ad8e7f5f3..3f60c9a5651 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -7546,7 +7546,7 @@ jobs: persist-credentials: false - name: Super-linter id: super-linter - uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.2.1 + uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.3.1 env: CREATE_LOG_FILE: "true" DEFAULT_BRANCH: main From 302538c1c0620a383ea209e61b170bd7d555dd36 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 20:05:10 +0000 Subject: [PATCH 4/4] Move CI check to pre-activation job - Create check_ci_status job that runs before agent - Add job-level if condition to skip agent when CI is passing - Remove conditional checks from individual setup steps - Update prompt to reference check_ci_status outputs - Agent job now depends on check_ci_status and only runs when ci_needs_fix=true Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/hourly-ci-cleaner.lock.yml | 90 +++++++++++++------- .github/workflows/hourly-ci-cleaner.md | 83 +++++++++--------- 2 files changed, 100 insertions(+), 73 deletions(-) diff --git a/.github/workflows/hourly-ci-cleaner.lock.yml b/.github/workflows/hourly-ci-cleaner.lock.yml index 289bf890784..f8675821061 100644 --- a/.github/workflows/hourly-ci-cleaner.lock.yml +++ b/.github/workflows/hourly-ci-cleaner.lock.yml @@ -135,7 +135,10 @@ jobs: }); agent: - needs: activation + needs: + - activation + - check_ci_status + if: needs.check_ci_status.outputs.ci_needs_fix == 'true' runs-on: ubuntu-latest permissions: actions: read @@ -171,28 +174,19 @@ jobs: mkdir -p /tmp/gh-aw/agent mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - id: ci_check - name: Check last CI workflow run status on main branch - run: "# Get the last CI workflow run on main branch, excluding pending and cancelled runs\nLAST_RUN=$(gh run list --workflow=ci.yml --branch=main --limit 50 --json conclusion,status,databaseId \\\n | jq -r '[.[] | select(.status == \"completed\" and (.conclusion == \"success\" or .conclusion == \"failure\"))] | .[0]')\n\nCONCLUSION=$(echo \"$LAST_RUN\" | jq -r '.conclusion')\nRUN_ID=$(echo \"$LAST_RUN\" | jq -r '.databaseId')\n\necho \"Last CI run conclusion: ${CONCLUSION}\"\necho \"Run ID: ${RUN_ID}\"\n\n# Write to environment and step summary\necho \"CI_STATUS=${CONCLUSION}\" >> \"$GITHUB_ENV\"\necho \"CI_RUN_ID=${RUN_ID}\" >> \"$GITHUB_ENV\"\n\nif [ \"$CONCLUSION\" = \"success\" ]; then\n echo \"✅ CI is passing on main branch - no action needed\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"CI_NEEDS_FIX=false\" >> \"$GITHUB_ENV\"\nelse\n echo \"❌ CI is failing on main branch - agent will attempt to fix\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"Run ID: ${RUN_ID}\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"CI_NEEDS_FIX=true\" >> \"$GITHUB_ENV\"\nfi\n" - - if: env.CI_NEEDS_FIX == 'true' - name: Install Make + - name: Install Make run: | sudo apt-get update sudo apt-get install -y make - - if: env.CI_NEEDS_FIX == 'true' - name: Setup Go + - name: Setup Go uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c with: cache: true go-version-file: go.mod - - if: env.CI_NEEDS_FIX == 'true' - name: Install npm dependencies + - name: Install npm dependencies run: npm ci working-directory: ./pkg/workflow/js - - if: env.CI_NEEDS_FIX == 'true' - name: Install dev dependencies + - name: Install dev dependencies run: make deps-dev - name: Configure Git credentials @@ -1956,10 +1950,10 @@ jobs: env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_ENV_CI_NEEDS_FIX: ${{ env.CI_NEEDS_FIX }} - GH_AW_ENV_CI_STATUS: ${{ env.CI_STATUS }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_NUMBER: ${{ github.run_number }} + GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_RUN_ID: ${{ needs.check_ci_status.outputs.ci_run_id }} + GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_STATUS: ${{ needs.check_ci_status.outputs.ci_status }} run: | PROMPT_DIR="$(dirname "$GH_AW_PROMPT")" mkdir -p "$PROMPT_DIR" @@ -2255,17 +2249,12 @@ jobs: - **Repository**: __GH_AW_GITHUB_REPOSITORY__ - **Run Number**: #__GH_AW_GITHUB_RUN_NUMBER__ - - **CI Status**: __GH_AW_ENV_CI_STATUS__ + - **CI Status**: __GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_STATUS__ + - **CI Run ID**: __GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_RUN_ID__ ## Your Task - **IMPORTANT**: Check the CI status first: - - **CI Status**: __GH_AW_ENV_CI_STATUS__ - - **CI Needs Fix**: __GH_AW_ENV_CI_NEEDS_FIX__ - - If `CI_NEEDS_FIX` is `false` or `CI_STATUS` is `success`, then **CI is passing and no action is needed**. Simply report that CI is healthy and exit successfully without making any changes. - - If CI has failed on the main branch, follow the instructions from the ci-cleaner agent to: + The CI workflow has failed on the main branch. Follow the instructions from the ci-cleaner agent to: 1. **Format sources** - Run `make fmt` to format all code 2. **Run linters** - Run `make lint` and fix any issues @@ -2310,10 +2299,10 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_ENV_CI_NEEDS_FIX: ${{ env.CI_NEEDS_FIX }} - GH_AW_ENV_CI_STATUS: ${{ env.CI_STATUS }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_NUMBER: ${{ github.run_number }} + GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_RUN_ID: ${{ needs.check_ci_status.outputs.ci_run_id }} + GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_STATUS: ${{ needs.check_ci_status.outputs.ci_status }} with: script: | const fs = require("fs"), @@ -2343,10 +2332,10 @@ jobs: return await substitutePlaceholders({ file: process.env.GH_AW_PROMPT, substitutions: { - GH_AW_ENV_CI_NEEDS_FIX: process.env.GH_AW_ENV_CI_NEEDS_FIX, - GH_AW_ENV_CI_STATUS: process.env.GH_AW_ENV_CI_STATUS, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, - GH_AW_GITHUB_RUN_NUMBER: process.env.GH_AW_GITHUB_RUN_NUMBER + GH_AW_GITHUB_RUN_NUMBER: process.env.GH_AW_GITHUB_RUN_NUMBER, + GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_RUN_ID: process.env.GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_RUN_ID, + GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_STATUS: process.env.GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_STATUS } }); - name: Append XPIA security instructions to prompt @@ -2513,10 +2502,10 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_ENV_CI_NEEDS_FIX: ${{ env.CI_NEEDS_FIX }} - GH_AW_ENV_CI_STATUS: ${{ env.CI_STATUS }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_NUMBER: ${{ github.run_number }} + GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_RUN_ID: ${{ needs.check_ci_status.outputs.ci_run_id }} + GH_AW_NEEDS_CHECK_CI_STATUS_OUTPUTS_CI_STATUS: ${{ needs.check_ci_status.outputs.ci_status }} with: script: | const fs = require("fs"); @@ -5984,6 +5973,45 @@ jobs: path: /tmp/gh-aw/aw.patch if-no-files-found: ignore + check_ci_status: + needs: activation + runs-on: ubuntu-latest + permissions: + actions: read + + outputs: + ci_needs_fix: ${{ steps.ci_check.outputs.ci_needs_fix }} + ci_run_id: ${{ steps.ci_check.outputs.ci_run_id }} + ci_status: ${{ steps.ci_check.outputs.ci_status }} + steps: + - name: Check last CI workflow run status on main branch + id: ci_check + run: | + # Get the last CI workflow run on main branch, excluding pending and cancelled runs + LAST_RUN=$(gh run list --workflow=ci.yml --branch=main --limit 50 --json conclusion,status,databaseId \ + | jq -r '[.[] | select(.status == "completed" and (.conclusion == "success" or .conclusion == "failure"))] | .[0]') + + CONCLUSION=$(echo "$LAST_RUN" | jq -r '.conclusion') + RUN_ID=$(echo "$LAST_RUN" | jq -r '.databaseId') + + echo "Last CI run conclusion: ${CONCLUSION}" + echo "Run ID: ${RUN_ID}" + + # Set outputs for use in other jobs + echo "ci_status=${CONCLUSION}" >> "$GITHUB_OUTPUT" + echo "ci_run_id=${RUN_ID}" >> "$GITHUB_OUTPUT" + + if [ "$CONCLUSION" = "success" ]; then + echo "✅ CI is passing on main branch - no action needed" >> "$GITHUB_STEP_SUMMARY" + echo "ci_needs_fix=false" >> "$GITHUB_OUTPUT" + else + echo "❌ CI is failing on main branch - agent will attempt to fix" >> "$GITHUB_STEP_SUMMARY" + echo "Run ID: ${RUN_ID}" >> "$GITHUB_STEP_SUMMARY" + echo "ci_needs_fix=true" >> "$GITHUB_OUTPUT" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + conclusion: needs: - activation diff --git a/.github/workflows/hourly-ci-cleaner.md b/.github/workflows/hourly-ci-cleaner.md index 1afba324df6..2be14c5cbfe 100644 --- a/.github/workflows/hourly-ci-cleaner.md +++ b/.github/workflows/hourly-ci-cleaner.md @@ -30,60 +30,64 @@ sandbox: - "/usr/local/bin/npm:/usr/local/bin/npm:ro" - "/usr/local/lib/node_modules:/usr/local/lib/node_modules:ro" - "/opt/hostedtoolcache/go:/opt/hostedtoolcache/go:ro" +if: needs.check_ci_status.outputs.ci_needs_fix == 'true' +jobs: + check_ci_status: + runs-on: ubuntu-latest + permissions: + actions: read + outputs: + ci_needs_fix: ${{ steps.ci_check.outputs.ci_needs_fix }} + ci_status: ${{ steps.ci_check.outputs.ci_status }} + ci_run_id: ${{ steps.ci_check.outputs.ci_run_id }} + steps: + - name: Check last CI workflow run status on main branch + id: ci_check + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Get the last CI workflow run on main branch, excluding pending and cancelled runs + LAST_RUN=$(gh run list --workflow=ci.yml --branch=main --limit 50 --json conclusion,status,databaseId \ + | jq -r '[.[] | select(.status == "completed" and (.conclusion == "success" or .conclusion == "failure"))] | .[0]') + + CONCLUSION=$(echo "$LAST_RUN" | jq -r '.conclusion') + RUN_ID=$(echo "$LAST_RUN" | jq -r '.databaseId') + + echo "Last CI run conclusion: ${CONCLUSION}" + echo "Run ID: ${RUN_ID}" + + # Set outputs for use in other jobs + echo "ci_status=${CONCLUSION}" >> "$GITHUB_OUTPUT" + echo "ci_run_id=${RUN_ID}" >> "$GITHUB_OUTPUT" + + if [ "$CONCLUSION" = "success" ]; then + echo "✅ CI is passing on main branch - no action needed" >> "$GITHUB_STEP_SUMMARY" + echo "ci_needs_fix=false" >> "$GITHUB_OUTPUT" + else + echo "❌ CI is failing on main branch - agent will attempt to fix" >> "$GITHUB_STEP_SUMMARY" + echo "Run ID: ${RUN_ID}" >> "$GITHUB_STEP_SUMMARY" + echo "ci_needs_fix=true" >> "$GITHUB_OUTPUT" + fi steps: - # Early exit guard: Check if there's work to do before consuming tokens - # If CI is passing, the workflow exits early without running the agent - - name: Check last CI workflow run status on main branch - id: ci_check - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Get the last CI workflow run on main branch, excluding pending and cancelled runs - LAST_RUN=$(gh run list --workflow=ci.yml --branch=main --limit 50 --json conclusion,status,databaseId \ - | jq -r '[.[] | select(.status == "completed" and (.conclusion == "success" or .conclusion == "failure"))] | .[0]') - - CONCLUSION=$(echo "$LAST_RUN" | jq -r '.conclusion') - RUN_ID=$(echo "$LAST_RUN" | jq -r '.databaseId') - - echo "Last CI run conclusion: ${CONCLUSION}" - echo "Run ID: ${RUN_ID}" - - # Write to environment and step summary - echo "CI_STATUS=${CONCLUSION}" >> "$GITHUB_ENV" - echo "CI_RUN_ID=${RUN_ID}" >> "$GITHUB_ENV" - - if [ "$CONCLUSION" = "success" ]; then - echo "✅ CI is passing on main branch - no action needed" >> "$GITHUB_STEP_SUMMARY" - echo "CI_NEEDS_FIX=false" >> "$GITHUB_ENV" - else - echo "❌ CI is failing on main branch - agent will attempt to fix" >> "$GITHUB_STEP_SUMMARY" - echo "Run ID: ${RUN_ID}" >> "$GITHUB_STEP_SUMMARY" - echo "CI_NEEDS_FIX=true" >> "$GITHUB_ENV" - fi - name: Install Make - if: env.CI_NEEDS_FIX == 'true' run: | sudo apt-get update sudo apt-get install -y make - name: Setup Go - if: env.CI_NEEDS_FIX == 'true' uses: actions/setup-go@v6 with: go-version-file: go.mod cache: true - name: Set up Node.js - if: env.CI_NEEDS_FIX == 'true' uses: actions/setup-node@v6 with: node-version: "24" cache: npm cache-dependency-path: pkg/workflow/js/package-lock.json - name: Install npm dependencies - if: env.CI_NEEDS_FIX == 'true' run: npm ci working-directory: ./pkg/workflow/js - name: Install dev dependencies - if: env.CI_NEEDS_FIX == 'true' run: make deps-dev safe-outputs: create-pull-request: @@ -109,17 +113,12 @@ When CI fails on the main branch, automatically diagnose and fix the issues by: - **Repository**: ${{ github.repository }} - **Run Number**: #${{ github.run_number }} -- **CI Status**: ${{ env.CI_STATUS }} +- **CI Status**: ${{ needs.check_ci_status.outputs.ci_status }} +- **CI Run ID**: ${{ needs.check_ci_status.outputs.ci_run_id }} ## Your Task -**IMPORTANT**: Check the CI status first: -- **CI Status**: ${{ env.CI_STATUS }} -- **CI Needs Fix**: ${{ env.CI_NEEDS_FIX }} - -If `CI_NEEDS_FIX` is `false` or `CI_STATUS` is `success`, then **CI is passing and no action is needed**. Simply report that CI is healthy and exit successfully without making any changes. - -If CI has failed on the main branch, follow the instructions from the ci-cleaner agent to: +The CI workflow has failed on the main branch. Follow the instructions from the ci-cleaner agent to: 1. **Format sources** - Run `make fmt` to format all code 2. **Run linters** - Run `make lint` and fix any issues