create-grist-widget 0.3.6 → 0.3.7
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
|
@@ -12,8 +12,12 @@ name: Deploy widget to GitHub Pages
|
|
|
12
12
|
# v0.0.1 + /latest/ + root right away, discarding any inherited canary
|
|
13
13
|
# version. On that same first release, the "Reset repo to a clean
|
|
14
14
|
# first-release state" step below rewrites package.json's version back to
|
|
15
|
-
# 0.0.1 in the repo itself
|
|
16
|
-
# than the inherited number
|
|
15
|
+
# 0.0.1 in the repo itself (so the *next* release bumps to 0.0.2 rather
|
|
16
|
+
# than the inherited number) and, since "Use this template" never runs
|
|
17
|
+
# the CLI's own rename step, also personalizes the four placeholder-
|
|
18
|
+
# identity spots (package.json's name, README.md's heading, index.html's
|
|
19
|
+
# <title>, App.tsx's title) to match this repo's real name -- a no-op
|
|
20
|
+
# wherever that placeholder text is already gone.
|
|
17
21
|
# - push to dev -> dev channel: mutable /<repo>/dev/
|
|
18
22
|
# with version.json + a self-reload snippet, for live review inside Grist.
|
|
19
23
|
#
|
|
@@ -158,7 +162,7 @@ jobs:
|
|
|
158
162
|
# run sees v0.0.1 already published (firstRelease=false) and no-ops.
|
|
159
163
|
- name: Reset repo to a clean first-release state
|
|
160
164
|
if: steps.plan.outputs.context == 'release' && steps.plan.outputs.firstRelease == 'true'
|
|
161
|
-
run: node scripts/deploy.mjs reset-branches
|
|
165
|
+
run: node scripts/deploy.mjs reset-branches --repo "$REPO_NAME"
|
|
162
166
|
|
|
163
167
|
cleanup:
|
|
164
168
|
# When the `dev` branch is deleted, remove /dev/ so the dev URL retires
|
package/template/README.md
CHANGED
|
@@ -40,8 +40,9 @@ This template has no live-preview deploy of its own inside this monorepo —
|
|
|
40
40
|
that used to exist (a `/template/` showcase on this repo's own GitHub
|
|
41
41
|
Pages) but has been retired. The only live preview of this template's
|
|
42
42
|
current source is external: `template-canary.yml` scaffolds it via the
|
|
43
|
-
*published* `create-grist-widget` package and pushes to the `dev`
|
|
44
|
-
`
|
|
43
|
+
*published* `create-grist-widget` package and pushes to the `dev` branch
|
|
44
|
+
(pre-release preview) and directly to `main` (stable `@latest`, promotion is
|
|
45
|
+
automatic) of
|
|
45
46
|
[`grist-widget-template`](https://github.com/ArthurBlanchon/grist-widget-template)
|
|
46
47
|
after every release — see https://gristwidgets.com/docs/contributing/releasing for the full
|
|
47
48
|
mechanism. There is no live preview of *unreleased* changes to this
|
|
@@ -39,11 +39,13 @@
|
|
|
39
39
|
// Regenerates versions.json (release runs only) and commits + pushes the
|
|
40
40
|
// gh-pages tree with a rebase-and-retry loop.
|
|
41
41
|
//
|
|
42
|
-
// reset-branches [--repo-dir <dir>]
|
|
42
|
+
// reset-branches [--repo-dir <dir>] [--repo <name>]
|
|
43
43
|
// On a repo's first genuine release only (caller gates on plan()'s
|
|
44
|
-
// firstRelease):
|
|
45
|
-
//
|
|
46
|
-
//
|
|
44
|
+
// firstRelease): renames the four placeholder-identity spots (only if
|
|
45
|
+
// --repo is given and they still carry the template's own placeholder
|
|
46
|
+
// text -- a no-op for a CLI scaffold that already renamed itself), resets
|
|
47
|
+
// package.json's version to 0.0.1, prunes every branch except
|
|
48
|
+
// main/dev/gh-pages, and force-resets dev to main's current tip.
|
|
47
49
|
|
|
48
50
|
import {
|
|
49
51
|
existsSync,
|
|
@@ -348,10 +350,56 @@ export function finalize({ siteDir, updateVersions, push, commitMessage, remoteB
|
|
|
348
350
|
throw lastErr
|
|
349
351
|
}
|
|
350
352
|
|
|
353
|
+
/**
|
|
354
|
+
* Derive an npm-safe package name and a human title from a real GitHub repo
|
|
355
|
+
* name -- which allows characters (uppercase, underscores, periods) npm
|
|
356
|
+
* package names don't. Mirrors the title-casing
|
|
357
|
+
* `packages/create-grist-widget/bin/create-grist-widget.mjs` already applies
|
|
358
|
+
* to its own CLI-provided `rawName`, so a repo named e.g. `Ask-Genial_Widget`
|
|
359
|
+
* produces the same shape of package name / title a CLI user typing
|
|
360
|
+
* `ask-genial-widget` would have gotten.
|
|
361
|
+
*/
|
|
362
|
+
export function deriveIdentity(repoName) {
|
|
363
|
+
const packageName =
|
|
364
|
+
(repoName || "")
|
|
365
|
+
.toLowerCase()
|
|
366
|
+
.replace(/[^a-z0-9-]+/g, "-")
|
|
367
|
+
.replace(/^-+|-+$/g, "") || "grist-widget"
|
|
368
|
+
const title = packageName
|
|
369
|
+
.split("-")
|
|
370
|
+
.filter(Boolean)
|
|
371
|
+
.map((w) => w[0].toUpperCase() + w.slice(1))
|
|
372
|
+
.join(" ")
|
|
373
|
+
return { packageName, title }
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* The same four placeholder-identity edits
|
|
378
|
+
* `packages/create-grist-widget/bin/create-grist-widget.mjs` applies at
|
|
379
|
+
* scaffold time, parameterized by a derived identity instead of CLI input.
|
|
380
|
+
* Each substitution is a plain string replace, so it's naturally a no-op
|
|
381
|
+
* wherever the placeholder text is already gone -- a CLI-scaffolded repo
|
|
382
|
+
* (whose name may legitimately differ from its GitHub repo name) is never
|
|
383
|
+
* touched by this.
|
|
384
|
+
*/
|
|
385
|
+
function identityEdits({ packageName, title }) {
|
|
386
|
+
return [
|
|
387
|
+
["package.json", [["grist-widget-template-vite", packageName]]],
|
|
388
|
+
["README.md", [["grist-widget-template-vite", packageName]]],
|
|
389
|
+
["index.html", [["<title>Grist Widget</title>", `<title>${title}</title>`]]],
|
|
390
|
+
["src/App.tsx", [['title: "Grist Widget Template",', `title: "${title}",`]]],
|
|
391
|
+
]
|
|
392
|
+
}
|
|
393
|
+
|
|
351
394
|
/**
|
|
352
395
|
* Establish the state every widget repo should start from, on its first
|
|
353
396
|
* genuine release only (gated by the caller on `plan()`'s `firstRelease`):
|
|
354
397
|
*
|
|
398
|
+
* 0. If `repo` is given, rewrite the four placeholder-identity spots (see
|
|
399
|
+
* `identityEdits`) to match the real repo name -- the piece "Use this
|
|
400
|
+
* template" skips entirely, since it copies the repo verbatim and never
|
|
401
|
+
* runs the CLI's own rename step. Folded into the same commit as the
|
|
402
|
+
* version reset below, not a separate one.
|
|
355
403
|
* 1. Reset package.json's version to 0.0.1. The first release already
|
|
356
404
|
* published v0.0.1 (forced by plan() regardless of package.json), but a
|
|
357
405
|
* repo copied via GitHub's "Use this template" still carries the source
|
|
@@ -372,27 +420,55 @@ export function finalize({ siteDir, updateVersions, push, commitMessage, remoteB
|
|
|
372
420
|
* a genuine release already published (firstRelease=false) and skips both
|
|
373
421
|
* the release and this reset, so there's no loop.
|
|
374
422
|
*/
|
|
375
|
-
export function resetBranchesIfFirstRelease(repoDir, keep = ["main", "dev", "gh-pages"]) {
|
|
423
|
+
export function resetBranchesIfFirstRelease(repoDir, repo, keep = ["main", "dev", "gh-pages"]) {
|
|
424
|
+
const changedFiles = new Set()
|
|
425
|
+
const renamedFiles = []
|
|
426
|
+
|
|
427
|
+
if (repo) {
|
|
428
|
+
for (const [file, subs] of identityEdits(deriveIdentity(repo))) {
|
|
429
|
+
const p = join(repoDir, file)
|
|
430
|
+
if (!existsSync(p)) continue
|
|
431
|
+
const before = readFileSync(p, "utf8")
|
|
432
|
+
const after = subs.reduce((text, [search, replace]) => text.split(search).join(replace), before)
|
|
433
|
+
if (after !== before) {
|
|
434
|
+
writeFileSync(p, after)
|
|
435
|
+
changedFiles.add(file)
|
|
436
|
+
renamedFiles.push(file)
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const identityReset = renamedFiles.length > 0
|
|
441
|
+
|
|
376
442
|
let versionReset = false
|
|
377
443
|
const pkgPath = join(repoDir, "package.json")
|
|
378
444
|
if (existsSync(pkgPath)) {
|
|
445
|
+
// Re-read after any identity edit above, so a rewritten `name` survives
|
|
446
|
+
// this JSON round-trip instead of being clobbered by it.
|
|
379
447
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"))
|
|
380
448
|
if (pkg.version !== "0.0.1") {
|
|
381
449
|
pkg.version = "0.0.1"
|
|
382
450
|
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n")
|
|
383
|
-
|
|
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)
|
|
451
|
+
changedFiles.add("package.json")
|
|
393
452
|
versionReset = true
|
|
394
453
|
}
|
|
395
454
|
}
|
|
455
|
+
|
|
456
|
+
if (changedFiles.size > 0) {
|
|
457
|
+
const parts = []
|
|
458
|
+
if (identityReset) parts.push("personalize scaffold")
|
|
459
|
+
if (versionReset) parts.push("reset version to 0.0.1")
|
|
460
|
+
git(["add", ...changedFiles], repoDir)
|
|
461
|
+
git(
|
|
462
|
+
[
|
|
463
|
+
"-c", "user.name=github-actions[bot]",
|
|
464
|
+
"-c", "user.email=41898282+github-actions[bot]@users.noreply.github.com",
|
|
465
|
+
"commit", "-m", `chore: ${parts.join(" + ")} for a clean first release`,
|
|
466
|
+
],
|
|
467
|
+
repoDir,
|
|
468
|
+
)
|
|
469
|
+
git(["push", "origin", "HEAD:refs/heads/main"], repoDir)
|
|
470
|
+
}
|
|
471
|
+
|
|
396
472
|
const raw = git(["ls-remote", "--heads", "origin"], repoDir)
|
|
397
473
|
const branches = raw
|
|
398
474
|
? raw.split("\n").map((line) => line.split("refs/heads/")[1]).filter(Boolean)
|
|
@@ -404,7 +480,7 @@ export function resetBranchesIfFirstRelease(repoDir, keep = ["main", "dev", "gh-
|
|
|
404
480
|
deletedBranches.push(b)
|
|
405
481
|
}
|
|
406
482
|
git(["push", "--force", "origin", "HEAD:refs/heads/dev"], repoDir)
|
|
407
|
-
return { deletedBranches, devReset: true, versionReset }
|
|
483
|
+
return { deletedBranches, devReset: true, versionReset, identityReset, renamedFiles }
|
|
408
484
|
}
|
|
409
485
|
|
|
410
486
|
// ----------------------------------------------------------------------------
|
|
@@ -467,7 +543,7 @@ function main() {
|
|
|
467
543
|
break
|
|
468
544
|
}
|
|
469
545
|
case "reset-branches": {
|
|
470
|
-
const res = resetBranchesIfFirstRelease(args["repo-dir"] || ".")
|
|
546
|
+
const res = resetBranchesIfFirstRelease(args["repo-dir"] || ".", args.repo)
|
|
471
547
|
console.log("reset-branches:", JSON.stringify(res))
|
|
472
548
|
break
|
|
473
549
|
}
|