diff --git a/.github/workflows/pkg.pr.new.yml b/.github/workflows/pkg.pr.new.yml index 9a56335e..60cf0ca5 100644 --- a/.github/workflows/pkg.pr.new.yml +++ b/.github/workflows/pkg.pr.new.yml @@ -1,5 +1,10 @@ name: Publish to pkg.pr.new -on: [push, pull_request] +on: + pull_request: + branches: [main] + push: + branches: [main] + tags: ["!**"] jobs: build: @@ -13,4 +18,13 @@ jobs: run: pnpm install - name: Build run: pnpm run build - - run: pnpx pkg-pr-new publish --compact + - run: pnpx pkg-pr-new publish --compact --json output.json --comment=off + - uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const output = JSON.parse(fs.readFileSync('output.json', 'utf8')); + const { default: process } = await import('${{ github.workspace }}/tools/pkg.pr.new-comment.mjs') + + await process({github, context, core, output}) diff --git a/tools/pkg.pr.new-comment.mjs b/tools/pkg.pr.new-comment.mjs new file mode 100644 index 00000000..689971e2 --- /dev/null +++ b/tools/pkg.pr.new-comment.mjs @@ -0,0 +1,124 @@ +/** + * Used in `/.github/workflows/pkg.pr.new.yml` + */ +export default async function ({ github, context, output }) { + // eslint-disable-next-line no-console -- For debugging on github actions. + console.log("pkg-pr-new publish output:", JSON.stringify(output)); + + const sha = + context.eventName === "pull_request" + ? context.payload.pull_request.head.sha + : context.payload.after; + const commitUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${sha}`; + + const pullRequestNumber = await getPullRequestNumber(); + + const packages = output.packages.map((p) => { + let normalizedUrl = p.url; + if (pullRequestNumber && p.url.endsWith(sha)) { + normalizedUrl = `${p.url.slice(0, -sha.length)}${pullRequestNumber}`; + } + const repoPath = `/${context.repo.owner}/${context.repo.repo}/`; + normalizedUrl = normalizedUrl.replace(repoPath, "/"); + + return { + name: p.name, + url: normalizedUrl, + }; + }); + + const botCommentIdentifier = ""; + + const onlineUrl = new URL( + "https://eslint-online-playground.netlify.app/#eslint-plugin-svelte%20with%20typescript", + ); + const overrideDeps = {}; + for (const p of packages) { + overrideDeps[p.name] = p.url; + } + onlineUrl.searchParams.set("overrideDeps", JSON.stringify(overrideDeps)); + const body = `${botCommentIdentifier} + +## Try the Instant Preview in Online Playground + +[ESLint Online Playground](${onlineUrl}) + +## Install the Instant Preview to Your Local + +\`\`\` +npm i ${packages.map((p) => p.url).join(" ")} +\`\`\` + +## Published Instant Preview Packages: + +${packages.map((p) => `- ${p.name}: ${p.url}`).join("\n")} + +[View Commit](${commitUrl})`; + + if (pullRequestNumber) { + await createOrUpdateComment(pullRequestNumber); + } else { + /* eslint-disable no-console -- For debugging on github actions. */ + console.log( + "No open pull request found for this push. Logging publish information to console:", + ); + console.log(`\n${"=".repeat(50)}`); + console.log(body); + console.log(`\n${"=".repeat(50)}`); + /* eslint-enable no-console -- For debugging on github actions. */ + } + + async function getPullRequestNumber() { + if (context.eventName === "pull_request") { + if (context.issue.number) { + return context.issue.number; + } + } else if (context.eventName === "push") { + const pullRequests = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + state: "open", + head: `${context.repo.owner}:${context.ref.replace("refs/heads/", "")}`, + }); + + if (pullRequests.data.length > 0) { + return pullRequests.data[0].number; + } + } + return null; + } + + async function findBotComment(issueNumber) { + if (!issueNumber) return null; + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + // eslint-disable-next-line camelcase -- The ID defined in the GitHub API. + issue_number: issueNumber, + }); + return comments.data.find((comment) => + comment.body.includes(botCommentIdentifier), + ); + } + + async function createOrUpdateComment(issueNumber) { + const existingComment = await findBotComment(issueNumber); + if (existingComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + // eslint-disable-next-line camelcase -- The ID defined in the GitHub API. + comment_id: existingComment.id, + body, + }); + } else { + await github.rest.issues.createComment({ + // eslint-disable-next-line camelcase -- The ID defined in the GitHub API. + issue_number: issueNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body, + }); + } + } +}