ci: comment PR artifacts from validation run
This commit is contained in:
112
.github/workflows/comment-pr-artifacts.yml
vendored
112
.github/workflows/comment-pr-artifacts.yml
vendored
@@ -1,112 +0,0 @@
|
|||||||
name: Comment PR Artifacts
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
workflows:
|
|
||||||
- PR Build Validation
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
pull-requests: write
|
|
||||||
issues: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
comment:
|
|
||||||
# Only runs for PR Build Validation runs triggered by PRs.
|
|
||||||
if: ${{ github.event.workflow_run.event == 'pull_request' }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Comment with artifact download link
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
script: |
|
|
||||||
const run = context.payload.workflow_run;
|
|
||||||
const owner = context.repo.owner;
|
|
||||||
const repo = context.repo.repo;
|
|
||||||
|
|
||||||
let prNumber = run.pull_requests?.[0]?.number;
|
|
||||||
|
|
||||||
// `workflow_run` payload does not reliably include pull request numbers.
|
|
||||||
// Ask the Actions API for the triggering run itself and use that as source of truth.
|
|
||||||
if (!prNumber) {
|
|
||||||
const runDetails = await github.rest.actions.getWorkflowRun({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
run_id: run.id,
|
|
||||||
});
|
|
||||||
prNumber = runDetails.data.pull_requests?.[0]?.number;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!prNumber) {
|
|
||||||
core.info(`No PR number found on workflow run ${run.id}; skipping.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only comment when the PR build job actually ran (i.e. authorization passed).
|
|
||||||
// Unauthorized PRs targeting non-dev will skip the `build` job.
|
|
||||||
const jobs = await github.paginate(
|
|
||||||
github.rest.actions.listJobsForWorkflowRun,
|
|
||||||
{ owner, repo, run_id: run.id, per_page: 100 }
|
|
||||||
);
|
|
||||||
const buildJob = jobs.find((j) => j.name === 'build');
|
|
||||||
if (!buildJob) {
|
|
||||||
core.info('No `build` job found on this run; skipping.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (buildJob.conclusion === 'skipped') {
|
|
||||||
core.info('`build` job was skipped; skipping comment.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// List artifacts from the run. If none exist (e.g. build failed before packaging),
|
|
||||||
// still comment with the run link so testers can see logs.
|
|
||||||
const artifacts = await github.paginate(
|
|
||||||
github.rest.actions.listWorkflowRunArtifacts,
|
|
||||||
{ owner, repo, run_id: run.id, per_page: 100 }
|
|
||||||
);
|
|
||||||
const active = artifacts.filter((a) => !a.expired);
|
|
||||||
|
|
||||||
const marker = '<!-- codenomad-pr-artifacts -->';
|
|
||||||
const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${run.id}`;
|
|
||||||
const retentionDays = 7;
|
|
||||||
|
|
||||||
const artifactsBlock = active.length
|
|
||||||
? ['Artifacts:', ...active.map((a) => `- ${a.name}`)].join('\n')
|
|
||||||
: 'Artifacts: (none found on this run)';
|
|
||||||
|
|
||||||
const body = [
|
|
||||||
marker,
|
|
||||||
'PR builds are available as GitHub Actions artifacts:',
|
|
||||||
'',
|
|
||||||
runUrl,
|
|
||||||
'',
|
|
||||||
`Artifacts expire in ${retentionDays} days.`,
|
|
||||||
artifactsBlock,
|
|
||||||
].join('\n');
|
|
||||||
|
|
||||||
const comments = await github.paginate(
|
|
||||||
github.rest.issues.listComments,
|
|
||||||
{ owner, repo, issue_number: prNumber, per_page: 100 }
|
|
||||||
);
|
|
||||||
const existing = comments.find((c) => (c.body || '').includes(marker));
|
|
||||||
|
|
||||||
if (existing) {
|
|
||||||
await github.rest.issues.updateComment({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
comment_id: existing.id,
|
|
||||||
body,
|
|
||||||
});
|
|
||||||
core.info(`Updated existing artifacts comment: ${existing.html_url}`);
|
|
||||||
} else {
|
|
||||||
const created = await github.rest.issues.createComment({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
issue_number: prNumber,
|
|
||||||
body,
|
|
||||||
});
|
|
||||||
core.info(`Created artifacts comment: ${created.data.html_url}`);
|
|
||||||
}
|
|
||||||
75
.github/workflows/pr-build.yml
vendored
75
.github/workflows/pr-build.yml
vendored
@@ -10,6 +10,8 @@ on:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
actions: write
|
actions: write
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: pr-build-${{ github.event.pull_request.number }}
|
group: pr-build-${{ github.event.pull_request.number }}
|
||||||
@@ -54,3 +56,76 @@ jobs:
|
|||||||
actions_artifacts_retention_days: 7
|
actions_artifacts_retention_days: 7
|
||||||
actions_artifacts_name_prefix: pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-
|
actions_artifacts_name_prefix: pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-
|
||||||
set_versions: false
|
set_versions: false
|
||||||
|
|
||||||
|
comment-artifacts:
|
||||||
|
needs:
|
||||||
|
- authorize
|
||||||
|
- build
|
||||||
|
if: ${{ always() && needs.authorize.outputs.allowed == 'true' }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Get PR number
|
||||||
|
id: get-pr
|
||||||
|
uses: bcgov/action-get-pr@v0.1.1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Comment with artifact download link
|
||||||
|
uses: actions/github-script@v8
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
script: |
|
||||||
|
const owner = context.repo.owner;
|
||||||
|
const repo = context.repo.repo;
|
||||||
|
const prNumber = Number('${{ steps.get-pr.outputs.pr }}');
|
||||||
|
if (!prNumber) {
|
||||||
|
core.setFailed('Failed to resolve PR number.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const artifacts = await github.paginate(
|
||||||
|
github.rest.actions.listWorkflowRunArtifacts,
|
||||||
|
{ owner, repo, run_id: context.runId, per_page: 100 }
|
||||||
|
);
|
||||||
|
const active = artifacts.filter((a) => !a.expired);
|
||||||
|
|
||||||
|
const marker = '<!-- codenomad-pr-artifacts -->';
|
||||||
|
const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${context.runId}`;
|
||||||
|
const retentionDays = 7;
|
||||||
|
const artifactsBlock = active.length
|
||||||
|
? ['Artifacts:', ...active.map((a) => `- ${a.name}`)].join('\n')
|
||||||
|
: 'Artifacts: (none found on this run)';
|
||||||
|
|
||||||
|
const body = [
|
||||||
|
marker,
|
||||||
|
'PR builds are available as GitHub Actions artifacts:',
|
||||||
|
'',
|
||||||
|
runUrl,
|
||||||
|
'',
|
||||||
|
`Artifacts expire in ${retentionDays} days.`,
|
||||||
|
artifactsBlock,
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const comments = await github.paginate(
|
||||||
|
github.rest.issues.listComments,
|
||||||
|
{ owner, repo, issue_number: prNumber, per_page: 100 }
|
||||||
|
);
|
||||||
|
const existing = comments.find((c) => (c.body || '').includes(marker));
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
await github.rest.issues.updateComment({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
comment_id: existing.id,
|
||||||
|
body,
|
||||||
|
});
|
||||||
|
core.info(`Updated existing artifacts comment: ${existing.html_url}`);
|
||||||
|
} else {
|
||||||
|
const created = await github.rest.issues.createComment({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: prNumber,
|
||||||
|
body,
|
||||||
|
});
|
||||||
|
core.info(`Created artifacts comment: ${created.data.html_url}`);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user