Comment #2808
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: 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 | |
| }); | |
| } |