create-grist-widget 0.2.24 → 0.3.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-grist-widget",
3
- "version": "0.2.24",
3
+ "version": "0.3.1",
4
4
  "description": "Scaffold a new Grist custom widget from the grist-widget-sdk Vite template",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -2,24 +2,18 @@ name: Deploy widget to GitHub Pages
2
2
 
3
3
  # Two channels, one workflow:
4
4
  # - push to main / manual dispatch -> release channel: immutable
5
- # /<repo>/v<version>/ + mutable /<repo>/latest/.
5
+ # /<repo>/v<version>/ + mutable /<repo>/latest/, plus the same build at
6
+ # the site root (the showcase hub landing page).
6
7
  # Rebuilt only when package.json's version has no v<version> dir yet, so
7
8
  # re-pushing main without a version bump is a no-op deploy.
8
- # A push that *creates* the main ref, authored by GitHub's own web-flow
9
- # bot -- fired by "Use this template" copying this repo onto a brand-new
10
- # ref -- is skipped entirely instead: it would otherwise publish
11
- # whatever boilerplate version package.json happens to have checked in
12
- # and permanently spend the first-release override before anyone's done
13
- # real work. (Checking github.event.created alone isn't enough: a CLI
14
- # scaffold's own first `git push -u origin main` also creates that ref
15
- # for the first time, but is a real user's genuine first release and
16
- # must not be skipped -- the web-flow committer check tells the two
17
- # apart.) That run still clears any foreign content the copy brought
18
- # along (stray v<version>/ dirs, a root/latest/ still pointing at the
19
- # source repo's own path) via `cleanup-foreign`, and places the freshly
20
- # built showcase hub at the site root via `place-root`, so the bare
21
- # repo-root URL works immediately instead of 404ing until the widget's
22
- # real first release. It just never creates a v<version>/ or latest/.
9
+ # A repo's first genuine release always resolves to v0.0.1 regardless of
10
+ # package.json's version, so "Use this template" (whose initial push to
11
+ # main by GitHub's web-flow bot fires this workflow) publishes a clean
12
+ # v0.0.1 + /latest/ + root right away, discarding any inherited canary
13
+ # version. On that same first release, the "Reset repo to a clean
14
+ # first-release state" step below rewrites package.json's version back to
15
+ # 0.0.1 in the repo itself, so the *next* release bumps to 0.0.2 rather
16
+ # than the inherited number.
23
17
  # - push to dev -> dev channel: mutable /<repo>/dev/
24
18
  # with version.json + a self-reload snippet, for live review inside Grist.
25
19
  #
@@ -106,8 +100,7 @@ jobs:
106
100
  --site site --repo "$REPO_NAME" \
107
101
  --event "${{ github.event_name }}" \
108
102
  --ref "${{ github.ref }}" \
109
- ${{ github.event.inputs.force == 'true' && '--force' || '' }} \
110
- ${{ github.event.created == true && github.event.head_commit.committer.email == 'noreply@github.com' && '--created' || '' }})
103
+ ${{ github.event.inputs.force == 'true' && '--force' || '' }})
111
104
  echo "Plan: $PLAN"
112
105
  node -e '
113
106
  const p = JSON.parse(process.argv[1]);
@@ -115,17 +108,13 @@ jobs:
115
108
  const out = process.env.GITHUB_OUTPUT;
116
109
  fs.appendFileSync(out, `context=${p.context}\n`);
117
110
  fs.appendFileSync(out, `skip=${p.skip ? "true" : "false"}\n`);
118
- fs.appendFileSync(out, `reason=${p.reason || ""}\n`);
119
111
  fs.appendFileSync(out, `version=${p.version || ""}\n`);
120
112
  fs.appendFileSync(out, `base=${p.base}\n`);
121
113
  fs.appendFileSync(out, `firstRelease=${p.firstRelease ? "true" : "false"}\n`);
122
114
  ' "$PLAN"
123
115
 
