1 name: NPM Release
2
3 on:
4 push:
5 tags:
6 - "v*.*.*"
7 workflow_dispatch:
8 inputs:
9 tag:
10 description: "Release tag (e.g. v0.1.1)"
11 required: true
12
13 permissions:
14 id-token: write
15 contents: read
16
17 env:
18 CARGO_TERM_COLOR: always
19
20 jobs:
21 publish-npm-binaries:
22 name: Publish NPM platform packages
23 runs-on: ${{ matrix.build.OS }}
24 strategy:
25 fail-fast: false
26 matrix:
27 build:
28 - {
29 NAME: linux-x64-glibc,
30 OS: ubuntu-latest,
31 TARGET: x86_64-unknown-linux-gnu,
32 }
33 - {
34 NAME: linux-arm64-glibc,
35 OS: ubuntu-24.04-arm,
36 TARGET: aarch64-unknown-linux-gnu,
37 }
38 - {
39 NAME: win32-x64-msvc,
40 OS: windows-2022,
41 TARGET: x86_64-pc-windows-msvc,
42 }
43 - {
44 NAME: win32-arm64-msvc,
45 OS: windows-2022,
46 TARGET: aarch64-pc-windows-msvc,
47 }
48 - { NAME: darwin-x64, OS: macos-26, TARGET: x86_64-apple-darwin }
49 - { NAME: darwin-arm64, OS: macos-26, TARGET: aarch64-apple-darwin }
50
51 steps:
52 - name: Checkout
53 uses: actions/checkout@v6
54 with:
55 ref: ${{ github.event.inputs.tag || github.ref }}
56
57 - name: Set the release version
58 shell: bash
59 run: |
60 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
61 release_version="${GITHUB_REF_NAME#v}"
62 else
63 release_version="${{ github.event.inputs.tag }}"
64 release_version="${release_version#v}"
65 fi
66 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
67
68 - name: Read Rust toolchain
69 shell: bash
70 run: |
71 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
72 if [ -z "$rust_toolchain" ]; then
73 echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
74 exit 1
75 fi
76 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
77
78 - name: Install Rust toolchain
79 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
80 with:
81 toolchain: ${{ env.RUST_TOOLCHAIN }}
82
83 - name: Install Rust target
84 shell: bash
85 run: |
86 rustup target add ${{ matrix.build.TARGET }} --toolchain ${{ env.RUST_TOOLCHAIN }}
87 rustup target list --installed
88
89 - name: Setup Rust cache
90 uses: Swatinem/rust-cache@v2
91 with:
92 key: npm-${{ matrix.build.TARGET }}
93
94 - name: Build binary
95 shell: bash
96 run: cargo build --locked --release --target ${{ matrix.build.TARGET }}
97
98 - name: Install Node
99 uses: actions/setup-node@v6
100 with:
101 node-version-file: .nvmrc
102 registry-url: "https://registry.npmjs.org"
103
104 # Trusted Publishing (OIDC) needs npm >= 11.5.1. .nvmrc pins the Node
105 # version (>= 22.14.0, also an OIDC requirement); npm still needs
106 # upgrading past whatever ships with it.
107 - name: Upgrade npm for Trusted Publishing
108 shell: bash
109 run: npm install -g npm@latest
110
111 # Authentication is OIDC: each @getsigit/* package has a Trusted
112 # Publisher pointing at this workflow, so there is no token to leak.
113 - name: Publish platform package to NPM
114 shell: bash
115 run: |
116 cd npm
117
118 # Binary name from Cargo.toml
119 cargo_bin="sigit"
120
121 # Prefix used for optional dependency package names
122 node_pkg_prefix="sigit"
123
124 # Derive OS and architecture from the build matrix name
125 # Matrix name format: <os>-<arch>[-<extra>]
126 node_os=$(echo "${{ matrix.build.NAME }}" | cut -d '-' -f1)
127 export node_os
128 node_arch=$(echo "${{ matrix.build.NAME }}" | cut -d '-' -f2)
129 export node_arch
130
131 # Set the version
132 export node_version="${{ env.RELEASE_VERSION }}"
133
134 # Build the platform package name; normalise win32 → windows
135 if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
136 export node_pkg="${node_pkg_prefix}-windows-${node_arch}"
137 else
138 export node_pkg="${node_pkg_prefix}-${node_os}-${node_arch}"
139 fi
140
141 # Create the package directory
142 mkdir -p "${node_pkg}/bin"
143
144 # Generate package.json + README for this platform slice
145 node ./scripts/render-platform-package.cjs \
146 "${node_pkg}" \
147 "${node_version}" \
148 "${node_os}" \
149 "${node_arch}"
150
151 # Windows binaries carry a .exe extension
152 if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
153 cargo_bin="${cargo_bin}.exe"
154 fi
155
156 cp "../target/${{ matrix.build.TARGET }}/release/${cargo_bin}" "${node_pkg}/bin"
157
158 cd "${node_pkg}"
159
160 npm_package_name="@getsigit/${node_pkg}"
161 if npm view "${npm_package_name}@${node_version}" version >/dev/null 2>&1; then
162 echo "${npm_package_name}@${node_version} already exists on npm, skipping publish"
163 exit 0
164 fi
165
166 npm publish --access public
167
168 publish-npm-base:
169 name: Publish base NPM package (@getsigit/sigit)
170 needs: publish-npm-binaries
171 runs-on: ubuntu-latest
172
173 steps:
174 - name: Checkout
175 uses: actions/checkout@v6
176 with:
177 ref: ${{ github.event.inputs.tag || github.ref }}
178
179 - name: Set the release version
180 shell: bash
181 run: |
182 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
183 release_version="${GITHUB_REF_NAME#v}"
184 else
185 release_version="${{ github.event.inputs.tag }}"
186 release_version="${release_version#v}"
187 fi
188 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
189
190 - name: Install Node
191 uses: actions/setup-node@v6
192 with:
193 node-version-file: .nvmrc
194 registry-url: "https://registry.npmjs.org"
195
196 # Trusted Publishing (OIDC) needs npm >= 11.5.1. .nvmrc pins the Node
197 # version (>= 22.14.0, also an OIDC requirement); npm still needs
198 # upgrading past whatever ships with it.
199 - name: Upgrade npm for Trusted Publishing
200 shell: bash
201 run: npm install -g npm@latest
202
203 - name: Publish base package to NPM
204 shell: bash
205 run: |
206 cd npm/sigit
207
208 # Rewrite package.json with the correct release version and
209 # matching optionalDependency versions
210 node ../scripts/render-main-package.cjs \
211 "./package.json" \
212 "${{ env.RELEASE_VERSION }}"
213
214 npm_package_name="@getsigit/sigit"
215 npm_package_version="${{ env.RELEASE_VERSION }}"
216
217 if npm view "${npm_package_name}@${npm_package_version}" version >/dev/null 2>&1; then
218 echo "${npm_package_name}@${npm_package_version} already exists on npm, skipping publish"
219 exit 0
220 fi
221
222 npm install
223 npm run build
224 npm publish --access public