Skip to content

Commit 328e842

Browse files
committed
📦 publish staticalize as npm package for Node.js environments
Some environments like Vercel require building in their own environment where only Node.js is available. There is no Deno, no Bun, and no way to download pre-built staticalize binaries. Publishing to npm as `staticalize` means `npx staticalize` works in these Node-only CI environments. - Add dnt build producing ESM npm package with bin entry point - Add build:npm and build:jsr tasks - Restructure publish workflow with verify-jsr/verify-npm pattern - Publish to both JSR and npm with provenance - Migrate CLI to configliere, imports to import map, tests to @std/expect
1 parent 869d87c commit 328e842

9 files changed

Lines changed: 330 additions & 70 deletions

File tree

‎.github/workflows/publish.yaml‎

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,109 @@ on:
77

88
permissions:
99
contents: write
10+
id-token: write
1011

1112
jobs:
12-
jsr:
13+
verify-jsr:
1314
runs-on: ubuntu-latest
1415
steps:
15-
- uses: actions/checkout@v4
16-
- uses: denoland/setup-deno@v2
16+
- name: checkout
17+
uses: actions/checkout@v4
18+
19+
- name: setup deno
20+
uses: denoland/setup-deno@v2
21+
with:
22+
deno-version: v2.x
23+
24+
- name: Get Version
25+
id: vars
26+
run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^v//')
27+
28+
- name: Build JSR
29+
run: deno task build:jsr ${{steps.vars.outputs.version}}
30+
31+
- name: dry run publish
32+
run: npx jsr publish --dry-run --allow-dirty
33+
34+
verify-npm:
35+
runs-on: ubuntu-latest
36+
steps:
37+
- name: checkout
38+
uses: actions/checkout@v4
39+
40+
- name: setup deno
41+
uses: denoland/setup-deno@v2
1742
with:
1843
deno-version: v2.x
19-
- run: deno publish --token=${{ secrets.JSR_API }}
44+
45+
- name: Get Version
46+
id: vars
47+
run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^v//')
48+
49+
- name: Setup Node
50+
uses: actions/setup-node@v4
51+
with:
52+
node-version: 24
53+
54+
- name: Build NPM
55+
run: deno task build:npm ${{steps.vars.outputs.version}}
56+
57+
- name: dry run publish
58+
run: npm publish --dry-run --tag=verify
59+
working-directory: ./build/npm
60+
61+
- name: upload build
62+
uses: actions/upload-artifact@v4
63+
with:
64+
name: npm-build
65+
path: ./build/npm
66+
67+
publish-npm:
68+
needs: [verify-jsr, verify-npm]
69+
runs-on: ubuntu-latest
70+
permissions:
71+
contents: read
72+
id-token: write
73+
steps:
74+
- name: Setup Node
75+
uses: actions/setup-node@v4
76+
with:
77+
node-version: 24
78+
79+
- name: download build
80+
uses: actions/download-artifact@v4
81+
with:
82+
name: npm-build
83+
path: ./build/npm
84+
85+
- name: Publish NPM
86+
run: npm publish --access=public --provenance --tag=latest
87+
working-directory: ./build/npm
88+
89+
publish-jsr:
90+
needs: [verify-jsr, verify-npm]
91+
runs-on: ubuntu-latest
92+
steps:
93+
- name: checkout
94+
uses: actions/checkout@v4
95+
96+
- name: setup deno
97+
uses: denoland/setup-deno@v2
98+
with:
99+
deno-version: v2.x
100+
101+
- name: Get Version
102+
id: vars
103+
run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^v//')
104+
105+
- name: Build JSR
106+
run: deno task build:jsr ${{steps.vars.outputs.version}}
107+
108+
- name: Publish JSR
109+
run: npx jsr publish --allow-dirty --token=${{secrets.JSR_API}}
20110

21111
release:
112+
needs: [verify-jsr, verify-npm]
22113
runs-on: ubuntu-latest
23114
steps:
24115
- uses: actions/checkout@v4

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
/statical
33
/dist/
44
/staticalize
5+
/.agent-shell/
6+
/build/
7+
/node_modules/

‎config.ts‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { cli, field, object, program } from "configliere";
2+
import z from "zod";
3+
import denoJSON from "./deno.json" with { type: "json" };
4+
5+
const url = () =>
6+
z.string().refine((str) => str.match(/^http/), {
7+
message: `must be a hypertext (http) url`,
8+
});
9+
10+
export const config = program({
11+
name: "staticalize",
12+
version: denoJSON.version,
13+
config: object({
14+
site: {
15+
description:
16+
"URL of the website to staticalize. E.g. http://localhost:8000",
17+
...field(url(), cli.argument()),
18+
},
19+
output: {
20+
description: "Directory to place the downloaded site",
21+
...field(z.string(), field.default("dist")),
22+
},
23+
base: {
24+
description: "Base URL of the public website. E.g. http://frontside.com",
25+
...field(url()),
26+
},
27+
}),
28+
});

‎deno.json‎

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,45 @@
88
"license": "MIT",
99
"tasks": {
1010
"dev": "deno run --watch main.ts",
11-
"compile": "deno compile --allow-read --allow-write --allow-env --allow-sys --allow-run --allow-net -o staticalize main.ts"
11+
"compile": "deno compile --allow-read --allow-write --allow-env --allow-sys --allow-run --allow-net -o staticalize main.ts",
12+
"build:npm": "deno run -A tasks/build-npm.ts",
13+
"build:jsr": "deno run -A tasks/build-jsr.ts"
1214
},
1315
"imports": {
1416
"@std/assert": "jsr:@std/assert@1",
17+
"@std/expect": "jsr:@std/expect@^1",
1518
"@std/cli": "jsr:@std/cli@1",
1619
"@std/testing": "jsr:@std/testing@^1.0.0",
1720
"@std/fs": "jsr:@std/fs@1",
1821
"@std/path": "jsr:@std/path@1",
1922
"@libs/xml": "jsr:@libs/xml@^6.0.0",
20-
"effection": "npm:effection@4.0.0-beta.2",
23+
"effection": "npm:effection@^4.0.2",
2124
"hast-util-from-html": "npm:hast-util-from-html@^2.0.3",
2225
"hast-util-select": "npm:hast-util-select@^6.0.4",
2326
"hast-util-to-html": "npm:hast-util-to-html@^9.0.5",
24-
"zod": "npm:zod@^3.20.0",
25-
"zod-opts": "npm:zod-opts@0.1.8"
27+
"zod": "npm:zod@^4.1.11",
28+
"zod-opts": "npm:zod-opts@0.1.8",
29+
"configliere": "npm:configliere@^0.2.3",
30+
"dnt": "jsr:@deno/dnt@0.42.3",
31+
"@hono/hono": "jsr:@hono/hono"
2632
},
2733
"lint": {
2834
"rules": {
2935
"exclude": ["prefer-const", "require-yield"]
3036
}
3137
},
38+
"publish": {
39+
"include": [
40+
"mod.ts",
41+
"staticalize.ts",
42+
"task-buffer.ts",
43+
"config.ts",
44+
"main.ts",
45+
"README.md",
46+
"deno.json"
47+
]
48+
},
3249
"fmt": {
33-
"exclude": ["dist"]
50+
"exclude": ["dist", "build"]
3451
}
3552
}

0 commit comments

Comments
 (0)