CI Status Check #1208
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: CI Status Check | |
| on: | |
| workflow_run: | |
| workflows: | |
| - "Shell Lint (shellcheck)" | |
| - "TypeScript CI" | |
| - "Secret Detection (gitleaks)" | |
| - "Lint GitHub Actions" | |
| - "Shell Compatibility Test" | |
| - "Validate Codex Config" | |
| - "Validate JSON Templates" | |
| types: | |
| - completed | |
| jobs: | |
| status-check: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: read | |
| statuses: write | |
| steps: | |
| - name: Check all required workflows passed | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| with: | |
| script: | | |
| const workflowRun = context.payload.workflow_run; | |
| // Get all workflow runs for this commit | |
| const { data: runs } = await github.rest.actions.listWorkflowRunsForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| head_sha: workflowRun.head_sha, | |
| event: workflowRun.event, | |
| per_page: 100 | |
| }); | |
| // Required workflow names (must match the trigger list) | |
| const requiredWorkflows = [ | |
| 'Shell Lint (shellcheck)', | |
| 'TypeScript CI', | |
| 'Secret Detection (gitleaks)', | |
| 'Lint GitHub Actions', | |
| 'Shell Compatibility Test', | |
| 'Validate Codex Config', | |
| 'Validate JSON Templates' | |
| ]; | |
| // Filter runs to only required workflows | |
| const requiredRuns = runs.workflow_runs.filter(run => | |
| requiredWorkflows.includes(run.name) | |
| ); | |
| // Group by workflow name and get the latest run for each | |
| const latestRuns = {}; | |
| for (const run of requiredRuns) { | |
| if (!latestRuns[run.name] || run.created_at > latestRuns[run.name].created_at) { | |
| latestRuns[run.name] = run; | |
| } | |
| } | |
| // Check if all required workflows have completed successfully | |
| const results = []; | |
| for (const workflowName of requiredWorkflows) { | |
| const run = latestRuns[workflowName]; | |
| if (!run) { | |
| results.push(`⏭️ ${workflowName}: Not run (paths filter)`); | |
| continue; | |
| } | |
| if (run.status !== 'completed') { | |
| results.push(`⏳ ${workflowName}: ${run.status}`); | |
| continue; | |
| } | |
| if (run.conclusion === 'success' || run.conclusion === 'skipped') { | |
| results.push(`✅ ${workflowName}: ${run.conclusion}`); | |
| } else { | |
| results.push(`❌ ${workflowName}: ${run.conclusion}`); | |
| } | |
| } | |
| core.info('Required workflow results:'); | |
| for (const result of results) { | |
| core.info(result); | |
| } | |
| // Check if all required workflows either passed or were skipped | |
| const allPassedOrSkipped = requiredWorkflows.every(workflowName => { | |
| const run = latestRuns[workflowName]; | |
| // Not found means skipped by paths filter - treat as success | |
| if (!run) return true; | |
| // Must be completed | |
| if (run.status !== 'completed') return false; | |
| // Success or skipped are acceptable | |
| return run.conclusion === 'success' || run.conclusion === 'skipped'; | |
| }); | |
| const allCompleted = requiredWorkflows.every(workflowName => { | |
| const run = latestRuns[workflowName]; | |
| // Not found means skipped by paths filter - treat as completed | |
| if (!run) return true; | |
| return run.status === 'completed'; | |
| }); | |
| if (!allCompleted) { | |
| core.info('⏳ Waiting for all workflows to complete...'); | |
| // Set pending status | |
| await github.rest.repos.createCommitStatus({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| sha: workflowRun.head_sha, | |
| state: 'pending', | |
| context: 'status-check', | |
| description: 'Waiting for all workflows to complete...' | |
| }); | |
| return; | |
| } | |
| if (!allPassedOrSkipped) { | |
| const failed = requiredWorkflows | |
| .map(workflowName => { | |
| const run = latestRuns[workflowName]; | |
| if (!run || run.conclusion === 'success' || run.conclusion === 'skipped') return null; | |
| return `${workflowName} (${run.conclusion})`; | |
| }) | |
| .filter(Boolean); | |
| // Set failure status | |
| await github.rest.repos.createCommitStatus({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| sha: workflowRun.head_sha, | |
| state: 'failure', | |
| context: 'status-check', | |
| description: `Required workflows failed: ${failed.join(', ')}` | |
| }); | |
| core.setFailed(`Required workflows failed: ${failed.join(', ')}`); | |
| return; | |
| } | |
| core.info('✅ All required workflows passed!'); | |
| // Set success status | |
| await github.rest.repos.createCommitStatus({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| sha: workflowRun.head_sha, | |
| state: 'success', | |
| context: 'status-check', | |
| description: 'All required workflows passed!' | |
| }); |