@dk/hipp 0.1.30 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -15
- package/hipp.js +15 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ By Dmytri Kleiner <dev@dmytri.to>
|
|
|
4
4
|
|
|
5
5
|
**HIPP** is a minimalist, stateless publishing tool that eliminates version-bump
|
|
6
6
|
commits and merge conflicts by treating Git Tags as the single source of truth.
|
|
7
|
-
Your `package.json` version stays
|
|
7
|
+
Your `package.json` version stays at `0.0.0` (or matches your latest tag).
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -22,10 +22,10 @@ This creates a **State Conflict**:
|
|
|
22
22
|
|
|
23
23
|
## The Solution
|
|
24
24
|
|
|
25
|
-
**HIPP makes
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
**HIPP makes Git tags the source of truth** - the version is always extracted
|
|
26
|
+
from the tag, not `package.json`. You can leave `package.json` at `0.0.0` (HIPP
|
|
27
|
+
rewrites it during publish) or keep it in sync with your tag (HIPP verifies the
|
|
28
|
+
match).
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
@@ -33,13 +33,14 @@ stays clean, and your registry package is guaranteed to match your Git tag.
|
|
|
33
33
|
|
|
34
34
|
### Setup
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Set your project's `package.json` version to `0.0.0`, or leave it in sync with
|
|
37
|
+
your latest tag. The git tag is always the source of truth.
|
|
37
38
|
|
|
38
39
|
```json
|
|
39
40
|
{ "name": "your-package", "version": "0.0.0" }
|
|
40
41
|
```
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
Ensure `package-lock.json` exists and is tracked by git.
|
|
43
44
|
|
|
44
45
|
### Tag and Publish
|
|
45
46
|
|
|
@@ -68,7 +69,7 @@ npx @dk/hipp -- --access public --tag beta
|
|
|
68
69
|
HIPP will:
|
|
69
70
|
|
|
70
71
|
1. **Key Generation**: Generate Ed25519 signing keys if needed (`hipp.priv`, `hipp.pub`)
|
|
71
|
-
2. **Verify**: Ensure
|
|
72
|
+
2. **Verify**: Ensure `package.json` version is `0.0.0` or matches the git tag
|
|
72
73
|
3. **Clean Check**: Ensure your git status is clean
|
|
73
74
|
4. **Validate**: Extract and verify the latest tag against Semver rules
|
|
74
75
|
5. **Sign**: Create a cryptographic manifest of your package content
|
|
@@ -93,6 +94,17 @@ with their original keys.
|
|
|
93
94
|
**Multiple publishers**: Each developer can use their own private key. Delete
|
|
94
95
|
`hipp.pub`, run HIPP, and a new keypair will be generated for that revision.
|
|
95
96
|
|
|
97
|
+
### Why This Works
|
|
98
|
+
|
|
99
|
+
The public key in `hipp.pub` is committed to git at the specific revision of
|
|
100
|
+
each release. Verification always uses the key from that historical revision,
|
|
101
|
+
not a current one. This means:
|
|
102
|
+
|
|
103
|
+
- You don't need to retain your private key — once published, past releases are
|
|
104
|
+
verifiable from the git history alone
|
|
105
|
+
- A compromised private key can only sign future releases, not forge past ones
|
|
106
|
+
- Multiple publishers work naturally because each release is self-contained
|
|
107
|
+
|
|
96
108
|
### Options
|
|
97
109
|
|
|
98
110
|
* `-y, --yes`: Skip the confirmation prompt (ideal for CI/CD pipelines).
|
|
@@ -208,7 +220,7 @@ package, but only private key holders can publish.
|
|
|
208
220
|
|
|
209
221
|
HIPP enforces strict integrity rules when publishing:
|
|
210
222
|
|
|
211
|
-
- `package.json` version must be `0.0.0`
|
|
223
|
+
- `package.json` version must be `0.0.0` or match the git tag
|
|
212
224
|
- `package-lock.json` must exist and be tracked by git
|
|
213
225
|
- `npm ci --ignore-scripts --dry-run` must succeed
|
|
214
226
|
- Repository must be clean
|
|
@@ -242,21 +254,21 @@ PERFORMANCE OF THIS SOFTWARE.
|
|
|
242
254
|
Verify this package with [@dk/hipp](https://www.npmjs.com/package/@dk/hipp):
|
|
243
255
|
|
|
244
256
|
```bash
|
|
245
|
-
npx @dk/hipp verify @dk/hipp@0.1.
|
|
257
|
+
npx @dk/hipp verify @dk/hipp@0.1.32
|
|
246
258
|
```
|
|
247
259
|
|
|
248
260
|
```json
|
|
249
261
|
{
|
|
250
262
|
"origin": "git@github.com:dmytri/hipp.git",
|
|
251
|
-
"tag": "v0.1.
|
|
252
|
-
"revision": "
|
|
253
|
-
"hash": "
|
|
254
|
-
"signature": "
|
|
263
|
+
"tag": "v0.1.32",
|
|
264
|
+
"revision": "2aa00fdf83fe709d8707ed1b568b104a21b8d3e8",
|
|
265
|
+
"hash": "f130afe85486afc6f41d3c4f2439e3c9e4cee3fb36fd323a0476908e730daa90",
|
|
266
|
+
"signature": "CfrmQ5a/cQwW7Sy3pYInuEdPOZH+SlrS3l7g6h0cQmNa38CcsVg9sZI1hG4XZSj9YT2cB6EAetDbOnljPqE8CA==",
|
|
255
267
|
"name": "Dmytri Kleiner",
|
|
256
268
|
"email": "dev@dmytri.to",
|
|
257
269
|
"npm": "11.12.1",
|
|
258
270
|
"node": "v25.8.2",
|
|
259
271
|
"git": "git version 2.47.3",
|
|
260
|
-
"hipp": "0.1.
|
|
272
|
+
"hipp": "0.1.32"
|
|
261
273
|
}
|
|
262
274
|
```
|
package/hipp.js
CHANGED
|
@@ -218,9 +218,9 @@ function getVersionFromExactTagOnHead() {
|
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
function ensureCleanRepo(pkg) {
|
|
222
|
-
if (pkg.version !== '0.0.0') {
|
|
223
|
-
fail(
|
|
221
|
+
function ensureCleanRepo(pkg, tagVersion) {
|
|
222
|
+
if (pkg.version !== '0.0.0' && pkg.version !== tagVersion) {
|
|
223
|
+
fail(`❌ Integrity Violation: package.json version must be 0.0.0 or match the git tag (v${tagVersion})`);
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
if (pkg.workspaces) {
|
|
@@ -525,6 +525,8 @@ async function runVerify(packageSpec) {
|
|
|
525
525
|
} else {
|
|
526
526
|
const publicKey = fs.readFileSync(publicKeyPath, 'utf8');
|
|
527
527
|
|
|
528
|
+
log.info(`🔑 Public key: hipp.pub from git@rev ${revision.slice(0, 12)} at tag ${tag}`);
|
|
529
|
+
|
|
528
530
|
log.info(`🏗️ Staging git files...`);
|
|
529
531
|
const trackedFiles = getTrackedFilesFromDir(tmpDir);
|
|
530
532
|
copyTrackedFilesFromDir(stageDir, tmpDir, trackedFiles);
|
|
@@ -674,7 +676,7 @@ async function run() {
|
|
|
674
676
|
|
|
675
677
|
const { rawTag, version } = getVersionFromExactTagOnHead();
|
|
676
678
|
|
|
677
|
-
ensureCleanRepo(pkg);
|
|
679
|
+
ensureCleanRepo(pkg, version);
|
|
678
680
|
|
|
679
681
|
const refInfo = ensureMutableRefPolicy();
|
|
680
682
|
const provenance = ensureRemoteProvenance(rawTag, refInfo.head);
|
|
@@ -794,14 +796,12 @@ if (isVerify) {
|
|
|
794
796
|
if (!hasSelf) {
|
|
795
797
|
try {
|
|
796
798
|
const pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8'));
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
return;
|
|
804
|
-
}
|
|
799
|
+
const rawTag = git(['describe', '--tags', '--exact-match', 'HEAD']);
|
|
800
|
+
if (rawTag.startsWith('v')) {
|
|
801
|
+
const tagVersion = semver.clean(rawTag);
|
|
802
|
+
if (tagVersion && (pkg.version === '0.0.0' || pkg.version === tagVersion)) {
|
|
803
|
+
runVerify(`${pkg.name}@${tagVersion}`);
|
|
804
|
+
return;
|
|
805
805
|
}
|
|
806
806
|
}
|
|
807
807
|
} catch {}
|
|
@@ -820,8 +820,8 @@ Usage:
|
|
|
820
820
|
npx hipp verify [@package[@version]]
|
|
821
821
|
npx hipp verify --self
|
|
822
822
|
|
|
823
|
-
Without arguments: in a hipp repo (package.json version 0.0.0
|
|
824
|
-
semver tag on HEAD), verifies the published package at that version.
|
|
823
|
+
Without arguments: in a hipp repo (package.json version 0.0.0 or matching
|
|
824
|
+
a semver tag on HEAD), verifies the published package at that version.
|
|
825
825
|
Otherwise verifies @dk/hipp itself.
|
|
826
826
|
--self: always verifies @dk/hipp.
|
|
827
827
|
|
|
@@ -835,7 +835,7 @@ Verify: Downloads npm tarball, clones git at tag, runs all three verification ch
|
|
|
835
835
|
3. Rebuild verification (npm tarball equals git rebuild with manifest+version)
|
|
836
836
|
|
|
837
837
|
Integrity rules:
|
|
838
|
-
- package.json version must be 0.0.0
|
|
838
|
+
- package.json version must be 0.0.0 or match the git tag
|
|
839
839
|
- package-lock.json must exist and be tracked
|
|
840
840
|
- npm ci --ignore-scripts --dry-run must succeed
|
|
841
841
|
- repository must be clean
|