PR Self-Heal #20591
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR Self-Heal | |
| on: | |
| workflow_run: | |
| workflows: | |
| - Copilot Review Gate | |
| - Verify Lite | |
| - PR Maintenance | |
| - Quality Gates | |
| - coverage-check | |
| types: [completed] | |
| schedule: | |
| - cron: "*/30 * * * *" | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: "PR number (optional)" | |
| required: false | |
| dry_run: | |
| description: "Dry-run mode" | |
| required: false | |
| default: "false" | |
| max_rounds: | |
| description: "Override max rounds" | |
| required: false | |
| concurrency: | |
| group: >- | |
| pr-self-heal-${{ | |
| github.event_name == 'workflow_dispatch' && (inputs.pr_number || 'manual') | |
| || github.event_name == 'workflow_run' && github.event.workflow_run.id | |
| || github.ref | |
| }} | |
| cancel-in-progress: true | |
| permissions: | |
| actions: write | |
| contents: read | |
| issues: write | |
| pull-requests: write | |
| jobs: | |
| self-heal: | |
| if: >- | |
| !contains(fromJSON('["1","true","yes","on","TRUE","YES","ON","True","Yes","On"]'), vars.AE_AUTOMATION_GLOBAL_DISABLE) | |
| && ( | |
| github.event_name == 'workflow_dispatch' | |
| || (vars.AE_SELF_HEAL_ENABLED == '1' | |
| && ( | |
| github.event_name == 'schedule' | |
| || (github.event_name == 'workflow_run' | |
| && join(github.event.workflow_run.pull_requests.*.number, '') != '' | |
| && ( | |
| github.event.workflow_run.conclusion == 'failure' | |
| || github.event.workflow_run.conclusion == 'timed_out' | |
| || github.event.workflow_run.conclusion == 'cancelled' | |
| ) | |
| ) | |
| ) | |
| ) | |
| ) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node + pnpm | |
| uses: ./.github/actions/setup-node-pnpm | |
| with: | |
| node-version: "20" | |
| - name: Resolve automation config | |
| env: | |
| AE_AUTOMATION_PROFILE: ${{ vars.AE_AUTOMATION_PROFILE || '' }} | |
| AE_COPILOT_AUTO_FIX: ${{ vars.AE_COPILOT_AUTO_FIX || '' }} | |
| AE_COPILOT_AUTO_FIX_SCOPE: ${{ vars.AE_COPILOT_AUTO_FIX_SCOPE || '' }} | |
| AE_COPILOT_AUTO_FIX_LABEL: ${{ vars.AE_COPILOT_AUTO_FIX_LABEL || '' }} | |
| AE_AUTO_MERGE: ${{ vars.AE_AUTO_MERGE || '' }} | |
| AE_AUTO_MERGE_MODE: ${{ vars.AE_AUTO_MERGE_MODE || '' }} | |
| AE_AUTO_MERGE_LABEL: ${{ vars.AE_AUTO_MERGE_LABEL || '' }} | |
| AE_AUTO_MERGE_REQUIRE_RISK_LOW: ${{ vars.AE_AUTO_MERGE_REQUIRE_RISK_LOW || '' }} | |
| AE_AUTO_MERGE_REQUIRE_CHANGE_PACKAGE: ${{ vars.AE_AUTO_MERGE_REQUIRE_CHANGE_PACKAGE || '' }} | |
| AE_AUTO_MERGE_CHANGE_PACKAGE_ALLOW_WARN: ${{ vars.AE_AUTO_MERGE_CHANGE_PACKAGE_ALLOW_WARN || '' }} | |
| AE_GH_THROTTLE_MS: ${{ vars.AE_GH_THROTTLE_MS || '' }} | |
| AE_GH_RETRY_MAX_ATTEMPTS: ${{ vars.AE_GH_RETRY_MAX_ATTEMPTS || '' }} | |
| AE_GH_RETRY_INITIAL_DELAY_MS: ${{ vars.AE_GH_RETRY_INITIAL_DELAY_MS || '' }} | |
| AE_GH_RETRY_MAX_DELAY_MS: ${{ vars.AE_GH_RETRY_MAX_DELAY_MS || '' }} | |
| AE_GH_RETRY_MULTIPLIER: ${{ vars.AE_GH_RETRY_MULTIPLIER || '' }} | |
| AE_GH_RETRY_JITTER_MS: ${{ vars.AE_GH_RETRY_JITTER_MS || '' }} | |
| AE_GH_RETRY_DEBUG: ${{ vars.AE_GH_RETRY_DEBUG || '' }} | |
| COPILOT_REVIEW_WAIT_MINUTES: ${{ vars.COPILOT_REVIEW_WAIT_MINUTES || '' }} | |
| COPILOT_REVIEW_MAX_ATTEMPTS: ${{ vars.COPILOT_REVIEW_MAX_ATTEMPTS || '' }} | |
| run: | | |
| node scripts/ci/lib/automation-config.mjs --format github-env >> "$GITHUB_ENV" | |
| node scripts/ci/lib/automation-config.mjs --format summary >> "$GITHUB_STEP_SUMMARY" | |
| - name: Run PR self-heal | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }} | |
| PR_NUMBER: ${{ github.event_name == 'workflow_dispatch' && inputs.pr_number || '' }} | |
| WORKFLOW_RUN_PR_NUMBERS: ${{ github.event_name == 'workflow_run' && join(github.event.workflow_run.pull_requests.*.number, ',') || '' }} | |
| AE_SELF_HEAL_DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || vars.AE_SELF_HEAL_DRY_RUN || 'false' }} | |
| AE_SELF_HEAL_MAX_ROUNDS: ${{ github.event_name == 'workflow_dispatch' && inputs.max_rounds || vars.AE_SELF_HEAL_MAX_ROUNDS || '3' }} | |
| AE_SELF_HEAL_MAX_AGE_MINUTES: ${{ vars.AE_SELF_HEAL_MAX_AGE_MINUTES || '180' }} | |
| AE_SELF_HEAL_MAX_PRS: ${{ vars.AE_SELF_HEAL_MAX_PRS || '20' }} | |
| AE_SELF_HEAL_ROUND_WAIT_SECONDS: ${{ vars.AE_SELF_HEAL_ROUND_WAIT_SECONDS || '60' }} | |
| AE_SELF_HEAL_WAIT_STRATEGY: ${{ vars.AE_SELF_HEAL_WAIT_STRATEGY || 'fixed' }} | |
| AE_SELF_HEAL_ROUND_WAIT_MAX_SECONDS: ${{ vars.AE_SELF_HEAL_ROUND_WAIT_MAX_SECONDS || vars.AE_SELF_HEAL_ROUND_WAIT_SECONDS || '60' }} | |
| run: node scripts/ci/pr-self-heal.mjs |