Refactor workflow dependency checks into reusable script

This commit is contained in:
shenlan 2025-09-29 15:58:03 +08:00
parent cdce6d2922
commit e897ecc48f
4 changed files with 184 additions and 3 deletions

View File

@ -0,0 +1,84 @@
const DEFAULT_REQUIRED_BRANCH = 'main';
function resolveBranch(context) {
const { eventName, ref, payload } = context;
if (eventName === 'workflow_run') {
return payload.workflow_run?.head_branch || '';
}
if (eventName === 'pull_request' || eventName === 'pull_request_target') {
return payload.pull_request?.head?.ref || '';
}
if (typeof ref === 'string' && ref.startsWith('refs/heads/')) {
return ref.replace('refs/heads/', '');
}
return '';
}
async function ensureSuccessfulRun({ github, context, core }, workflowFile, branch) {
const { data } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: workflowFile,
branch,
per_page: 1,
status: 'completed'
});
if (!data.workflow_runs.length) {
core.setFailed(`No completed runs of ${workflowFile} found on branch ${branch}.`);
return false;
}
const [run] = data.workflow_runs;
if (run.conclusion !== 'success') {
core.setFailed(`Latest ${workflowFile} run (${run.id}) concluded with ${run.conclusion}.`);
return false;
}
core.info(`Dependency workflow ${workflowFile} succeeded on branch ${branch} (run id ${run.id}).`);
return true;
}
async function evaluateWorkflowStatus({ github, context, core }, options) {
const {
dependencyWorkflowFile,
requiredBranch = DEFAULT_REQUIRED_BRANCH,
} = options;
const branch = resolveBranch(context);
if (!branch) {
core.info('Unable to determine triggering branch, skipping downstream jobs.');
core.setOutput('should-run', 'false');
return;
}
if (branch !== requiredBranch) {
core.info(`Branch ${branch} is not ${requiredBranch}; skipping downstream jobs.`);
core.setOutput('should-run', 'false');
return;
}
if (context.eventName === 'workflow_run') {
const conclusion = context.payload.workflow_run?.conclusion;
if (conclusion !== 'success') {
core.setFailed(`Upstream workflow ${context.payload.workflow_run?.name} concluded with ${conclusion}.`);
return;
}
}
const ok = await ensureSuccessfulRun({ github, context, core }, dependencyWorkflowFile, branch);
if (!ok) {
return;
}
core.setOutput('should-run', 'true');
}
module.exports = {
evaluateWorkflowStatus,
};

View File

@ -15,9 +15,41 @@ on:
workflow_dispatch:
branches:
- main
workflow_run:
workflows:
- Alicloud Landing Zone Baseline
types:
- completed
jobs:
verify-baseline-status:
name: Verify Alicloud baseline readiness
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
outputs:
should-run: ${{ steps.evaluate.outputs.should-run }}
steps:
- name: Checkout helpers
uses: actions/checkout@v4
with:
sparse-checkout: |
.github/scripts/evaluate-workflow-status.js
sparse-checkout-cone-mode: false
- name: Evaluate upstream workflow status
id: evaluate
uses: actions/github-script@v7
with:
script: |
const { evaluateWorkflowStatus } = require('./.github/scripts/evaluate-workflow-status');
await evaluateWorkflowStatus({ github, context, core }, {
dependencyWorkflowFile: 'iac-pipeline-alicloud-landingzone-baseline.yaml',
});
apply-cluster-resources:
needs: verify-baseline-status
if: needs.verify-baseline-status.outputs.should-run == 'true'
uses: svc-design/actions/.github/workflows/setup-gcp-cloud.yml@main
with:
config: 'multi-cluster-config.yaml'

View File

@ -13,10 +13,41 @@ on:
description: 'Whether to perform a dry-run'
required: false
default: 'true'
workflow_run:
workflows:
- Provision Monitor Server Infrastructure
types:
- completed
jobs:
verify-dependencies:
name: Verify dependency workflows
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
outputs:
should-run: ${{ steps.evaluate.outputs.should-run }}
steps:
- name: Checkout helpers
uses: actions/checkout@v4
with:
sparse-checkout: |
.github/scripts/evaluate-workflow-status.js
sparse-checkout-cone-mode: false
- name: Evaluate upstream workflow status
id: evaluate
uses: actions/github-script@v7
with:
script: |
const { evaluateWorkflowStatus } = require('./.github/scripts/evaluate-workflow-status');
await evaluateWorkflowStatus({ github, context, core }, {
dependencyWorkflowFile: 'iac-pipeline-infrastructure-monitor-server.yml',
});
deploy:
if: github.ref == 'refs/heads/main'
needs: verify-dependencies
if: needs.verify-dependencies.outputs.should-run == 'true'
runs-on: ubuntu-latest
env:
DEPLOY_ACTION: ${{ github.event.inputs.deploy_action || 'upgrade' }}

View File

@ -11,6 +11,11 @@ on:
description: "Run Ansible in check mode"
required: false
default: 'true'
workflow_run:
workflows:
- MultiCluster Pipeline Create with IAC tools
types:
- completed
push:
branches:
- main
@ -25,15 +30,44 @@ env:
ANSIBLE_LOAD_CALLBACK_PLUGINS: 'true'
jobs:
verify-dependencies:
name: Verify dependency workflows
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
outputs:
should-run: ${{ steps.evaluate.outputs.should-run }}
steps:
- name: Checkout helpers
uses: actions/checkout@v4
with:
sparse-checkout: |
.github/scripts/evaluate-workflow-status.js
sparse-checkout-cone-mode: false
- name: Evaluate upstream workflow status
id: evaluate
uses: actions/github-script@v7
with:
script: |
const { evaluateWorkflowStatus } = require('./.github/scripts/evaluate-workflow-status');
await evaluateWorkflowStatus({ github, context, core }, {
dependencyWorkflowFile: 'iac-pipeline-create.yml',
});
pre-setup:
needs: verify-dependencies
if: needs.verify-dependencies.outputs.should-run == 'true'
runs-on: ubuntu-latest
steps:
- name: Pre-setup confirmation
run: echo "Pre-setup stage completed"
deploy:
needs: pre-setup
if: github.ref == 'refs/heads/main'
needs:
- pre-setup
- verify-dependencies
if: needs.verify-dependencies.outputs.should-run == 'true'
runs-on: ubuntu-latest
strategy:
matrix: