Skip to content

Commit d11d76b

Browse files
committed
feat: migrate to Trusted Publishing for npm packages
Major changes: - Migrate from classic npm tokens to OIDC-based Trusted Publishing - Add automatic provenance attestation generation - Update GitHub Actions workflows for enhanced security Workflow improvements: - Add id-token: write and contents: read permissions for OIDC - Add contents: write and pull-requests: write for release automation - Make auth-token optional in publish action (OIDC when not provided) - Update npm to latest version before publishing (required for OIDC) GitHub Actions fixes: - Add gpg-key-signing parameter to github-config action - Use printf instead of echo for base64 decoding (prevents shell expansion) - Upgrade actions/upload-artifact and actions/download-artifact from v3 to v4 - Update Node.js from 16 to 20 (required for npm 11.5+) Build configuration: - Add objectAssign option to buble plugin for object spread support - Fix repository URL case (macpaw → MacPaw) for provenance validation Release: - Version bump to 1.2.2 - Add CHANGELOG.md - Successfully published with Trusted Publishing and provenance Benefits: - No long-lived tokens to manage or rotate - Automatic cryptographic proof of package origin - Short-lived OIDC credentials that can't be extracted - Better security and audit trail
1 parent 041378b commit d11d76b

File tree

10 files changed

+107
-73
lines changed

10 files changed

+107
-73
lines changed

.changeset/flat-melons-matter.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.github/actions/github-config/action.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
name: 'github config'
2-
description: 'Update GIT config with signing key'
1+
name: "github config"
2+
description: "Update GIT config with signing key"
33
inputs:
44
gpg-key-base64:
5-
description: 'Base64 GPG key'
5+
description: "Base64 GPG key"
6+
required: true
7+
gpg-key-signing:
8+
description: "Git signing key"
69
required: true
710
runs:
811
using: "composite"
912
steps:
1013
- run: |
1114
mkdir -p ${GITHUB_WORKSPACE}/.gpg
12-
echo ${{ inputs.gpg-key-base64 }} | base64 -d > ${GITHUB_WORKSPACE}/.gpg/private.key
15+
printf '%s' "${{ inputs.gpg-key-base64 }}" | base64 -d > ${GITHUB_WORKSPACE}/.gpg/private.key
1316
gpg --import ${GITHUB_WORKSPACE}/.gpg/private.key
1417
15-
git config --global user.signingkey <user-signingkey>
18+
git config --global user.signingkey ${{ inputs.gpg-key-signing }}
1619
git config --global commit.gpgsign true
1720
git config user.name ci-macpaw
1821
git config user.email [email protected]

.github/actions/prepare-packages/action.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,30 @@ name: "Prepare packages"
22
description: "Builds and packs the packages for release"
33
inputs:
44
node-version:
5-
description: 'The version of Node.js to use'
5+
description: "The version of Node.js to use"
66
required: true
77
node-cache:
8-
description: 'The cache key to use for caching Node.js'
8+
description: "The cache key to use for caching Node.js"
99
required: false
1010
package-manager:
11-
description: 'The package manager to use'
11+
description: "The package manager to use"
1212
required: false
13-
default: 'npm'
13+
default: "npm"
1414
registry-url:
15-
description: 'The registry URL to use'
15+
description: "The registry URL to use"
1616
required: false
1717
artifact-name:
18-
description: 'The name of the artifact to upload'
18+
description: "The name of the artifact to upload"
1919
required: false
20-
default: 'package-artifact'
20+
default: "package-artifact"
2121
artifact-retention-days:
22-
description: 'The number of days to retain the artifact'
22+
description: "The number of days to retain the artifact"
2323
required: false
2424
default: 1
2525
build-command:
26-
description: 'The command to use to build the package'
26+
description: "The command to use to build the package"
2727
required: false
28-
default: 'build'
28+
default: "build"
2929

3030
runs:
3131
using: composite
@@ -42,7 +42,7 @@ runs:
4242
- name: Install dependencies
4343
shell: bash
4444
run: ${{ inputs.package-manager }} install
45-
45+
4646
- name: Build
4747
shell: bash
4848
run: |
@@ -51,13 +51,13 @@ runs:
5151
else
5252
${{ inputs.package-manager }} ${{ inputs.build-command }}
5353
fi
54-
54+
5555
- name: Pack artifact
5656
shell: bash
57-
run: tar -czf /tmp/artifact.tar.gz .
57+
run: tar -czf /tmp/artifact.tar.gz .
5858

5959
- name: Upload artifact
60-
uses: actions/upload-artifact@v3
60+
uses: actions/upload-artifact@v4
6161
with:
6262
name: ${{ inputs.artifact-name }}
6363
path: /tmp/artifact.tar.gz

.github/actions/publish/action.yml

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,31 @@ name: "Publish package to registry"
22
description: "Publishes the package to the registry"
33
inputs:
44
node-version:
5-
description: 'The version of Node.js to use'
5+
description: "The version of Node.js to use"
66
required: true
77
node-cache:
8-
description: 'The cache key to use for caching Node.js'
8+
description: "The cache key to use for caching Node.js"
99
required: false
1010
package-manager:
11-
description: 'The package manager to use'
11+
description: "The package manager to use"
1212
required: false
13-
default: 'npm'
13+
default: "npm"
1414
registry-url:
15-
description: 'The registry URL to use'
15+
description: "The registry URL to use"
1616
required: false
1717
artifact-name:
18-
description: 'The name of the artifact to download'
18+
description: "The name of the artifact to download"
1919
required: false
20-
default: 'package-artifact'
20+
default: "package-artifact"
2121
scope:
22-
description: 'The scope to use'
22+
description: "The scope to use"
2323
required: false
24-
default: ''
24+
default: ""
2525
auth-token:
26-
description: 'The auth token to use'
27-
required: true
26+
description: "The auth token to use"
27+
required: false
2828
use-public-flag:
29-
description: 'Whether to use the public flag'
29+
description: "Whether to use the public flag"
3030
required: false
3131
default: false
3232

@@ -43,15 +43,20 @@ runs:
4343
scope: ${{ inputs.scope }}
4444

4545
- name: Download artifact
46-
uses: actions/download-artifact@v3
46+
uses: actions/download-artifact@v4
4747
with:
4848
name: ${{ inputs.artifact-name }}
4949

5050
- name: Unpack artifact
5151
shell: bash
5252
run: tar xf artifact.tar.gz
5353

54-
- name: Publish
54+
- name: Update npm
55+
shell: bash
56+
run: npm install -g npm@latest
57+
58+
- name: Publish (with token)
59+
if: ${{ inputs.auth-token != '' }}
5560
shell: bash
5661
run: |
5762
if [ "${{ inputs.use-public-flag }}" = "true" ]; then
@@ -61,3 +66,13 @@ runs:
6166
fi
6267
env:
6368
NODE_AUTH_TOKEN: ${{ inputs.auth-token }}
69+
70+
- name: Publish (with OIDC)
71+
if: ${{ inputs.auth-token == '' }}
72+
shell: bash
73+
run: |
74+
if [ "${{ inputs.use-public-flag }}" = "true" ]; then
75+
npm publish --access public
76+
else
77+
npm publish
78+
fi

.github/actions/release/action.yml

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,51 @@ name: "Release package action"
22
description: "Matches changesets if they are in the release branch, creates a release PR with version updates, otherwise if there are versions update, it will create a release."
33
inputs:
44
node-version:
5-
description: 'The version of Node.js to use'
5+
description: "The version of Node.js to use"
66
required: true
77
node-cache:
8-
description: 'The cache key to use for caching Node.js'
8+
description: "The cache key to use for caching Node.js"
99
required: false
1010
package-manager:
11-
description: 'The package manager to use'
11+
description: "The package manager to use"
1212
required: false
13-
default: 'npm'
13+
default: "npm"
1414
registry-url:
15-
description: 'The registry URL to use'
15+
description: "The registry URL to use"
1616
required: false
1717
release-pr-title:
18-
description: 'The title of the release PR'
18+
description: "The title of the release PR"
1919
required: false
20-
default: 'ci(changesets): :package: version packages'
20+
default: "ci(changesets): :package: version packages"
2121
release-commit-message:
22-
description: 'The commit message of the release PR'
22+
description: "The commit message of the release PR"
2323
required: false
24-
default: 'ci(changesets): version packages'
24+
default: "ci(changesets): version packages"
2525
github-token:
26-
description: 'The github token to use'
26+
description: "The github token to use"
2727
required: true
28-
release-command:
29-
description: 'The command to use to release'
28+
release-command:
29+
description: "The command to use to release"
3030
required: false
31-
default: 'release'
31+
default: "release"
3232
gpg-key-base64:
33-
description: 'The base64 encoded GPG key to use'
33+
description: "The base64 encoded GPG key to use"
34+
required: true
35+
gpg-key-signing:
36+
description: "The GPG signing key ID"
3437
required: true
3538
outputs:
3639
release-ready:
3740
description: "Random number"
3841
value: ${{ steps.output-generator.outputs.release-ready }}
3942
runs:
4043
using: composite
41-
steps:
44+
steps:
4245
- name: Configure git user
4346
uses: ./.github/actions/github-config
4447
with:
4548
gpg-key-base64: ${{ inputs.gpg-key-base64 }}
49+
gpg-key-signing: ${{ inputs.gpg-key-signing }}
4650