124
- # Also builds on the ref-created push (skip == 'true' there), but with
125
- # the root base plan() hands back for that case (/<repo>/, not a
126
- # versioned path) -- see the "landing hub" step below.
127
116
  - name: Build
128
- if: steps.plan.outputs.skip != 'true' || steps.plan.outputs.reason == 'ref-created'
117
+ if: steps.plan.outputs.skip != 'true'
129
118
  run: |
130
119
  pnpm exec tsc -b
131
120
  pnpm exec vite build --base "${{ steps.plan.outputs.base }}"
@@ -143,28 +132,9 @@ jobs:
143
132
  --sha "$SHA" --ref "${{ github.ref }}"
144
133
 
145
134
  - name: Skip (already published)
146
- if: steps.plan.outputs.skip == 'true' && steps.plan.outputs.reason != 'ref-created'
135
+ if: steps.plan.outputs.skip == 'true'
147
136
  run: echo "== skip — v${{ steps.plan.outputs.version }} already published"
148
137
 
149
- # The ref-created "Use this template" push publishes no versioned
150
- # release (that would spend the first-release override on unmodified
151
- # boilerplate -- see plan()), so it never reaches Place. But it still:
152
- # 1. clears any foreign content the copy brought along
153
- # (cleanupForeignVersionsIfFirstRelease, normally a side effect of
154
- # Place) -- stray v<version>/ dirs, a root/latest/ pointing at the
155
- # source repo's own path; then
156
- # 2. places the freshly built showcase hub at the site root, so
157
- # https://owner.github.io/<repo>/ isn't a bare 404 until the
158
- # widget's first real release (the CLI path gets a working root on
159
- # its own genuine first push; this makes the template-copy path
160
- # match). No v<version>/ or latest/ -- those stay absent, correctly
161
- # 404ing, until a real release exists.
162
- - name: Clean foreign content + place landing hub (ref-created push)
163
- if: steps.plan.outputs.reason == 'ref-created'
164
- run: |
165
- node scripts/deploy.mjs cleanup-foreign --site site --repo "$REPO_NAME"
166
- node scripts/deploy.mjs place-root --site site --dist dist
167
-
168
138
  - name: Finalize (versions.json + commit + push)
169
139
  run: |
170
140
  UPDATE_VERSIONS=""
@@ -175,15 +145,18 @@ jobs:
175
145
  --site site --repo "$REPO_NAME" $UPDATE_VERSIONS --push \
176
146
  --commit-message "deploy: ${{ steps.plan.outputs.context }} @ ${{ github.sha }}"
177
147
 
178
- # On this repo's first genuine release only: prune every branch except
179
- # main/dev/gh-pages, and reset dev to main's current tip. Establishes
180
- # the schema every widget should start from (main == dev, gh-pages is
181
- # CI-managed only) regardless of how the repo was created -- a CLI
182
- # scaffold already satisfies this trivially; a repo copied via GitHub's
183
- # "Use this template" often doesn't (a stray inherited branch, or dev
184
- # tracking the source template's own unrelated preview history).
148
+ # On this repo's first genuine release only: reset package.json's version
149
+ # to 0.0.1 (so the next release bumps to 0.0.2 rather than any inherited
150
+ # canary version), prune every branch except main/dev/gh-pages, and
151
+ # reset dev to main's current tip. Establishes the state every widget
152
+ # should start from regardless of how the repo was created -- a CLI
153
+ # scaffold already satisfies it trivially; a repo copied via GitHub's
154
+ # "Use this template" often doesn't (an inherited version, a stray
155
+ # branch, or dev tracking the source template's own preview history).
185
156
  # Placed after Finalize so it never runs if the release itself failed.
186
- - name: Reset branches on first genuine release
157
+ # The version-reset commit re-triggers this workflow on main, but that
158
+ # run sees v0.0.1 already published (firstRelease=false) and no-ops.
159
+ - name: Reset repo to a clean first-release state
187
160
  if: steps.plan.outputs.context == 'release' && steps.plan.outputs.firstRelease == 'true'
