From 39e15a89295ab2bf642181488c1f9868d0ede1b2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Mar 2026 03:23:00 +0000 Subject: [PATCH 1/6] feat: comment benchmark APK link on open PRs Add PR commenting to the build-benchmark-apk workflow. When a build completes, it now finds any open PR for the branch and posts a comment with a direct download link to the benchmark APK artifact. https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf --- .github/workflows/build-benchmark-apk.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-benchmark-apk.yml b/.github/workflows/build-benchmark-apk.yml index a9e338b31..e3efc3674 100644 --- a/.github/workflows/build-benchmark-apk.yml +++ b/.github/workflows/build-benchmark-apk.yml @@ -48,9 +48,30 @@ jobs: with: script: | const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + const artifactUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/artifacts/${{ steps.upload.outputs.artifact-id }}`; + const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${artifactUrl})\n\nOr view all artifacts in the [workflow run](${runUrl}#artifacts).`; + await github.rest.repos.createCommitComment({ owner: context.repo.owner, repo: context.repo.repo, commit_sha: context.sha, - body: `📦 **Benchmark APK ready!**\n\nDownload it from the [workflow run artifacts](${runUrl}#artifacts).` + body }); + + // Find open PRs for this branch and comment on them + const branch = context.ref.replace('refs/heads/', ''); + const { data: prs } = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + head: `${context.repo.owner}:${branch}`, + state: 'open' + }); + + for (const pr of prs) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body + }); + } From af12d13d67229650bcd97825b10f9225dbaa5201 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Mar 2026 03:34:53 +0000 Subject: [PATCH 2/6] fix: use artifact-url output for direct APK download link The manually constructed URL was invalid. Use the artifact-url output from upload-artifact which provides the correct download URL. https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf --- .github/workflows/build-benchmark-apk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-benchmark-apk.yml b/.github/workflows/build-benchmark-apk.yml index e3efc3674..54db24f5e 100644 --- a/.github/workflows/build-benchmark-apk.yml +++ b/.github/workflows/build-benchmark-apk.yml @@ -48,7 +48,7 @@ jobs: with: script: | const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; - const artifactUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/artifacts/${{ steps.upload.outputs.artifact-id }}`; + const artifactUrl = `${{ steps.upload.outputs.artifact-url }}`; const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${artifactUrl})\n\nOr view all artifacts in the [workflow run](${runUrl}#artifacts).`; await github.rest.repos.createCommitComment({ From 6bc927147c5e592e7140e77bd127647341f477e4 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Mar 2026 03:47:47 +0000 Subject: [PATCH 3/6] fix: use nightly.link for direct APK download without auth GitHub artifact URLs require authentication and don't provide direct file downloads. nightly.link proxies artifact downloads, giving a direct download link that works for anyone without GitHub login. https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf --- .github/workflows/build-benchmark-apk.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-benchmark-apk.yml b/.github/workflows/build-benchmark-apk.yml index 54db24f5e..beaddc41b 100644 --- a/.github/workflows/build-benchmark-apk.yml +++ b/.github/workflows/build-benchmark-apk.yml @@ -48,8 +48,9 @@ jobs: with: script: | const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; - const artifactUrl = `${{ steps.upload.outputs.artifact-url }}`; - const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${artifactUrl})\n\nOr view all artifacts in the [workflow run](${runUrl}#artifacts).`; + const artifactName = encodeURIComponent('Play Benchmark APK'); + const nightlyUrl = `https://nightly.link/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/${artifactName}.zip`; + const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${nightlyUrl})\n\nOr view all artifacts in the [workflow run](${runUrl}#artifacts).`; await github.rest.repos.createCommitComment({ owner: context.repo.owner, From 61dc903e9a5cc21bb011dc573108301d47cea47a Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Mar 2026 04:03:18 +0000 Subject: [PATCH 4/6] fix: use artifact ID for direct download URL instead of nightly.link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the artifact-id output from upload-artifact to construct a direct GitHub artifact download URL. No third-party service needed — the URL points to the artifact on GitHub which triggers a download when clicked. https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf --- .github/workflows/build-benchmark-apk.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-benchmark-apk.yml b/.github/workflows/build-benchmark-apk.yml index beaddc41b..1f19c0e67 100644 --- a/.github/workflows/build-benchmark-apk.yml +++ b/.github/workflows/build-benchmark-apk.yml @@ -47,10 +47,10 @@ jobs: uses: actions/github-script@v7 with: script: | + const artifactId = `${{ steps.upload.outputs.artifact-id }}`; const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; - const artifactName = encodeURIComponent('Play Benchmark APK'); - const nightlyUrl = `https://nightly.link/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/${artifactName}.zip`; - const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${nightlyUrl})\n\nOr view all artifacts in the [workflow run](${runUrl}#artifacts).`; + const downloadUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/artifacts/${artifactId}`; + const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${downloadUrl})\n\nOr view all artifacts in the [workflow run](${runUrl}#artifacts).`; await github.rest.repos.createCommitComment({ owner: context.repo.owner, From 706d282681198321ed817e117b53dcaab7dd54aa Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Mar 2026 04:05:33 +0000 Subject: [PATCH 5/6] fix: direct APK download via prerelease asset, PR comment only - Upload APK as a GitHub prerelease asset for direct .apk download (no zip wrapping like artifacts) - Remove commit comment, only comment on open PRs - Clean up existing release with same tag before creating https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf --- .github/workflows/build-benchmark-apk.yml | 69 ++++++++++++++++++----- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-benchmark-apk.yml b/.github/workflows/build-benchmark-apk.yml index 1f19c0e67..ba9c7ee3c 100644 --- a/.github/workflows/build-benchmark-apk.yml +++ b/.github/workflows/build-benchmark-apk.yml @@ -36,30 +36,69 @@ jobs: - name: Build Benchmark APK run: ./gradlew assemblePlayBenchmark - - name: Upload Play Benchmark APK + - name: Upload APK to prerelease id: upload - uses: actions/upload-artifact@v6 - with: - name: Play Benchmark APK - path: amethyst/build/outputs/apk/play/benchmark/amethyst-play-universal-benchmark.apk - - - name: Comment on commit with APK link uses: actions/github-script@v7 with: script: | - const artifactId = `${{ steps.upload.outputs.artifact-id }}`; - const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; - const downloadUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/artifacts/${artifactId}`; - const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${downloadUrl})\n\nOr view all artifacts in the [workflow run](${runUrl}#artifacts).`; + const fs = require('fs'); + const apkPath = 'amethyst/build/outputs/apk/play/benchmark/amethyst-play-universal-benchmark.apk'; + const sha = context.sha.substring(0, 7); + const tag = `benchmark-${sha}`; - await github.rest.repos.createCommitComment({ + // Delete existing release with this tag if it exists + try { + const { data: existing } = await github.rest.repos.getReleaseByTag({ + owner: context.repo.owner, + repo: context.repo.repo, + tag + }); + await github.rest.repos.deleteRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: existing.id + }); + await github.rest.git.deleteRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `tags/${tag}` + }); + } catch (e) { + // Release doesn't exist yet, that's fine + } + + const { data: release } = await github.rest.repos.createRelease({ owner: context.repo.owner, repo: context.repo.repo, - commit_sha: context.sha, - body + tag_name: tag, + target_commitish: context.sha, + name: `Benchmark APK (${sha})`, + body: `Auto-generated benchmark APK for commit ${context.sha}`, + prerelease: true }); - // Find open PRs for this branch and comment on them + const apkData = fs.readFileSync(apkPath); + const { data: asset } = await github.rest.repos.uploadReleaseAsset({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: release.id, + name: 'amethyst-play-universal-benchmark.apk', + data: apkData, + headers: { + 'content-type': 'application/vnd.android.package-archive', + 'content-length': apkData.length + } + }); + + core.setOutput('apk-url', asset.browser_download_url); + + - name: Comment on PR with APK link + uses: actions/github-script@v7 + with: + script: | + const apkUrl = `${{ steps.upload.outputs.apk-url }}`; + const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${apkUrl})`; + const branch = context.ref.replace('refs/heads/', ''); const { data: prs } = await github.rest.pulls.list({ owner: context.repo.owner, From dbf5d6954c73eafb61f847fe70a15a4c6ea41e58 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Mar 2026 04:08:30 +0000 Subject: [PATCH 6/6] fix: revert to artifact zip download, PR comment only Use upload-artifact with artifact-id for direct zip download URL. Remove prerelease approach and commit comments. https://claude.ai/code/session_0138kUcZaPQoQcAc7nA1KDbf --- .github/workflows/build-benchmark-apk.yml | 62 +++-------------------- 1 file changed, 7 insertions(+), 55 deletions(-) diff --git a/.github/workflows/build-benchmark-apk.yml b/.github/workflows/build-benchmark-apk.yml index ba9c7ee3c..1326569d9 100644 --- a/.github/workflows/build-benchmark-apk.yml +++ b/.github/workflows/build-benchmark-apk.yml @@ -36,68 +36,20 @@ jobs: - name: Build Benchmark APK run: ./gradlew assemblePlayBenchmark - - name: Upload APK to prerelease + - name: Upload Play Benchmark APK id: upload - uses: actions/github-script@v7 + uses: actions/upload-artifact@v6 with: - script: | - const fs = require('fs'); - const apkPath = 'amethyst/build/outputs/apk/play/benchmark/amethyst-play-universal-benchmark.apk'; - const sha = context.sha.substring(0, 7); - const tag = `benchmark-${sha}`; - - // Delete existing release with this tag if it exists - try { - const { data: existing } = await github.rest.repos.getReleaseByTag({ - owner: context.repo.owner, - repo: context.repo.repo, - tag - }); - await github.rest.repos.deleteRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: existing.id - }); - await github.rest.git.deleteRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: `tags/${tag}` - }); - } catch (e) { - // Release doesn't exist yet, that's fine - } - - const { data: release } = await github.rest.repos.createRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - tag_name: tag, - target_commitish: context.sha, - name: `Benchmark APK (${sha})`, - body: `Auto-generated benchmark APK for commit ${context.sha}`, - prerelease: true - }); - - const apkData = fs.readFileSync(apkPath); - const { data: asset } = await github.rest.repos.uploadReleaseAsset({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: release.id, - name: 'amethyst-play-universal-benchmark.apk', - data: apkData, - headers: { - 'content-type': 'application/vnd.android.package-archive', - 'content-length': apkData.length - } - }); - - core.setOutput('apk-url', asset.browser_download_url); + name: Play Benchmark APK + path: amethyst/build/outputs/apk/play/benchmark/amethyst-play-universal-benchmark.apk - name: Comment on PR with APK link uses: actions/github-script@v7 with: script: | - const apkUrl = `${{ steps.upload.outputs.apk-url }}`; - const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${apkUrl})`; + const artifactId = `${{ steps.upload.outputs.artifact-id }}`; + const downloadUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/artifacts/${artifactId}`; + const body = `📦 **Benchmark APK ready!**\n\nDownload: [Play Benchmark APK](${downloadUrl})`; const branch = context.ref.replace('refs/heads/', ''); const { data: prs } = await github.rest.pulls.list({