4751
- name: Prepare node
4852
uses: ./.github/actions/prepare-node

.github/workflows/release.yml

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ jobs:
1010
name: Create release
1111
runs-on: ubuntu-latest
1212
continue-on-error: false
13+
permissions:
14+
contents: write # Required to create release branches and tags
15+
pull-requests: write # Required to create release PRs
1316
outputs:
1417
releaseReady: ${{ steps.releaseOutputs.outputs.releaseReady }}
1518
steps:
@@ -23,12 +26,13 @@ jobs:
2326
uses: ./.github/actions/release
2427
id: release
2528
with:
26-
node-version: 16
27-
release-pr-title: 'chore(release): :package: version update for packages'
28-
release-commit-message: 'chore(release): version update for packages'
29+
node-version: 20
30+
release-pr-title: "chore(release): :package: version update for packages"
31+
release-commit-message: "chore(release): version update for packages"
2932
github-token: ${{ secrets.GITHUB_TOKEN }}
30-
release-command: 'changes:release'
33+
release-command: "changes:release"
3134
gpg-key-base64: ${{ secrets.CI_GITHUB_GPG_KEY_BASE64 }}
35+
gpg-key-signing: ${{ secrets.CI_GITHUB_GPG_KEY_SIGNING }}
3236

3337
- name: Generate outputs
3438
id: releaseOutputs
@@ -51,14 +55,17 @@ jobs:
5155
- name: Prepare
5256
uses: ./.github/actions/prepare-packages
5357
with:
54-
node-version: 16
55-
build-command: 'build'
58+
node-version: 20
59+
build-command: "build"
5660

5761
publish-npm:
5862
name: Publish to NPM Registry
5963
needs: prepare
6064
runs-on: ubuntu-latest
6165
continue-on-error: false
66+
permissions:
67+
id-token: write # Required for OIDC/Trusted Publishing
68+
contents: read # Required to checkout code
6269
steps:
6370
- name: Cancel previous jobs
6471
uses: styfle/[email protected]
@@ -69,11 +76,10 @@ jobs:
6976
- name: Publish to NPM
7077
uses: ./.github/actions/publish
7178
with:
72-
node-version: 16
73-
registry-url: 'https://registry.npmjs.org/'
74-
artifact-name: 'package-artifact'
75-
scope: '@macpaw'
76-
auth-token: ${{ secrets.NPM_TOKEN }}
79+
node-version: 20
80+
registry-url: "https://registry.npmjs.org/"
81+
artifact-name: "package-artifact"
82+
scope: "@macpaw"
7783

7884
publish-github:
7985
name: Publish to Github Registry
@@ -83,15 +89,15 @@ jobs:
8389
steps:
8490
- name: Cancel previous jobs
8591
uses: styfle/[email protected]
86-
92+
8793
- name: Checkout
8894
uses: actions/checkout@v3
8995

9096
- name: Publish to NPM
9197
uses: ./.github/actions/publish
9298
with:
93-
node-version: 16
99+
node-version: 20
94100
registry-url: https://npm.pkg.github.com/
95-
artifact-name: 'package-artifact'
96-
scope: '@macpaw'
101+
artifact-name: "package-artifact"
102+
scope: "@macpaw"
97103
auth-token: ${{ secrets.GITHUB_TOKEN }}

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# @macpaw/browser-deeplink
2+
3+
## 1.2.1
4+
5+
### Patch Changes
6+
7+
- d597495: Patch changes to trigger release

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@macpaw/browser-deeplink",
3-
"version": "1.2.0",
3+
"version": "1.2.2",
44
"main": "dist/index.js",
55
"module": "src/index",
66
"license": "MIT",
@@ -23,5 +23,5 @@
2323
],
2424
"types": "src/index.d.ts",
2525
"homepage": "https://macpaw.github.io/browser-deeplink/example",
26-
"repository": "macpaw/browser-deeplink"
26+
"repository": "MacPaw/browser-deeplink"
2727
}

rollup.config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ const config = {
77
format: 'cjs',
88
indent: false
99
},
10-
plugins: [buble()],
10+
plugins: [
11+
buble({
12+
objectAssign: 'Object.assign',
13+
}),
14+
],
1115
};
1216

1317
export default config;

0 commit comments

Comments
 (0)