Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"baseBranch": "origin/main",
"updateInternalDependencies": "patch",
"ignore": []
}
127 changes: 127 additions & 0 deletions .github/scripts/publish-to-pkg-pr-new.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/* eslint-disable camelcase */

import fs from "node:fs";

/**
* @param {{ github: EXPECTED_ANY, context: EXPECTED_ANY }} params params
*/
export async function run({ github, context }) {
const output = JSON.parse(fs.readFileSync("output.json", "utf8"));

const sha =
context.eventName === "pull_request" ? context.payload.pull_request.head.sha : context.sha;

const commitUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${sha}`;

const packages = output.packages.map((pkg) => `${pkg.name}@${pkg.url}`).join(" ");

const botCommentIdentifier = "<!-- posted by pkg.pr.new -->";
const body = `${botCommentIdentifier}
This PR is packaged and the instant preview is available (${commitUrl}).

Install it locally:

- npm

\`\`\`shell
npm i -D ${packages}
\`\`\`

- yarn

\`\`\`shell
yarn add -D ${packages}
\`\`\`

- pnpm

\`\`\`shell
pnpm add -D ${packages}
\`\`\`
`;

/**
* @param {number=} issueNumber PR number
* @returns {Promise<EXPECTED_ANY>} the existing bot comment, if any
*/
async function findBotComment(issueNumber) {
if (!issueNumber) return null;
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
});
return comments.data.find(
(comment) =>
// Prevent unintentional overwriting
comment.user &&
comment.user.login === "github-actions[bot]" &&
comment.body.includes(botCommentIdentifier),
);
}

/**
* @param {number=} issueNumber issue number
* @returns {Promise<void>}
*/
async function createOrUpdateComment(issueNumber) {
if (!issueNumber) {
console.log("No issue number provided. Cannot post or update comment.");
return;
}

const existingComment = await findBotComment(issueNumber);

if (existingComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body,
});
} else {
await github.rest.issues.createComment({
issue_number: issueNumber,
owner: context.repo.owner,
repo: context.repo.repo,
body,
});
}
}

/**
* @returns {void}
*/
function logPublishInfo() {
console.log(`\n${"=".repeat(50)}`);
console.log("Publish Information");
console.log("=".repeat(50));
console.log("\nPublished Packages:");
console.log(output.packages);
console.log("\nTemplates:");
console.log(output.templates);
console.log(`\nCommit URL: ${commitUrl}`);
console.log(`\n${"=".repeat(50)}`);
}

if (context.eventName === "pull_request") {
if (context.issue.number) {
await createOrUpdateComment(context.issue.number);
}
} else if (context.eventName === "push") {
const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: sha,
});

if (prs.length > 0) {
await createOrUpdateComment(prs[0].number);
} else {
console.log(
"No open pull request found for this push. Logging publish information to console:",
);
logPublishInfo();
}
}
}
64 changes: 64 additions & 0 deletions .github/workflows/publish-to-pkg-pr-new.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Publish to pkg.pr.new

on:
pull_request:
branches: [main]
push:
branches: [main]
tags: ["!**"]

permissions:
issues: write
pull-requests: write

jobs:
publish:
if: |
github.repository == 'webpack/webpack-cli' &&
(github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository)
name: Publish to pkg.pr.new
runs-on: ubuntu-latest
outputs:
sha: ${{ steps.publish.outputs.sha }}
urls: ${{ steps.publish.outputs.urls }}
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Changeset needs access to the main branch to find pending changesets
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: lts/*
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Compute affected packages
id: affected
run: |
npx changeset status --output changes.json || true
npm query .workspace > workspaces.json
packages=$(jq -r --slurpfile ws workspaces.json '[.releases[] | select(.type != "none") | .name] as $names | $ws[0][] | select(.name | IN($names[])) | "./" + .location' changes.json 2>/dev/null | tr '\n' ' ' || true)
echo "packages=$packages" >> "$GITHUB_OUTPUT"
echo "Affected packages: ${packages:-none}"

- name: Publish
if: steps.affected.outputs.packages != ''
run: npx pkg-pr-new publish --compact --json output.json --comment=off ${{ steps.affected.outputs.packages }}

- name: Add metadata to output
if: steps.affected.outputs.packages != ''
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { run } = await import('${{ github.workspace }}/.github/scripts/publish-to-pkg-pr-new.mjs');
await run({ github, context });
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"json5": "^2.2.3",
"lint-staged": "^17.0.8",
"mini-css-extract-plugin": "^2.10.2",
"pkg-pr-new": "^0.0.79",
"prettier": "^3.8.4",
"readable-stream": "^4.7.0",
"sass": "^1.101.0",
Expand Down