188
161
  run: node scripts/deploy.mjs reset-branches
189
162
 
@@ -0,0 +1 @@
1
+ # grist-widget-template-vite
@@ -90,42 +90,32 @@ automatically.
90
90
  > grist-widget`?** That path copies this repo's default branch verbatim —
91
91
  > it doesn't run any of the CLI's own setup (renaming `package.json`,
92
92
  > titles, etc.), and whatever version happens to be checked into the
93
- > source repo's `package.json` (which can be well past `0.0.1` — see below)
94
- > comes along with it. You don't need to reset it by hand: your first real
93
+ > source repo's `package.json` (which can be well past `0.0.1`) comes along
94
+ > with it. **The moment the repo is created, GitHub's own initial push to
95
+ > `main` fires this workflow and publishes a clean `v0.0.1`** — your first
95
96
  > release always resolves to `v0.0.1` regardless of what `package.json`
96
- > says, and that value stays untouched in the file — only the deploy
97
- > pipeline's own idea of "which version is this" is overridden, once, for
98
- > that first release. If you also checked **"Include all branches"** (to
99
- > get `gh-pages`/Pages already set up, no manual Settings step), your first
100
- > real release also automatically clears out every leftover `v<version>/`
101
- > it finds — a `v<version>/` only counts as a genuine prior release once it
102
- > carries a `showcase-meta.json` naming *this* repo (written by this
103
- > pipeline's own `place` step), so on a repo with no genuine releases yet,
104
- > everything else is provably inherited noise and gets safely wiped on your
105
- > first push to `main`. Also on that same first release, every branch
106
- > except `main`, `dev`, and `gh-pages` gets pruned, and `dev` gets
107
- > force-reset to match `main`'s tip — a fresh widget always starts from
108
- > `main == dev`, regardless of whether it came from the CLI (already true)
109
- > or a template copy (may have inherited a stray branch, or a `dev` full of
110
- > the source template's own unrelated preview history). All three of these
111
- > only ever apply before your *first* genuine release — once one exists,
112
- > they're permanently a no-op, so it's still safest to never manually
113
- > re-seed `gh-pages` again after that point.
114
- >
115
- > "Use this template" also immediately fires this workflow once on its own,
116
- > the moment the repo is created — before you've cloned it, let alone
117
- > changed anything. That run is recognized (GitHub's own web-flow bot
118
- > creating the `main` ref) and **publishes no versioned release**: it
119
- > doesn't count as your first release, so the `0.0.1` override above still
120
- > applies in full once you actually push real changes. It does two useful
121
- > things, though: if you checked "Include all branches", it clears out
122
- > whatever foreign content came along (stray `v<version>/` dirs, a
123
- > root/`latest/` still pointing at the *source* repo's own path); and it
124
- > places the landing page at your repo-root URL so
125
- > `https://<you>.github.io/<repo>/` works right away, instead of 404ing
126
- > until your first real release. Your `/latest/` and `/v<version>/` URLs
127
- > stay absent (they 404) until you actually publish — there's no release to
128
- > point them at yet.
97
+ > says, so `/`, `/latest/`, and `/v0.0.1/` all go live right away (once
98
+ > you've done the one-time Pages setup below). You don't reset the version
99
+ > by hand: on that first release the pipeline also **rewrites
100
+ > `package.json`'s version back to `0.0.1` in the repo itself** (a commit it
101
+ > pushes to `main`/`dev`), so your *next* release naturally bumps to
102
+ > `0.0.2` instead of jumping to whatever inherited number you started with.
103
+ > If you also checked **"Include all branches"** (to get `gh-pages`/Pages
104
+ > already set up, no manual Settings step), that first release also clears
105
+ > out every leftover bit of inherited content it finds — stray
106
+ > `v<version>/` dirs, and a root/`latest/` still pointing at the *source*
107
+ > repo's own path — before writing its own. A `v<version>/` only counts as
108
+ > a genuine prior release once it carries a `showcase-meta.json` naming
109
+ > *this* repo, so on a repo with no genuine releases yet, everything else is
110
+ > provably inherited noise and gets safely replaced. On that same first
111
+ > release, every branch except `main`, `dev`, and `gh-pages` is pruned and
112
+ > `dev` is force-reset to match `main`'s tip — a fresh widget always starts
113
+ > from `main == dev`, whether it came from the CLI (already true) or a
114
+ > template copy (may have inherited a stray branch, or a `dev` full of the
115
+ > source template's own unrelated preview history). All of this only ever
116
+ > applies before your *first* genuine release — once one exists, it's
117
+ > permanently a no-op, so it's still safest to never manually re-seed
118
+ > `gh-pages` again after that point.
129
119
 
130
120
  **One-time setup** (the workflow can't do this part for you):
131
121
 
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@fontsource-variable/geist": "^5.2.8",
16
- "grist-widget-sdk": "^0.2.15",
16
+ "grist-widget-sdk": "^0.3.0",
17
17
  "@tailwindcss/vite": "^4.2.1",
18
18
  "class-variance-authority": "^0.7.1",
19
19
  "clsx": "^2.1.1",
@@ -19,33 +19,18 @@
19
19
  //
20
20
  // Subcommands:
21
21
  // plan --site <dir> --repo <name> --event <push|workflow_dispatch>
22
- // --ref <ref> [--force] [--created]
22
+ // --ref <ref> [--force]
23
23
  // Prints JSON { context: "release"|"dev", version?, base, skip }.
24
24
  // Release is skipped when v<version> already exists on gh-pages
25
25
  // (idempotence: re-pushing main without a version bump is a no-op).
26
- // --created additionally skips unconditionally, without consuming the
27
- // first-release version override -- see plan()'s own comment. Callers
28
- // must only pass --created for GitHub's own server-side "Use this
29
- // template" push, never a real user push that merely happens to create
30
- // a ref for the first time (e.g. a CLI scaffold's first `git push -u
31
- // origin main`) -- see deploy.yml's wiring for the distinguishing check.
26
+ // A repo's first genuine release always resolves to v0.0.1 regardless of
27
+ // package.json's version -- so "Use this template" (whose initial push
28
+ // to main fires this workflow) publishes a clean v0.0.1 straight away.
32
29
  //
33
30
  // place --site <dir> --repo <name> --channel <release|dev>
34
31
  // [--version <v>] --dist <dir> --sha <sha> [--ref <ref>]
35
32
  // Copies a freshly built dist into the gh-pages tree.
36
33
  //
37
- // cleanup-foreign --site <dir> --repo <name>
38
- // Standalone entry point for `cleanupForeignVersionsIfFirstRelease` --
39
- // used on a skipped ref-created push (see `plan`), which never reaches
40
- // `place` (the only other caller of this cleanup) so foreign content
41
- // from "Use this template" would otherwise sit untouched indefinitely.
42
- //
43
- // place-root --site <dir> --dist <dir>
44
- // Place a root-based build (built with base "/<repo>/") at the site
45
- // root only -- the showcase hub landing page. Used on the ref-created
46
- // push so the bare repo-root URL works before the first real release,
47
- // without publishing a versioned release. Run after `cleanup-foreign`.
48
- //
49
34
  // remove --site <dir>
50
35
  // Removes dev/ from the gh-pages tree (retire the dev URL when the `dev`
51
36
  // branch is deleted). Never touches a release or latest/.
@@ -56,7 +41,8 @@
56
41
  //
57
42
  // reset-branches [--repo-dir <dir>]
58
43
  // On a repo's first genuine release only (caller gates on plan()'s
59
- // firstRelease): prunes every branch except main/dev/gh-pages and
44
+ // firstRelease): resets package.json's version to 0.0.1, prunes every
45
+ // branch except main/dev/gh-pages, and
60
46
  // force-resets dev to main's current tip.
61
47
 
62
48
  import {
@@ -119,7 +105,7 @@ function hasGenuineRelease(siteDir, repo) {
119
105
  * genuinely published by this repo before (unless force), so re-pushing main
120
106
  * without a version bump is a no-op.
121
107
  */
122
- export function plan(siteDir, repo, event, ref, { force = false, created = false } = {}) {
108
+ export function plan(siteDir, repo, event, ref, { force = false } = {}) {
123
109
  const isRelease = event === "workflow_dispatch" || ref === "refs/heads/main" || ref === "main"
124
110
  if (!isRelease) {
125
111
  return { context: "dev", base: basePathFor(repo, "dev") }
@@ -129,46 +115,20 @@ export function plan(siteDir, repo, event, ref, { force = false, created = false
129
115
  // whatever package.json's version field says -- found live: a repo copied
130
116
  // via GitHub's "Use this template" inherited "0.2.18" from the source
131
117
  // template repo's own main branch (itself a canary-stamped scaffold that
132
- // had been promoted there), instead of starting fresh. Once a repo has a
133
- // genuine release, this no longer applies -- its own version bumps are
134
- // its own responsibility from then on, same as `cleanupForeignVersionsIfFirstRelease`.
118
+ // had been promoted there), instead of starting fresh. This is what makes
119
+ // "Use this template" publish a clean v0.0.1 the moment the repo is
120
+ // created (GitHub's own initial push to main fires this workflow): the
121
+ // copy's inherited canary version is ignored for that first release. To
122
+ // keep the *next* release clean too, the workflow's first-release reset
123
+ // step rewrites package.json's version back to 0.0.1 in the repo itself
124
+ // (see `resetBranchesIfFirstRelease`), so the second release naturally
125
+ // bumps from 0.0.1 rather than the inherited canary number. Once a repo
126
+ // has a genuine release, this override no longer applies -- its own
127
+ // version bumps are its own responsibility from then on.
135
128
  const firstRelease = !hasGenuineRelease(siteDir, repo)
136
129
  const version = firstRelease ? "0.0.1" : pkg.version
137
130
  if (!version) throw new Error("package.json has no version")
138
131
  const versionDir = join(siteDir, `v${version}`)
139
- // GitHub's "Use this template" copies the source repo's main branch onto a
140
- // brand-new ref, which fires this same push-to-main event itself --
141
- // before anyone has done any real work. Without this check, that event
142
- // would consume the first-release override above on whatever unmodified
143
- // boilerplate happens to be checked in, so the widget's *actual* first
144
- // release (once someone merges real content) no longer counts as
145
- // firstRelease and publishes under that boilerplate's version verbatim
146
- // instead of a clean 0.0.1 -- found live (a monorepo widget moved into its
147
- // own repo this way published its real first release as "v0.2.21").
148
- // Skipping this event entirely (never placing anything, never touching
149
- // gh-pages) keeps hasGenuineRelease() false, so the override survives
150
- // intact for whenever a real release actually happens.
151
- if (created && event === "push") {
152
- // Publish no versioned release (so the first-release override above
153
- // survives), but the caller still builds + places the showcase hub at
154
- // the site root -- otherwise https://owner.github.io/<repo>/ is a bare
155
- // 404 until the widget's first real release (found live on a fresh "Use
156
- // this template" copy). The hub renders for any URL with no channel
157
- // suffix, the bare root included (see main.tsx), so it must be built
158
- // based at the repo root (/<repo>/), not a versioned path -- hence the
159
- // root base here rather than basePathFor's v<version>/. The workflow
160
- // keys off reason === "ref-created" to build with this base and place
161
- // root-only. `skip` stays true so the normal versioned place/finalize
162
- // path is bypassed.
163
- return {
164
- context: "release",
165
- version,
166
- base: `/${repo}/`,
167
- skip: true,
168
- reason: "ref-created",
169
- firstRelease,
170
- }
171
- }
172
132
  const exists = isGenuineRelease(versionDir, repo)
173
133
  return {
174
134
  context: "release",
@@ -271,11 +231,11 @@ function replaceDir(dest, srcDist) {
271
231
  * template" -> "Include all branches"): stray `v<version>/` directories,
272
232
  * but also a root `index.html`/`latest/` still referencing the *source*
273
233
  * repo's own base path (found live: a fresh copy's root and `latest/`
274
- * pointed at `/grist-widget-template/v0.2.22/assets/...`, 404ing on this
275
- * repo's own Pages site -- a blank page -- because the ref-created push
276
- * that used to overwrite them with this repo's own build is now skipped
277
- * entirely, see `plan()`). Safe to clear unconditionally: a repo with zero
278
- * genuine releases can't have any of its own history to lose. Once a
234
+ * pointed at `/grist-widget-template/v0.2.22/assets/...`, which 404s on
235
+ * this repo's own Pages site). Called by `placeTarget` right before it
236
+ * writes this repo's own first release, so the inherited noise is replaced
237
+ * rather than layered under. Safe to clear unconditionally: a repo with
238
+ * zero genuine releases can't have any of its own history to lose. Once a
279
239
  * genuine release exists for this repo, buildVersionsManifest is non-empty
280
240
  * and this is permanently a no-op.
281
241
  */
@@ -330,27 +290,6 @@ export function placeTarget({ siteDir, channel, version, distDir, sha, ref, repo
330
290
  return { placed: `v${version}`, latest: "latest", root: true }
331
291
  }
332
292
 
333
- /**
334
- * Place a root-based build (built with base "/<repo>/") at the gh-pages site
335
- * root only -- the showcase hub landing page, nothing else. Used on the
336
- * ref-created "Use this template" push (see plan()): publishes no versioned
337
- * release, so the first-release override survives, but keeps the bare
338
- * repo-root URL from 404ing until that first real release (found live: a
339
- * fresh copy's https://owner.github.io/<repo>/ was a 404, since the initial
340
- * deploy that used to place this hub now publishes nothing). Never creates a
341
- * v<version>/ or latest/. On the first genuine release, placeTarget's own
342
- * cleanupForeignVersionsIfFirstRelease clears this hub (root index.html +
343
- * assets/) before placing the release's own root copy, so nothing lingers.
344
- * Callers run `cleanup-foreign` first, so a re-triggered ref-created run
345
- * replaces the hub cleanly rather than layering onto stale files.
346
- */
347
- export function placeRootHub({ siteDir, distDir }) {
348
- if (!existsSync(distDir)) throw new Error(`dist not found: ${distDir}`)
349
- mkdirSync(siteDir, { recursive: true })
350
- cpSync(distDir, siteDir, { recursive: true })
351
- return { placed: "root" }
352
- }
353
-
354
293
  /**
355
294
  * Remove the mutable dev dir from the gh-pages tree (retire the dev URL when
356
295
  * the `dev` branch is deleted). Only ever touches `dev/` — never a versioned
@@ -410,19 +349,50 @@ export function finalize({ siteDir, updateVersions, push, commitMessage, remoteB
410
349
  }
411
350
 
412
351
  /**
413
- * Establish the schema every widget repo should start from -- `main` and
414
- * `dev` identical, `gh-pages` managed by CI only -- by pruning every other
415
- * branch and force-resetting `dev` to `main`'s current tip (the commit
416
- * already checked out at `repoDir`). Runs once, gated by the caller on
417
- * `plan()`'s `firstRelease` flag, so it applies equally to a CLI scaffold
418
- * (already satisfies this trivially -- nothing to prune, dev already equals
419
- * main) and a repo copied via GitHub's "Use this template" (may have a
420
- * stray inherited branch, or `dev` tracking the source template's own
421
- * unrelated preview history). Operates on `repoDir`, the repo's own
422
- * checkout -- a different directory than the gh-pages `siteDir` every other
423
- * function here works with.
352
+ * Establish the state every widget repo should start from, on its first
353
+ * genuine release only (gated by the caller on `plan()`'s `firstRelease`):
354
+ *
355
+ * 1. Reset package.json's version to 0.0.1. The first release already
356
+ * published v0.0.1 (forced by plan() regardless of package.json), but a
357
+ * repo copied via GitHub's "Use this template" still carries the source
358
+ * template's inherited canary version in the file (found live: a copy
359
+ * shipped 0.2.23) -- so its *next* release would jump straight to
360
+ * v0.2.24 instead of a clean v0.0.2. Rewriting the file to 0.0.1 here,
361
+ * committed to main, makes the next bump land on 0.0.2. A CLI scaffold
362
+ * already ships 0.0.1, so this is a no-op there.
363
+ * 2. main == dev, gh-pages CI-managed only: prune every other branch and
364
+ * force-reset `dev` to `main`'s current tip (which now carries the
365
+ * version-reset commit). A CLI scaffold satisfies this trivially; a
366
+ * "Use this template" copy may have a stray inherited branch, or a
367
+ * `dev` tracking the source template's own unrelated preview history.
368
+ *
369
+ * Operates on `repoDir`, the repo's own checkout -- a different directory
370
+ * than the gh-pages `siteDir` every other function here works with. The
371
+ * version-reset commit re-triggers this workflow on main, but that run sees
372
+ * a genuine release already published (firstRelease=false) and skips both
373
+ * the release and this reset, so there's no loop.
424
374
  */
425
375
  export function resetBranchesIfFirstRelease(repoDir, keep = ["main", "dev", "gh-pages"]) {
376
+ let versionReset = false
377
+ const pkgPath = join(repoDir, "package.json")
378
+ if (existsSync(pkgPath)) {
379
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"))
380
+ if (pkg.version !== "0.0.1") {
381
+ pkg.version = "0.0.1"
382
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n")
383
+ git(["add", "package.json"], repoDir)
384
+ git(
385
+ [
386
+ "-c", "user.name=github-actions[bot]",
387
+ "-c", "user.email=41898282+github-actions[bot]@users.noreply.github.com",
388
+ "commit", "-m", "chore: reset version to 0.0.1 for a clean first release",
389
+ ],
390
+ repoDir,
391
+ )
392
+ git(["push", "origin", "HEAD:refs/heads/main"], repoDir)
393
+ versionReset = true
394
+ }
395
+ }
426
396
  const raw = git(["ls-remote", "--heads", "origin"], repoDir)
427
397
  const branches = raw
428
398
  ? raw.split("\n").map((line) => line.split("refs/heads/")[1]).filter(Boolean)
@@ -434,7 +404,7 @@ export function resetBranchesIfFirstRelease(repoDir, keep = ["main", "dev", "gh-
434
404
  deletedBranches.push(b)
435
405
  }
436
406
  git(["push", "--force", "origin", "HEAD:refs/heads/dev"], repoDir)
437
- return { deletedBranches, devReset: true }
407
+ return { deletedBranches, devReset: true, versionReset }
438
408
  }
439
409
 
440
410
  // ----------------------------------------------------------------------------
@@ -463,7 +433,6 @@ function main() {
463
433
  case "plan": {
464
434
  const result = plan(args.site, args.repo, args.event, args.ref, {
465
435
  force: !!args.force,
466
- created: !!args.created,
467
436
  })
468
437
  process.stdout.write(JSON.stringify(result))
469
438
  break
@@ -486,16 +455,6 @@ function main() {
486
455
  console.log("remove:", JSON.stringify(res))
487
456
  break
488
457
  }
489
- case "cleanup-foreign": {
490
- const res = cleanupForeignVersionsIfFirstRelease(args.site, args.repo)
491
- console.log("cleanup-foreign:", JSON.stringify(res))
492
- break
493
- }
494
- case "place-root": {
495
- const res = placeRootHub({ siteDir: args.site, distDir: args.dist })
496
- console.log("place-root:", JSON.stringify(res))
497
- break
498
- }
499
458
  case "finalize": {
500
459
  const res = finalize({
501
460
  siteDir: args.site,