Skip to content

Commit e730c1e

Browse files
authored
feat: add npm package (#51)
1 parent 64131ea commit e730c1e

8 files changed

Lines changed: 193 additions & 46 deletions

File tree

.github/workflows/ci.generated.yml

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@ jobs:
7474
run: |-
7575
git config --global core.autocrlf false
7676
git config --global core.eol lf
77-
- uses: actions/checkout@v6
78-
- uses: dsherret/rust-toolchain-file@v1
77+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
78+
- uses: dsherret/rust-toolchain-file@3551321aa44dd44a0393eb3b6bdfbc5d25ecf621 # v1
7979
- name: Cache cargo
80-
uses: Swatinem/rust-cache@v2
80+
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
8181
if: '!startsWith(github.ref, ''refs/tags/'')'
8282
with:
8383
key: '${{ matrix.config.target }}'
84-
- uses: denoland/setup-deno@v2
84+
- uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2
8585
- name: Setup (Linux x86_64-musl)
8686
if: matrix.config.target == 'x86_64-unknown-linux-musl'
8787
run: |-
@@ -125,8 +125,8 @@ jobs:
125125
- name: Lint workflow generation
126126
if: '!startsWith(github.ref, ''refs/tags/'') && matrix.config.target == ''x86_64-unknown-linux-gnu'''
127127
run: |-
128-
deno run -A .github/workflows/ci.ts --lint
129-
deno run -A .github/workflows/release.ts --lint
128+
./.github/workflows/ci.ts --lint
129+
./.github/workflows/release.ts --lint
130130
- name: Test (Debug)
131131
if: 'matrix.config.run_tests == ''true'' && !startsWith(github.ref, ''refs/tags/'')'
132132
run: cargo test --locked --all-features
@@ -196,55 +196,55 @@ jobs:
196196
zip -r dprint-plugin-exec-loongarch64-unknown-linux-gnu.zip dprint-plugin-exec
197197
echo "::set-output name=ZIP_CHECKSUM::$(shasum -a 256 dprint-plugin-exec-loongarch64-unknown-linux-gnu.zip | awk '{print $1}')"
198198
- name: Upload artifacts (x86_64-apple-darwin)
199-
uses: actions/upload-artifact@v4
199+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
200200
if: 'matrix.config.target == ''x86_64-apple-darwin'' && startsWith(github.ref, ''refs/tags/'')'
201201
with:
202202
name: x86_64-apple-darwin-artifacts
203203
path: target/x86_64-apple-darwin/release/dprint-plugin-exec-x86_64-apple-darwin.zip
204204
- name: Upload artifacts (aarch64-apple-darwin)
205-
uses: actions/upload-artifact@v4
205+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
206206
if: 'matrix.config.target == ''aarch64-apple-darwin'' && startsWith(github.ref, ''refs/tags/'')'
207207
with:
208208
name: aarch64-apple-darwin-artifacts
209209
path: target/aarch64-apple-darwin/release/dprint-plugin-exec-aarch64-apple-darwin.zip
210210
- name: Upload artifacts (x86_64-pc-windows-msvc)
211-
uses: actions/upload-artifact@v4
211+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
212212
if: 'matrix.config.target == ''x86_64-pc-windows-msvc'' && startsWith(github.ref, ''refs/tags/'')'
213213
with:
214214
name: x86_64-pc-windows-msvc-artifacts
215215
path: target/x86_64-pc-windows-msvc/release/dprint-plugin-exec-x86_64-pc-windows-msvc.zip
216216
- name: Upload artifacts (x86_64-unknown-linux-gnu)
217-
uses: actions/upload-artifact@v4
217+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
218218
if: 'matrix.config.target == ''x86_64-unknown-linux-gnu'' && startsWith(github.ref, ''refs/tags/'')'
219219
with:
220220
name: x86_64-unknown-linux-gnu-artifacts
221221
path: target/x86_64-unknown-linux-gnu/release/dprint-plugin-exec-x86_64-unknown-linux-gnu.zip
222222
- name: Upload artifacts (x86_64-unknown-linux-musl)
223-
uses: actions/upload-artifact@v4
223+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
224224
if: 'matrix.config.target == ''x86_64-unknown-linux-musl'' && startsWith(github.ref, ''refs/tags/'')'
225225
with:
226226
name: x86_64-unknown-linux-musl-artifacts
227227
path: target/x86_64-unknown-linux-musl/release/dprint-plugin-exec-x86_64-unknown-linux-musl.zip
228228
- name: Upload artifacts (aarch64-unknown-linux-gnu)
229-
uses: actions/upload-artifact@v4
229+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
230230
if: 'matrix.config.target == ''aarch64-unknown-linux-gnu'' && startsWith(github.ref, ''refs/tags/'')'
231231
with:
232232
name: aarch64-unknown-linux-gnu-artifacts
233233
path: target/aarch64-unknown-linux-gnu/release/dprint-plugin-exec-aarch64-unknown-linux-gnu.zip
234234
- name: Upload artifacts (aarch64-unknown-linux-musl)
235-
uses: actions/upload-artifact@v4
235+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
236236
if: 'matrix.config.target == ''aarch64-unknown-linux-musl'' && startsWith(github.ref, ''refs/tags/'')'
237237
with:
238238
name: aarch64-unknown-linux-musl-artifacts
239239
path: target/aarch64-unknown-linux-musl/release/dprint-plugin-exec-aarch64-unknown-linux-musl.zip
240240
- name: Upload artifacts (riscv64gc-unknown-linux-gnu)
241-
uses: actions/upload-artifact@v4
241+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
242242
if: 'matrix.config.target == ''riscv64gc-unknown-linux-gnu'' && startsWith(github.ref, ''refs/tags/'')'
243243
with:
244244
name: riscv64gc-unknown-linux-gnu-artifacts
245245
path: target/riscv64gc-unknown-linux-gnu/release/dprint-plugin-exec-riscv64gc-unknown-linux-gnu.zip
246246
- name: Upload artifacts (loongarch64-unknown-linux-gnu)
247-
uses: actions/upload-artifact@v4
247+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
248248
if: 'matrix.config.target == ''loongarch64-unknown-linux-gnu'' && startsWith(github.ref, ''refs/tags/'')'
249249
with:
250250
name: loongarch64-unknown-linux-gnu-artifacts
@@ -255,12 +255,19 @@ jobs:
255255
- build
256256
if: 'startsWith(github.ref, ''refs/tags/'')'
257257
runs-on: ubuntu-latest
258+
permissions:
259+
contents: write
260+
id-token: write
258261
steps:
259262
- name: Checkout
260-
uses: actions/checkout@v4
263+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
261264
- name: Download artifacts
262-
uses: actions/download-artifact@v4
263-
- uses: denoland/setup-deno@v2
265+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
266+
- uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2
267+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
268+
with:
269+
node-version: 24.x
270+
registry-url: 'https://registry.npmjs.org'
264271
- name: Move downloaded artifacts to root directory
265272
run: |-
266273
mv x86_64-apple-darwin-artifacts/dprint-plugin-exec-x86_64-apple-darwin.zip .
@@ -293,10 +300,12 @@ jobs:
293300
run: 'echo "::set-output name=CHECKSUM::$(shasum -a 256 plugin.json | awk ''{print $1}'')"'
294301
- name: Update Config Schema Version
295302
run: 'sed -i ''s/exec\/0.0.0/exec\/${{ steps.get_tag_version.outputs.TAG_VERSION }}/'' deployment/schema.json'
303+
- name: Build npm packages
304+
run: deno run -A scripts/create_npm_packages.ts
296305
- name: Create release notes
297306
run: 'deno run -A ./scripts/generate_release_notes.ts ${{ steps.get_tag_version.outputs.TAG_VERSION }} ${{ steps.get_plugin_file_checksum.outputs.CHECKSUM }} > ${{ github.workspace }}-CHANGELOG.txt'
298307
- name: Release
299-
uses: softprops/action-gh-release@v2.6.1
308+
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
300309
env:
301310
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
302311
with:
@@ -313,3 +322,5 @@ jobs:
313322
plugin.json
314323
deployment/schema.json
315324
body_path: '${{ github.workspace }}-CHANGELOG.txt'
325+
- name: Publish npm packages
326+
run: deno run -A scripts/publish_npm_packages.ts

.github/workflows/ci.ts

100644100755
Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
#!/usr/bin/env -S deno run -A
2-
import {
3-
conditions,
4-
defineMatrix,
5-
expr,
6-
job,
7-
step,
8-
workflow,
9-
} from "jsr:@david/gagen@^0.5.0";
2+
import { conditions, defineMatrix, expr, job, step, workflow } from "jsr:@david/gagen@^0.5.0";
103

114
enum OperatingSystem {
125
Macx86 = "macos-15-intel",
@@ -174,7 +167,8 @@ const buildJob = job("build", {
174167
{
175168
name: "Setup cross",
176169
if: isCross,
177-
run: "cargo install cross --git https://github.com/cross-rs/cross --rev 4090beca3cfffa44371a5bba524de3a578aa46c3",
170+
run:
171+
"cargo install cross --git https://github.com/cross-rs/cross --rev 4090beca3cfffa44371a5bba524de3a578aa46c3",
178172
},
179173
{
180174
name: "Build (Debug)",
@@ -211,8 +205,8 @@ const buildJob = job("build", {
211205
name: "Lint workflow generation",
212206
if: isNotTag.and(target.equals("x86_64-unknown-linux-gnu")),
213207
run: [
214-
"deno run -A .github/workflows/ci.ts --lint",
215-
"deno run -A .github/workflows/release.ts --lint",
208+
"./.github/workflows/ci.ts --lint",
209+
"./.github/workflows/release.ts --lint",
216210
],
217211
},
218212
{
@@ -229,7 +223,7 @@ const buildJob = job("build", {
229223
...profiles.map((profile) => ({
230224
name: `Upload artifacts (${profile.target})`,
231225
if: target.equals(profile.target).and(isTag),
232-
uses: "actions/upload-artifact@v4",
226+
uses: "actions/upload-artifact@v7",
233227
with: {
234228
name: profile.artifactsName,
235229
path: `target/${profile.target}/release/${profile.zipFileName}`,
@@ -257,15 +251,19 @@ const draftReleaseJob = job("draft_release", {
257251
if: isTag,
258252
needs: [buildJob],
259253
runsOn: "ubuntu-latest",
254+
// id-token: write is required for npm --provenance
255+
permissions: { contents: "write", "id-token": "write" },
260256
steps: [
261-
{ name: "Checkout", uses: "actions/checkout@v4" },
262-
{ name: "Download artifacts", uses: "actions/download-artifact@v4" },
257+
{ name: "Checkout", uses: "actions/checkout@v6" },
258+
{ name: "Download artifacts", uses: "actions/download-artifact@v8" },
263259
{ uses: "denoland/setup-deno@v2" },
260+
{
261+
uses: "actions/setup-node@v6",
262+
with: { "node-version": "24.x", "registry-url": "https://registry.npmjs.org" },
263+
},
264264
{
265265
name: "Move downloaded artifacts to root directory",
266-
run: profiles.map((profile) =>
267-
`mv ${profile.artifactsName}/${profile.zipFileName} .`
268-
),
266+
run: profiles.map((profile) => `mv ${profile.artifactsName}/${profile.zipFileName} .`),
269267
},
270268
{
271269
name: "Output checksums",
@@ -281,11 +279,19 @@ const draftReleaseJob = job("draft_release", {
281279
getPluginFileChecksum,
282280
{
283281
name: "Update Config Schema Version",
284-
run: `sed -i 's/exec\\/0.0.0/exec\\/${getTagVersion.outputs.TAG_VERSION}/' deployment/schema.json`,
282+
run:
283+
`sed -i 's/exec\\/0.0.0/exec\\/${getTagVersion.outputs.TAG_VERSION}/' deployment/schema.json`,
284+
},
285+
{
286+
// must run before "Create release notes" — the notes embed the main
287+
// npm tarball's sha256 from npm-dist/publish-manifest.json.
288+
name: "Build npm packages",
289+
run: "deno run -A scripts/create_npm_packages.ts",
285290
},
286291
{
287292
name: "Create release notes",
288-
run: `deno run -A ./scripts/generate_release_notes.ts ${getTagVersion.outputs.TAG_VERSION} ${getPluginFileChecksum.outputs.CHECKSUM} > \${{ github.workspace }}-CHANGELOG.txt`,
293+
run:
294+
`deno run -A ./scripts/generate_release_notes.ts ${getTagVersion.outputs.TAG_VERSION} ${getPluginFileChecksum.outputs.CHECKSUM} > \${{ github.workspace }}-CHANGELOG.txt`,
289295
},
290296
{
291297
name: "Release",
@@ -300,6 +306,10 @@ const draftReleaseJob = job("draft_release", {
300306
body_path: "${{ github.workspace }}-CHANGELOG.txt",
301307
},
302308
},
309+
{
310+
name: "Publish npm packages",
311+
run: "deno run -A scripts/publish_npm_packages.ts",
312+
},
303313
],
304314
});
305315

@@ -318,5 +328,5 @@ workflow({
318328
}).writeOrLint({
319329
filePath: new URL("./ci.generated.yml", import.meta.url),
320330
header: "# GENERATED BY ./ci.ts -- DO NOT DIRECTLY EDIT",
321-
pinDeps: false,
331+
pinDeps: true,
322332
});

.github/workflows/release.generated.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ jobs:
1919
timeout-minutes: 30
2020
steps:
2121
- name: Clone repository
22-
uses: actions/checkout@v4
22+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
2323
with:
2424
token: '${{ secrets.GH_DPRINTBOT_PAT }}'
25-
- uses: denoland/setup-deno@v2
26-
- uses: dtolnay/rust-toolchain@stable
25+
- uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2
26+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
2727
- name: Bump version and tag
2828
env:
2929
GITHUB_TOKEN: '${{ secrets.GH_DPRINTBOT_PAT }}'

.github/workflows/release.ts

100644100755
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@ workflow({
4949
}).writeOrLint({
5050
filePath: new URL("./release.generated.yml", import.meta.url),
5151
header: "# GENERATED BY ./release.ts -- DO NOT DIRECTLY EDIT",
52-
pinDeps: false,
52+
pinDeps: true,
5353
});

scripts/create_npm_packages.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { $, CargoToml, getChecksum, processPlugin } from "jsr:@dprint/automation@0.11.2";
2+
3+
const pluginName = "dprint-plugin-exec";
4+
const mainPackageName = "@dprint/exec";
5+
const outDir = "npm-dist";
6+
// where the platform zips are extracted before being repacked as npm sub-packages.
7+
const extractDir = "npm-binaries";
8+
9+
const platforms: processPlugin.Platform[] = [
10+
"darwin-aarch64",
11+
"darwin-x86_64",
12+
"linux-aarch64",
13+
"linux-aarch64-musl",
14+
"linux-x86_64",
15+
"linux-x86_64-musl",
16+
"linux-riscv64",
17+
"linux-loongarch64",
18+
"windows-x86_64",
19+
];
20+
21+
const rootDir = $.path(import.meta.dirname!).join("..");
22+
const version = new CargoToml(rootDir.join("Cargo.toml")).version();
23+
24+
const extractRoot = rootDir.join(extractDir);
25+
extractRoot.mkdirSync({ recursive: true });
26+
27+
const platformInputs = await Promise.all(platforms.map(async (platform) => {
28+
const zipPath = rootDir.join(
29+
processPlugin.getStandardZipFileName(pluginName, platform),
30+
);
31+
const platformDir = extractRoot.join(platform);
32+
platformDir.mkdirSync({ recursive: true });
33+
await $`unzip -o ${zipPath.toString()} -d ${platformDir.toString()}`.quiet();
34+
const binaryName = platform.startsWith("windows-") ? `${pluginName}.exe` : pluginName;
35+
return {
36+
platform,
37+
binaryPath: platformDir.join(binaryName).toString(),
38+
};
39+
}));
40+
41+
const result = await processPlugin.createDprintOrgNpmPackages({
42+
pluginName,
43+
mainPackageName,
44+
version,
45+
outDir: rootDir.join(outDir).toString(),
46+
platforms: platformInputs,
47+
packageJsonExtra: {
48+
description: "Execute a CLI as a dprint plugin to format code.",
49+
license: "MIT",
50+
repository: {
51+
type: "git",
52+
url: "git+https://github.com/dprint/dprint-plugin-exec.git",
53+
},
54+
homepage: "https://github.com/dprint/dprint-plugin-exec",
55+
},
56+
});
57+
58+
// hash the main tarball so the release-notes step can embed it in the
59+
// `npm:@dprint/exec@<version>/plugin.json@<hash>` reference users paste
60+
// into dprint.json. This is the hash dprint verifies before extracting.
61+
const mainPackageChecksum = await getChecksum(await Deno.readFile(result.mainPackageTarball));
62+
63+
// emit a manifest so publish_npm_packages.ts knows the order and which
64+
// tarballs to publish without having to re-derive it from the directory.
65+
await Deno.writeTextFile(
66+
rootDir.join(outDir, "publish-manifest.json").toString(),
67+
JSON.stringify(
68+
{
69+
mainPackageName,
70+
version,
71+
subPackageTarballs: result.subPackageTarballs,
72+
mainPackageTarball: result.mainPackageTarball,
73+
mainPackageChecksum,
74+
},
75+
undefined,
76+
2,
77+
) + "\n",
78+
);
79+
80+
console.log("Main package tarball:", result.mainPackageTarball);
81+
console.log("Sub-package tarballs:");
82+
for (const tgz of result.subPackageTarballs) {
83+
console.log(" " + tgz);
84+
}

scripts/create_plugin_file.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { $, CargoToml, processPlugin } from "jsr:@dprint/automation@0.10.3";
1+
import { $, CargoToml, processPlugin } from "jsr:@dprint/automation@0.11.0";
22

33
const currentDirPath = $.path(import.meta.dirname!);
44
const cargoFilePath = currentDirPath.join("../Cargo.toml");

0 commit comments

Comments
 (0)