From 2aad91b66050da4cea9ee689414f04248192e608 Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Sun, 16 Aug 2026 09:59:24 +0200 Subject: [PATCH 1/2] chore: add pkg-pr-new to preview pkg version before its published --- .github/workflows/pkg-pr-new.yml | 80 ++++++++++++++++++++++++++++++++ package.json | 1 + pnpm-lock.yaml | 9 ++++ 3 files changed, 90 insertions(+) create mode 100644 .github/workflows/pkg-pr-new.yml diff --git a/.github/workflows/pkg-pr-new.yml b/.github/workflows/pkg-pr-new.yml new file mode 100644 index 0000000..256fdf7 --- /dev/null +++ b/.github/workflows/pkg-pr-new.yml @@ -0,0 +1,80 @@ +name: Publish Any Commit + +on: + push: + branches: ['**'] + tags: ['!**'] + pull_request_review: + types: [submitted] + +permissions: {} + +jobs: + check: + name: Check permissions + if: github.event_name == 'push' || github.event.review.state == 'approved' + runs-on: ubuntu-latest + permissions: + pull-requests: read + outputs: + approved: ${{ steps.check.outputs.approved }} + steps: + - name: Push events are already gated by branch write access + if: github.event_name == 'push' + id: push-approved + run: echo "approved=true" >> "$GITHUB_OUTPUT" + - uses: actions-cool/check-user-permission@c21884f3dda18dafc2f8b402fe807ccc9ec1aa5e # v2.4.0 + if: github.event_name == 'pull_request_review' + id: checkPermissions + with: + require: write + - name: Combine results + id: check + run: echo "approved=${{ steps.push-approved.outputs.approved || steps.checkPermissions.outputs.require-result }}" >> "$GITHUB_OUTPUT" + + build: + name: Build + needs: check + if: needs.check.outputs.approved == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + persist-credentials: false + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm run build + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: dist + path: dist/ + + publish: + name: Publish + needs: build + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + persist-credentials: false + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile --ignore-scripts + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: dist + path: dist/ + - run: pnpm exec pkg-pr-new publish --commentWithSha diff --git a/package.json b/package.json index 19f85aa..605b97c 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "knip": "^6.18.0", "oxfmt": "^0.60.0", "oxlint": "^1.71.0", + "pkg-pr-new": "^0.0.88", "postcss": "^8.5.15", "publint": "^0.3.21", "tailwindcss": "^2.2.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 029b3c9..9399cfd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: oxlint: specifier: ^1.71.0 version: 1.75.0 + pkg-pr-new: + specifier: ^0.0.88 + version: 0.0.88 postcss: specifier: ^8.5.15 version: 8.5.23 @@ -1723,6 +1726,10 @@ packages: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} + pkg-pr-new@0.0.88: + resolution: {integrity: sha512-Xc6PMJ2gher0WZP+rtjefFk26hIb7V1PTLL30bmy1Z2vsRmSvqiss7Ag1XUdyplTGYzIlFNJp4L3vMNmK44N6g==} + hasBin: true + postcss-js@3.0.3: resolution: {integrity: sha512-gWnoWQXKFw65Hk/mi2+WTQTHdPD5UJdDXZmX073EY/B3BWnYjO4F4t0VneTCnCGQ5E5GsCdMkzPaTXwl3r5dJw==} engines: {node: '>=10.0'} @@ -3368,6 +3375,8 @@ snapshots: picomatch@4.0.5: {} + pkg-pr-new@0.0.88: {} + postcss-js@3.0.3: dependencies: camelcase-css: 2.0.1 From 6e35fe6cb42be058ebd784c7e3890ab9e936ff5a Mon Sep 17 00:00:00 2001 From: Bart Veneman Date: Sun, 16 Aug 2026 10:25:29 +0200 Subject: [PATCH 2/2] update to post comment on approved authors --- .github/workflows/pkg-pr-new.yml | 33 +++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pkg-pr-new.yml b/.github/workflows/pkg-pr-new.yml index 256fdf7..9ec9c64 100644 --- a/.github/workflows/pkg-pr-new.yml +++ b/.github/workflows/pkg-pr-new.yml @@ -1,9 +1,18 @@ name: Publish Any Commit +# Publishes preview packages via pkg.pr.new. Gated so untrusted/fork PRs can't +# trigger a build+publish just by opening a PR - only: +# - push: pushing to a branch already requires repo write access +# - pull_request: only when opened/updated by an author with write access +# (e.g. a maintainer's own branch) +# - pull_request_review: for everyone else, once a maintainer approves the PR +# tags/releases are excluded so version-tag pushes don't trigger a duplicate publish. on: push: branches: ['**'] tags: ['!**'] + pull_request: + types: [opened, synchronize, reopened] pull_request_review: types: [submitted] @@ -12,7 +21,7 @@ permissions: {} jobs: check: name: Check permissions - if: github.event_name == 'push' || github.event.review.state == 'approved' + if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event.review.state == 'approved' runs-on: ubuntu-latest permissions: pull-requests: read @@ -23,14 +32,24 @@ jobs: if: github.event_name == 'push' id: push-approved run: echo "approved=true" >> "$GITHUB_OUTPUT" - - uses: actions-cool/check-user-permission@c21884f3dda18dafc2f8b402fe807ccc9ec1aa5e # v2.4.0 + - name: Check PR author permission + uses: actions-cool/check-user-permission@c21884f3dda18dafc2f8b402fe807ccc9ec1aa5e # v2.4.0 + if: github.event_name == 'pull_request' + id: checkAuthor + with: + username: ${{ github.event.pull_request.user.login }} + require: write + - name: Check reviewer permission + uses: actions-cool/check-user-permission@c21884f3dda18dafc2f8b402fe807ccc9ec1aa5e # v2.4.0 if: github.event_name == 'pull_request_review' id: checkPermissions with: require: write - name: Combine results id: check - run: echo "approved=${{ steps.push-approved.outputs.approved || steps.checkPermissions.outputs.require-result }}" >> "$GITHUB_OUTPUT" + # Exactly one of the three steps above runs per trigger, the others are + # skipped and their outputs are empty strings, so this picks whichever ran. + run: echo "approved=${{ steps.push-approved.outputs.approved || steps.checkAuthor.outputs.require-result || steps.checkPermissions.outputs.require-result }}" >> "$GITHUB_OUTPUT" build: name: Build @@ -40,6 +59,8 @@ jobs: permissions: contents: read steps: + # For PR-related events this checks out the PR head commit (not a merge + # commit with main), matching the sha pkg-pr-new publishes/comments with. - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} @@ -60,9 +81,13 @@ jobs: name: Publish needs: build runs-on: ubuntu-latest + # Separate job from `build` so only this one - the one that actually needs + # to comment on the PR - carries pull-requests: write. permissions: pull-requests: write steps: + # For PR-related events this checks out the PR head commit (not a merge + # commit with main), matching the sha pkg-pr-new publishes/comments with. - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} @@ -77,4 +102,6 @@ jobs: with: name: dist path: dist/ + # --commentWithSha uses the commit sha in install URLs/comments instead + # of a PR number, and pnpm exec (not npx/dlx) runs the pinned devDependency. - run: pnpm exec pkg-pr-new publish --commentWithSha