CI Comment #1545
This file contains 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 Comment | |
on: | |
workflow_run: | |
workflows: ["CI"] | |
types: | |
- completed | |
jobs: | |
ci-comment: | |
name: Update PR body | |
if: > | |
${{ github.event.workflow_run.event == 'pull_request' && | |
github.event.workflow_run.conclusion == 'success' }} | |
runs-on: ubuntu-latest | |
env: | |
OPAMSOLVERTIMEOUT: 3600 | |
SNAPSHOT: "snapshot-${{ matrix.snapshot }}" | |
steps: | |
- name: Checkout code (10 commits) | |
uses: actions/checkout@v2 | |
with: | |
fetch-depth: 10 | |
submodules: true | |
- name: 'Download artifact' | |
uses: actions/github-script@v3.1.0 | |
with: | |
script: | | |
const artifacts = await github.actions.listWorkflowRunArtifacts({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
run_id: ${{github.event.workflow_run.id }}, | |
}); | |
const fs = require('fs'); | |
const matchedArtifacts = artifacts.data.artifacts.filter((artifact) => { | |
return artifact.name.startsWith('pr'); | |
}); | |
for await (const artifact of matchedArtifacts) { | |
console.log('download artifact', artifact); | |
const download = await github.actions.downloadArtifact({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
artifact_id: artifact.id, | |
archive_format: 'zip', | |
}); | |
fs.writeFileSync(`${{github.workspace}}/pr-${artifact.id}.zip`, Buffer.from(download.data)); | |
} | |
- name: Extract | |
run: | | |
shopt -s nullglob | |
for file in *.zip ; do | |
unzip "$file" -d "${file%.zip}" | |
done | |
for f in pr-*/comment.txt ; do | |
echo "# $f" | |
cat "$f" | |
done | |
- name: Update the PR body | |
uses: actions/github-script@v2 | |
env: | |
SNAPSHOT_UPDATABLE: ${{ steps.test-update-snapshot.outputs.result }} | |
PACKAGES_TO_UPDATE: ${{ steps.test-update-snapshot.outputs.packages }} | |
with: | |
github-token: ${{ github.token }} | |
script: | | |
const fs = require('fs'); | |
const dir = await fs.promises.opendir('.'); | |
const snapshots = []; | |
const readFile = (fileName, d) => { | |
try { | |
return fs.readFileSync(fileName, 'utf8').trim(); | |
} catch (e) { | |
console.log(e); | |
return d; | |
} | |
}; | |
for await (const dirent of dir) { | |
if (dirent.isDirectory() && dirent.name.startsWith('pr-')) { | |
const dirname = dirent.name; | |
if (!fs.existsSync(`${dirname}/pull-number.txt`)) { | |
continue; | |
} | |
const pull_number = Number(fs.readFileSync(`${dirname}/pull-number.txt`, 'utf8')); | |
const run_id = Number(fs.readFileSync(`${dirname}/run-id.txt`, 'utf8')); | |
const snapshot = fs.readFileSync(`${dirname}/id.txt`, 'utf8').trim(); | |
const matrix = fs.readFileSync(`${dirname}/matrix.txt`, 'utf8').trim(); | |
const result = readFile(`${dirname}/result.txt`, undefined); | |
const packages = readFile(`${dirname}/packages.txt`, 'unknown'); | |
const comment = readFile(`${dirname}/comment.txt`, undefined); | |
snapshots.push({pull_number, run_id, snapshot, matrix, result, packages, comment}); | |
} | |
} | |
console.log('snapshots', snapshots); | |
if (snapshots.length === 0) { | |
console.log('No artifacts read'); | |
return; | |
} | |
const pull_number = snapshots[0].pull_number; | |
const pullRequestId = { | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
pull_number | |
}; | |
const pull_request = await github.pulls.get(pullRequestId); | |
const actionHeader = '\n# Automatic follow-ups\n'; | |
const actionText = (snapshot) => `Add to snapshot \`${snapshot}\``; | |
const body = pull_request.data.body.replace(/\r?\n/g, '\n'); | |
const extractAction = (str) => | |
str.replace(/^\[.\] /, "") | |
.replace(/ :: .*/, "") | |
.replace(/^~~(.*)~~.*/, "$1"); | |
if (body) { | |
const splitted = body.split(actionHeader); | |
const actions = splitted[1] | |
? splitted[1] | |
.split('\n- ') | |
.map((action) => { | |
for (snapshot of snapshots) { | |
console.log('action', action, actionText(snapshot.snapshot), snapshot); | |
const extractedAction = extractAction(action); | |
if (extractedAction === actionText(snapshot.snapshot)) { | |
switch (snapshot.result) { | |
case 'updated': | |
return `[ ] ${extractedAction} :: ${snapshot.packages}`; | |
case 'no-updates': | |
return `~~${extractedAction}~~ (No updates)`; | |
case 'failed': | |
// return `~~${extractedAction}~~ ([Inconsistent](https://github.com/${context.repo.owner}/${context.repo.repo}/runs/${snapshot.run_id}?check_suite_focus=true))`; | |
return `~~${extractedAction}~~ (Inconsistent)`; | |
case 'unknown': | |
return `~~${extractedAction}~~ (Result unknown)`; | |
default: | |
if (snapshot.result.startsWith('inconsistent-snapshot ')) { | |
return `~~${extractedAction}~~ (${snapshot.result})`; | |
} | |
return `~~${extractedAction}~~ (Result unknown)`; | |
} | |
} | |
} | |
return action; | |
}) | |
: []; | |
const replacedBody = `${splitted[0]}${actionHeader}${actions.join('\n- ')}`; | |
await github.pulls.update({ | |
...pullRequestId, | |
body: replacedBody | |
}); | |
} | |
const comments = [ | |
'# CI Summary' | |
]; | |
for (snapshot of snapshots) { | |
if (snapshot.comment) { | |
comments.push(`## Matrix: ${snapshot.matrix}`); | |
comments.push(snapshot.comment); | |
} | |
} | |
if (comments.length) { | |
await github.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: pull_number, | |
body: comments.join('\n') | |
}); | |
} |