+2
-2
.github/workflows/publish-jsr.yml
+2
-2
.github/workflows/publish-jsr.yml
+93
-48
RELEASE.md
+93
-48
RELEASE.md
···
24
24
25
25
## Pre-Release Checklist
26
26
27
-
1. Ensure all tests pass
27
+
- [ ] Ensure all tests pass
28
28
29
-
```bash
30
-
pnpm test:run
31
-
```
29
+
```bash
30
+
pnpm test:run
31
+
```
32
32
33
-
2. Type check all packages
33
+
- [ ] Type check all packages
34
34
35
-
```bash
36
-
pnpm typecheck
37
-
```
35
+
```bash
36
+
pnpm typecheck
37
+
```
38
38
39
-
3. Build all packages
39
+
- [ ] Build all packages
40
40
41
-
```bash
42
-
pnpm build
43
-
```
41
+
```bash
42
+
pnpm build
43
+
```
44
44
45
-
4. Review changelog and update version numbers
45
+
- [ ] Update version numbers
46
46
47
47
## Publishing voltx.js
48
48
···
51
51
- **npm**: `voltx.js` (unscoped)
52
52
- **JSR**: `@voltx.js/core` (scoped, JSR requires scopes)
53
53
54
+
Publishing is **fully automated** via GitHub Actions when you push a tag.
55
+
54
56
### 1. Update Version
55
57
56
58
Update version in both files:
···
64
66
- Minor: new features, backward compatible (0.1.0 → 0.2.0)
65
67
- Major: breaking changes (0.1.0 → 1.0.0)
66
68
67
-
### 2. Build Package
69
+
### 2. Build and Test Locally
68
70
69
71
```bash
70
72
cd lib
71
73
pnpm build
74
+
pnpm test:run
72
75
```
73
76
74
77
Verify build outputs:
75
78
76
-
- `dist/volt.js` - Main framework bundle
77
-
- `dist/volt.css` - CSS framework
78
-
- `dist/index.d.ts` - TypeScript declarations
79
+
- [ ] `dist/voltx.js` - Unminified ES module
80
+
- [ ] `dist/voltx.min.js` - Minified ES module
81
+
- [ ] `dist/voltx.min.js.gz` - Gzipped minified version (for size verification)
82
+
- [ ] `dist/voltx.d.ts` - Main TypeScript declarations
83
+
- [ ] `dist/debug.js` - Debug module (unminified)
84
+
- [ ] `dist/debug.min.js` - Debug module (minified)
85
+
- [ ] `dist/debug.d.ts` - Debug TypeScript declarations
86
+
- [ ] `dist/voltx.css` - Unminified CSS framework
87
+
- [ ] `dist/voltx.min.css` - Minified CSS framework
79
88
80
-
### 3. Publish to npm
89
+
Ensure no unwanted files:
90
+
91
+
- [ ] No chunks (code splitting disabled)
92
+
- [ ] No asset files (vite.svg, etc.)
93
+
94
+
### 3. Commit Version Bump
81
95
82
96
```bash
83
-
cd lib
84
-
npm publish --provenance
97
+
git add lib/package.json lib/jsr.json
98
+
git commit -m "chore: bump version to vX.Y.Z"
99
+
git push origin main
85
100
```
86
101
87
-
The `--provenance` flag adds supply chain security metadata when publishing from GitHub Actions.
88
-
89
-
### 4. Publish to JSR
102
+
### 4. Create and Push Tag
90
103
91
104
```bash
92
-
cd lib
93
-
npx jsr publish
105
+
git tag vX.Y.Z
106
+
git push origin vX.Y.Z
94
107
```
95
108
96
-
First time: Browser window opens for authentication
97
-
Subsequent publishes: Uses cached credentials
109
+
**This triggers automated publishing:**
110
+
111
+
- `.github/workflows/publish-npm.yml` - Publishes to npm with provenance
112
+
- `.github/workflows/publish-jsr.yml` - Publishes to JSR
113
+
114
+
### 5. Monitor GitHub Actions
115
+
116
+
- [ ] Check workflow runs: <https://github.com/stormlightlabs/volt/actions>
117
+
- [ ] Verify npm publish workflow succeeded
118
+
- [ ] Verify JSR publish workflow succeeded
98
119
99
-
### 5. Verify Publication
120
+
### 6. Verify Publication
100
121
101
-
npm:
122
+
- [ ] Verify npm publication
102
123
103
124
```bash
104
125
npm view voltx.js
105
126
```
106
127
107
-
JSR:
128
+
Visit: <https://www.npmjs.com/package/voltx.js>
129
+
130
+
- [ ] Verify JSR publication
108
131
109
132
```bash
110
133
npx jsr info @voltx.js/core
111
134
```
112
135
113
-
Or visit:
136
+
Visit: <https://jsr.io/@voltx.js/core>
137
+
138
+
- [ ] Verify unpkg.com distribution structure
139
+
Visit: `https://unpkg.com/voltx.js@VERSION/` (replace VERSION)
114
140
115
-
- npm: <https://www.npmjs.com/package/voltx.js>
116
-
- JSR: <https://jsr.io/@voltx.js/core>
141
+
You should see:
142
+
- dist/ directory with all build outputs
143
+
- LICENSE
144
+
- README.md
145
+
- package.json
117
146
118
147
## Post-Release
119
148
120
-
1. Create Git tag
149
+
- [ ] Create GitHub release with changelog
150
+
- Go to <https://github.com/stormlightlabs/volt/releases>
151
+
- Click "Draft a new release"
152
+
- Select the tag (vX.Y.Z) that was just pushed
153
+
- Add release notes and changelog
154
+
- [ ] Update documentation if needed
155
+
- [ ] Announce release (if significant update)
121
156
122
-
```bash
123
-
git tag v0.1.0
124
-
git push origin v0.1.0
125
-
```
157
+
## Manual Publishing (Fallback)
158
+
159
+
If GitHub Actions fail or you need to publish manually:
126
160
127
-
2. Create GitHub release with changelog
161
+
### npm
128
162
129
-
3. Update documentation if needed
163
+
```bash
164
+
cd lib
165
+
npm publish --provenance
166
+
```
167
+
168
+
Requires:
169
+
170
+
- npm login (`npm whoami` to verify)
171
+
- npm publish rights to voltx.js package
172
+
173
+
### JSR
130
174
131
-
## To-Do
175
+
```bash
176
+
cd lib
177
+
npx jsr publish
178
+
```
132
179
133
-
Consider setting up GitHub Actions workflow to automate:
180
+
First time: Browser window opens for authentication
181
+
Subsequent publishes: Uses cached credentials
134
182
135
-
- Publishing to npm
136
-
- Version bumping
137
-
- Building
138
-
- Git tagging
139
-
- GitHub release creation
183
+
## To-Do
140
184
141
-
Consider using `bumpp` or `changeset` for automated version management across the monorepo.
185
+
- Consider using `bumpp` or `changeset` for automated version management across the monorepo.
186
+
- Write a changelog
+1
-1
lib/README.md
+1
-1
lib/README.md
+10
-6
lib/package.json
+10
-6
lib/package.json
···
9
9
"keywords": ["reactive", "signals", "framework", "ui", "declarative", "html", "dom", "frontend"],
10
10
"main": "./dist/voltx.js",
11
11
"module": "./dist/voltx.js",
12
-
"types": "./dist/index.d.ts",
12
+
"types": "./dist/voltx.d.ts",
13
13
"exports": {
14
-
".": { "types": "./dist/index.d.ts", "import": "./dist/voltx.js" },
14
+
".": { "types": "./dist/voltx.d.ts", "import": "./dist/voltx.js" },
15
15
"./debug": { "types": "./dist/debug.d.ts", "import": "./dist/debug.js" },
16
-
"./css": "./dist/volt.css",
16
+
"./css": "./dist/voltx.css",
17
17
"./package.json": "./package.json"
18
18
},
19
-
"files": ["dist", "src", "README.md"],
19
+
"files": ["dist", "LICENSE", "README.md"],
20
20
"scripts": {
21
21
"dev": "vite",
22
-
"build": "pnpm build:lib && pnpm build:css",
23
-
"build:lib": "tsc -p tsconfig.build.json && vite build --mode lib",
22
+
"build": "pnpm build:clean && pnpm build:types && pnpm build:lib && pnpm build:lib:min && pnpm build:css && pnpm build:css:min && pnpm build:finalize",
23
+
"build:clean": "rm -rf dist",
24
+
"build:types": "tsc -p tsconfig.build.json",
25
+
"build:lib": "vite build --mode lib",
26
+
"build:lib:min": "vite build --mode lib:min",
24
27
"build:css": "postcss src/styles/index.css -o dist/voltx.css",
25
28
"build:css:min": "postcss src/styles/index.css -o dist/voltx.min.css --env production",
29
+
"build:finalize": "node scripts/build-finalize.js",
26
30
"preview": "vite preview",
27
31
"test": "vitest",
28
32
"test:run": "vitest run",
+81
lib/scripts/build-finalize.js
+81
lib/scripts/build-finalize.js
···
1
+
#!/usr/bin/env node
2
+
3
+
/**
4
+
* Post-build script to finalize the distribution package:
5
+
* 1. Copy index.d.ts to voltx.d.ts for cleaner imports
6
+
* 2. Compress voltx.min.js to voltx.min.js.gz
7
+
* 3. Clean up unwanted files (chunks, assets)
8
+
*/
9
+
import { copyFileSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
10
+
import path from "node:path";
11
+
import { fileURLToPath } from "node:url";
12
+
import { createGzip } from "node:zlib";
13
+
14
+
// TODO: move to dev cli
15
+
function main() {
16
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
+
const distDir = path.resolve(__dirname, "../dist");
18
+
19
+
console.log("Finalizing build...\n");
20
+
21
+
try {
22
+
const indexDts = path.join(distDir, "index.d.ts");
23
+
const voltxDts = path.join(distDir, "voltx.d.ts");
24
+
copyFileSync(indexDts, voltxDts);
25
+
console.log("✓ Copied index.d.ts → voltx.d.ts");
26
+
} catch (error) {
27
+
console.error("✗ Failed to copy type definitions:", error.message);
28
+
process.exit(1);
29
+
}
30
+
31
+
try {
32
+
const minJsPath = path.join(distDir, "voltx.min.js");
33
+
const gzPath = path.join(distDir, "voltx.min.js.gz");
34
+
35
+
const input = readFileSync(minJsPath);
36
+
const gzip = createGzip({ level: 9 });
37
+
const output = [];
38
+
39
+
gzip.on("data", (chunk) => output.push(chunk));
40
+
gzip.on("end", () => {
41
+
writeFileSync(gzPath, Buffer.concat(output));
42
+
const originalSize = (input.length / 1024).toFixed(2);
43
+
const compressedSize = (Buffer.concat(output).length / 1024).toFixed(2);
44
+
console.log(`✓ Compressed voltx.min.js: ${originalSize}KB → ${compressedSize}KB (gzip)`);
45
+
});
46
+
47
+
gzip.write(input);
48
+
gzip.end();
49
+
} catch (error) {
50
+
console.error("✗ Failed to compress voltx.min.js:", error.message);
51
+
process.exit(1);
52
+
}
53
+
54
+
try {
55
+
const files = readdirSync(distDir);
56
+
// Any files not named voltx* or debug* or images
57
+
const unwantedPatterns = [/^(?!voltx|debug).*\.js$/, /\.svg$/, /\.png$/, /\.jpg$/];
58
+
59
+
let cleanedCount = 0;
60
+
for (const file of files) {
61
+
const shouldDelete = unwantedPatterns.some((pattern) => pattern.test(file));
62
+
if (shouldDelete) {
63
+
unlinkSync(path.join(distDir, file));
64
+
console.log(`✓ Removed unwanted file: ${file}`);
65
+
cleanedCount++;
66
+
}
67
+
}
68
+
69
+
if (cleanedCount === 0) {
70
+
console.log("✓ No unwanted files to clean");
71
+
}
72
+
} catch (error) {
73
+
console.error("✗ Failed to clean unwanted files:", error.message);
74
+
process.exit(1);
75
+
}
76
+
77
+
console.log("\n✨ Build finalization complete!");
78
+
process.exit(0);
79
+
}
80
+
81
+
main();
+1
-1
lib/tsconfig.json
+1
-1
lib/tsconfig.json
+32
-14
lib/vite.config.ts
+32
-14
lib/vite.config.ts
···
21
21
},
22
22
};
23
23
24
-
const buildOptions = (mode: string): BuildEnvironmentOptions => ({
25
-
minify: mode === "lib" ? "oxc" : true,
26
-
...(mode === "lib"
27
-
? {
28
-
lib: {
29
-
entry: { voltx: path.resolve(__dirname, "src/index.ts"), debug: path.resolve(__dirname, "src/debug.ts") },
30
-
name: "VoltX",
31
-
formats: ["es"],
32
-
},
33
-
rolldownOptions: { output: { assetFileNames: "voltx.[ext]", minify: true } },
34
-
}
35
-
: {}),
36
-
});
24
+
const buildOptions = (mode: string): BuildEnvironmentOptions => {
25
+
const isLibBuild = mode === "lib" || mode === "lib:min";
26
+
const shouldMinify = mode === "lib:min";
27
+
28
+
return {
29
+
minify: shouldMinify ? "oxc" : false,
30
+
...(isLibBuild
31
+
? {
32
+
lib: {
33
+
entry: { voltx: path.resolve(__dirname, "src/index.ts"), debug: path.resolve(__dirname, "src/debug.ts") },
34
+
name: "VoltX",
35
+
formats: ["es"],
36
+
fileName: (format, entryName) => {
37
+
const suffix = shouldMinify ? ".min.js" : ".js";
38
+
return `${entryName}${suffix}`;
39
+
},
40
+
},
41
+
rolldownOptions: {
42
+
output: { assetFileNames: "voltx.[ext]", manualChunks: undefined, preserveModules: false },
43
+
onwarn(warning, warn) {
44
+
if (warning.code === "UNUSED_EXTERNAL_IMPORT") return;
45
+
warn(warning);
46
+
},
47
+
},
48
+
}
49
+
: {}),
50
+
};
51
+
};
37
52
38
53
export default defineConfig(({ mode }) => ({
39
54
resolve: {
···
46
61
"$vebug": path.resolve(__dirname, "./src/debug.ts"),
47
62
},
48
63
},
49
-
build: buildOptions(mode),
64
+
build: {
65
+
...buildOptions(mode),
66
+
emptyOutDir: false, // Don't clear dist/ to preserve TypeScript declarations
67
+
},
50
68
test,
51
69
plugins: [],
52
70
}));