Skip to content

Comment

Comment #2808

name: Comment
on:
workflow_run:
workflows: [ Build ]
types:
- completed
jobs:
comment:
runs-on: ubuntu-latest
if: >
github.event.workflow_run.event == 'pull_request'
steps:
- name: Download artifacts
id: download-artifacts
uses: actions/github-script@v9
with:
script: |
const fs = require('fs');
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
});
async function downloadIfAvailable(name, fileName) {
const artifact = artifacts.data.artifacts.find((a) => a.name === name);
if (artifact) {
const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: artifact.id,
archive_format: 'zip',
});
fs.writeFileSync(`${{github.workspace}}/${fileName}`, Buffer.from(download.data));
return true;
}
return false;
}
await downloadIfAvailable("pr", "pr.zip");
await downloadIfAvailable("Android Screenshots", "androidScreenshots.zip");
await downloadIfAvailable("iPad Screenshots", "iPadScreenshots.zip");
await downloadIfAvailable("iPhone Screenshots", "iPhoneScreenshots.zip");
- name: Unzip Artifacts
shell: bash
run: |
if [ -f "pr.zip" ]; then unzip pr.zip; fi
mkdir -p screenshots
if [ -f "androidScreenshots.zip" ]; then unzip androidScreenshots.zip -d screenshots/; fi
if [ -f "iPadScreenshots.zip" ]; then unzip iPadScreenshots.zip -d screenshots/; fi
if [ -f "iPhoneScreenshots.zip" ]; then unzip iPhoneScreenshots.zip -d screenshots/; fi
- name: Fetch PR Number
id: fetch-pr-number
uses: actions/github-script@v9
with:
script: |
const fs = require('fs');
let issue_number;
if (fs.existsSync('./NR')) {
issue_number = Number(fs.readFileSync('./NR', 'utf8').trim());
} else {
const { data } = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: '${{ github.event.workflow_run.head_sha }}'
});
if (data.length > 0) {
issue_number = data[0].number;
} else {
core.setFailed("Could not determine PR number.");
return;
}
}
core.setOutput("pr_number", issue_number);
- name: Update PR Screenshots
shell: bash
run: |
if [ -d "screenshots" ] && [ "$(ls -A screenshots 2>/dev/null)" ]; then
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
if ! git clone --branch=pr-screenshots --depth=1 https://${{ github.repository_owner }}:${{ github.token }}@github.com/${{ github.repository }} pr-screenshots; then
mkdir pr-screenshots
cd pr-screenshots
git init
git remote add origin https://${{ github.repository_owner }}:${{ github.token }}@github.com/${{ github.repository }}
else
cd pr-screenshots
fi
for file in ../screenshots/*; do
if [[ -f "$file" ]]; then
filename=$(basename "$file")
if [[ "$filename" =~ -([0-9]+_.*\.png)$ ]]; then
screenshot_part="${BASH_REMATCH[1]}"
if [[ "$filename" == *"iPhone"* ]]; then
generic_name="iPhone-${screenshot_part}"
elif [[ "$filename" == *"iPad"* ]]; then
generic_name="iPad-${screenshot_part}"
else
generic_name="Android-${screenshot_part}"
fi
else
generic_name="$filename"
fi
cp -f "$file" "./${{ steps.fetch-pr-number.outputs.pr_number }}_${generic_name}"
fi
done
git checkout --orphan temporary
git add --all .
git commit -am "[Auto] Update screenshots for #${{ steps.fetch-pr-number.outputs.pr_number }} ($(date +%Y-%m-%d.%H:%M:%S))"
git branch -D pr-screenshots || true
git branch -m pr-screenshots
git push --force origin pr-screenshots
fi
- name: Update PR Comment
uses: actions/github-script@v9
with:
script: |
const issue_number = ${{ steps.fetch-pr-number.outputs.pr_number }};
const owner = context.repo.owner;
const repo = context.repo.repo;
const conclusion = '${{ github.event.workflow_run.conclusion }}';
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner,
repo,
run_id: ${{ github.event.workflow_run.id }},
});
let artifactLinks = "";
const ignoredArtifacts = ["pr", "Android Screenshots", "iPad Screenshots", "iPhone Screenshots"];
artifacts.data.artifacts.forEach(artifact => {
if (!ignoredArtifacts.includes(artifact.name)) {
const url = `https://github.com/${owner}/${repo}/actions/runs/${{ github.event.workflow_run.id }}/artifacts/${artifact.id}`;
let platformName = artifact.name;
if (artifact.name.includes('apk-files')) platformName = 'Android';
else if (artifact.name.includes('iOS IPA')) platformName = 'iOS';
else if (artifact.name.includes('windows-installer')) platformName = 'Windows';
else if (artifact.name.includes('macos-app')) platformName = 'macOS';
else if (artifact.name === 'linux-packages') platformName = 'Linux';
else if (artifact.name === 'linux-packages-arm64') platformName = 'Linux (ARM64)';
else if (artifact.name.includes('web-app') || artifact.name.includes('web')) platformName = 'Web';
artifactLinks += `- **${platformName}**: [Download](${url})\n`;
}
});
const screenshotsSection = `
<details>
<summary>Android Screenshots</summary>
<table>
<tr>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_Android-1_instruments_screen.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_Android-2_nav_drawer.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_Android-3_accelerometer.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_Android-4_power_source.png?raw=true" width="1080"/></td>
</tr>
<tr>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_Android-5_multimeter.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_Android-6_wave_generator.png?raw=true" width="1080"/></td>
<td colspan="2"><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_Android-7_oscilloscope.png?raw=true" width="2146"/></td>
</tr>
</table>
</details>
<details>
<summary>iPhone Screenshots</summary>
<table>
<tr>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPhone-1_instruments_screen.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPhone-2_nav_drawer.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPhone-3_accelerometer.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPhone-4_power_source.png?raw=true" width="1080"/></td>
</tr>
<tr>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPhone-5_multimeter.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPhone-6_wave_generator.png?raw=true" width="1080"/></td>
<td colspan="2"><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPhone-7_oscilloscope.png?raw=true" width="2146"/></td>
</tr>
</table>
</details>
<details>
<summary>iPad Screenshots</summary>
<table>
<tr>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPad-1_instruments_screen.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPad-2_nav_drawer.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPad-3_accelerometer.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPad-4_power_source.png?raw=true" width="1080"/></td>
</tr>
<tr>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPad-5_multimeter.png?raw=true" width="1080"/></td>
<td><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPad-6_wave_generator.png?raw=true" width="1080"/></td>
<td colspan="2"><img src="https://github.com/${owner}/${repo}/blob/pr-screenshots/${issue_number}_iPad-7_oscilloscope.png?raw=true" width="2146"/></td>
</tr>
</table>
</details>
`;
let body = `**Build Status:** `;
if (conclusion === 'success') {
body += `Build successful.\n\n## Build artifacts to test\n\n${artifactLinks || '_No artifacts uploaded._'}\n\n## Screenshots\n\n${screenshotsSection}`;
} else {
body += `Build workflow failed. _Please check the Actions logs for details._\n`;
if (artifactLinks) {
body += `\n## Build artifacts to test\n\n(Available before failure)\n\n${artifactLinks}\n`;
}
body += `\n> *Note: Screenshots are not generated on failed builds. Below are the latest screenshots from the \`pr-screenshots\` branch, if they exist.*\n\n## Screenshots\n\n${screenshotsSection}`;
}
const comments = await github.rest.issues.listComments({
owner,
repo,
issue_number
});
const botComment = comments.data.find(comment => comment.user.login === 'github-actions[bot]');
if (botComment) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: botComment.id,
body
});
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number,
body
});
}