Post Playground link to PR #290
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: Post Playground link to PR | |
on: | |
pull_request_target: | |
types: [labeled] | |
workflow_run: | |
workflows: ["WebAssembly"] | |
types: [completed] | |
jobs: | |
post-summary: | |
name: Post Playground link | |
runs-on: ubuntu-latest | |
permissions: | |
pull-requests: write | |
# Post a comment only if the PR status check is passed and the PR is labeled with `Playground`. | |
# Triggered twice: when the PR is labeled and when PR build is passed. | |
if: >- | |
${{ false | |
|| (true | |
&& github.event_name == 'pull_request_target' | |
&& contains(github.event.pull_request.labels.*.name, 'Playground')) | |
|| (true | |
&& github.event_name == 'workflow_run' | |
&& github.event.workflow_run.conclusion == 'success' | |
&& github.event.workflow_run.event == 'pull_request') | |
}} | |
steps: | |
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const fs = require('fs/promises'); | |
const buildWorkflowPath = '.github/workflows/wasm.yml'; | |
const findSuccessfuBuildRun = async (pr) => { | |
const opts = github.rest.actions.listWorkflowRunsForRepo.endpoint.merge({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
status: 'success', | |
branch: pr.head.ref, | |
}); | |
const runs = await github.paginate(opts); | |
const buildRun = runs.find(run => run.path == buildWorkflowPath); | |
return buildRun; | |
} | |
const postComment = async (body, pr) => { | |
const { data: comments } = await github.rest.issues.listComments({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: pr.number, | |
}); | |
const commentOpts = { owner: context.repo.owner, repo: context.repo.repo, body: comment }; | |
const existingComment = comments.find(comment => comment.body.startsWith(magicComment)); | |
if (existingComment) { | |
core.info(`Updating existing comment: ${existingComment.html_url}`); | |
await github.rest.issues.updateComment({ | |
...commentOpts, comment_id: existingComment.id | |
}); | |
} else { | |
await github.rest.issues.createComment({ | |
...commentOpts, issue_number: pr.number | |
}); | |
} | |
} | |
const derivePRNumber = async () => { | |
if (context.payload.pull_request) { | |
return context.payload.pull_request.number; | |
} | |
// Workaround for https://github.com/orgs/community/discussions/25220 | |
const { data: { artifacts } } = await github.rest.actions.listWorkflowRunArtifacts({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
run_id: context.payload.workflow_run.id, | |
}); | |
const artifact = artifacts.find(artifact => artifact.name == 'github-pr-info'); | |
if (!artifact) { | |
throw new Error('Cannot find github-pr-info.txt artifact'); | |
} | |
const { data } = await github.rest.actions.downloadArtifact({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
artifact_id: artifact.id, | |
archive_format: 'zip', | |
}); | |
await fs.writeFile('pr-info.zip', Buffer.from(data)); | |
await exec.exec('unzip', ['pr-info.zip']); | |
return await fs.readFile('github-pr-info.txt', 'utf8'); | |
} | |
const prNumber = await derivePRNumber(); | |
const { data: pr } = await github.rest.pulls.get({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
pull_number: prNumber, | |
}); | |
core.info(`Checking if the PR ${prNumber} is labeled with Playground...`); | |
if (!pr.labels.some(label => label.name == 'Playground')) { | |
core.info(`The PR is not labeled with Playground.`); | |
return; | |
} | |
core.info(`Checking if the build is successful for ${pr.head.ref} in ${pr.head.repo.owner.login}/${pr.head.repo.name}...`); | |
const buildRun = await findSuccessfuBuildRun(pr); | |
if (!buildRun) { | |
core.info(`No successful build run found for ${buildWorkflowPath} on ${pr.head.ref} yet.`); | |
return; | |
} | |
core.info(`Found a successful build run: ${buildRun.html_url}`); | |
const runLink = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; | |
const magicComment = `<!-- AUTO-GENERATED-COMMENT-PR-PLAYGROUND -->`; | |
const comment = `${magicComment} | |
**Try on Playground**: https://ruby.github.io/play-ruby?run=${buildRun.id} | |
This is an automated comment by [\`pr-playground.yml\`](${runLink}) workflow. | |
`; | |
core.info(`Comment: ${comment}`); | |
await postComment(comment, pr); | |