create-grist-widget 0.2.13 → 0.2.14
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
|
@@ -125,10 +125,14 @@ jobs:
|
|
|
125
125
|
if: steps.plan.outputs.skip == 'true'
|
|
126
126
|
run: echo "== skip — v${{ steps.plan.outputs.version }} already published"
|
|
127
127
|
|
|
128
|
-
- name: Finalize (commit + push)
|
|
128
|
+
- name: Finalize (versions.json + commit + push)
|
|
129
129
|
run: |
|
|
130
|
+
UPDATE_VERSIONS=""
|
|
131
|
+
if [ "${{ steps.plan.outputs.context }}" = "release" ]; then
|
|
132
|
+
UPDATE_VERSIONS="--update-versions"
|
|
133
|
+
fi
|
|
130
134
|
node scripts/deploy.mjs finalize \
|
|
131
|
-
--site site --push \
|
|
135
|
+
--site site $UPDATE_VERSIONS --push \
|
|
132
136
|
--commit-message "deploy: ${{ steps.plan.outputs.context }} @ ${{ github.sha }}"
|
|
133
137
|
|
|
134
138
|
cleanup:
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
// release (push to main / workflow_dispatch)
|
|
9
9
|
// - immutable /<repo>/v<version>/ (built once, never overwritten)
|
|
10
10
|
// - mutable /<repo>/latest/ (alias to newest release)
|
|
11
|
+
// - /<repo>/versions.json (released-version index, newest first
|
|
12
|
+
// -- read by the showcase hub/notice)
|
|
11
13
|
//
|
|
12
14
|
// dev (push to dev)
|
|
13
15
|
// - mutable /<repo>/dev/ (+ version.json + self-reload)
|
|
@@ -30,10 +32,19 @@
|
|
|
30
32
|
// Removes dev/ from the gh-pages tree (retire the dev URL when the `dev`
|
|
31
33
|
// branch is deleted). Never touches a release or latest/.
|
|
32
34
|
//
|
|
33
|
-
// finalize --site <dir> [--push] [--commit-message <msg>]
|
|
34
|
-
//
|
|
35
|
+
// finalize --site <dir> [--update-versions] [--push] [--commit-message <msg>]
|
|
36
|
+
// Regenerates versions.json (release runs only) and commits + pushes the
|
|
37
|
+
// gh-pages tree with a rebase-and-retry loop.
|
|
35
38
|
|
|
36
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
existsSync,
|
|
41
|
+
readFileSync,
|
|
42
|
+
readdirSync,
|
|
43
|
+
writeFileSync,
|
|
44
|
+
rmSync,
|
|
45
|
+
mkdirSync,
|
|
46
|
+
cpSync,
|
|
47
|
+
} from "node:fs"
|
|
37
48
|
import { join, dirname } from "node:path"
|
|
38
49
|
import { execFileSync } from "node:child_process"
|
|
39
50
|
|
|
@@ -107,6 +118,28 @@ export function injectSelfReload(html, sha) {
|
|
|
107
118
|
return out + snippet
|
|
108
119
|
}
|
|
109
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Scan siteDir for previously-released v<version>/showcase-meta.json files
|
|
123
|
+
* and assemble the versions.json manifest, newest first. Read by the
|
|
124
|
+
* showcase hub (TemplateLanding) and per-channel notice (ChannelNotice) to
|
|
125
|
+
* show this widget's own release history -- not the grist-widget-sdk
|
|
126
|
+
* monorepo's (found live: every scaffolded widget's version index showed
|
|
127
|
+
* the monorepo's versions instead of its own, since showcase-versions.ts
|
|
128
|
+
* used to hardcode that URL).
|
|
129
|
+
*/
|
|
130
|
+
export function buildVersionsManifest(siteDir) {
|
|
131
|
+
const entries = []
|
|
132
|
+
for (const name of existsSync(siteDir) ? readdirSync(siteDir) : []) {
|
|
133
|
+
if (!/^v\d+\.\d+\.\d+/.test(name)) continue
|
|
134
|
+
const metaPath = join(siteDir, name, "showcase-meta.json")
|
|
135
|
+
if (!existsSync(metaPath)) continue
|
|
136
|
+
const meta = JSON.parse(readFileSync(metaPath, "utf8"))
|
|
137
|
+
entries.push({ version: meta.version, publishedAt: meta.publishedAt })
|
|
138
|
+
}
|
|
139
|
+
entries.sort((a, b) => new Date(b.publishedAt) - new Date(a.publishedAt))
|
|
140
|
+
return entries
|
|
141
|
+
}
|
|
142
|
+
|
|
110
143
|
// ----------------------------------------------------------------------------
|
|
111
144
|
// Filesystem / git effects
|
|
112
145
|
// ----------------------------------------------------------------------------
|
|
@@ -144,6 +177,10 @@ export function placeTarget({ siteDir, channel, version, distDir, sha, ref }) {
|
|
|
144
177
|
// so nothing 404s.
|
|
145
178
|
const versionDir = join(siteDir, `v${version}`)
|
|
146
179
|
replaceDir(versionDir, distDir)
|
|
180
|
+
writeFileSync(
|
|
181
|
+
join(versionDir, "showcase-meta.json"),
|
|
182
|
+
JSON.stringify({ version, publishedAt: new Date().toISOString(), sha }, null, 2) + "\n",
|
|
183
|
+
)
|
|
147
184
|
const latestDir = join(siteDir, "latest")
|
|
148
185
|
replaceDir(latestDir, distDir)
|
|
149
186
|
mkdirSync(siteDir, { recursive: true })
|
|
@@ -173,8 +210,12 @@ function sleep(ms) {
|
|
|
173
210
|
while (Date.now() < end) {}
|
|
174
211
|
}
|
|
175
212
|
|
|
176
|
-
/**
|
|
177
|
-
export function finalize({ siteDir, push, commitMessage, remoteBranch = "gh-pages" }) {
|
|
213
|
+
/** Regenerate versions.json (release runs only), then commit + push with rebase-retry. */
|
|
214
|
+
export function finalize({ siteDir, updateVersions, push, commitMessage, remoteBranch = "gh-pages" }) {
|
|
215
|
+
if (updateVersions) {
|
|
216
|
+
const versions = buildVersionsManifest(siteDir)
|
|
217
|
+
writeFileSync(join(siteDir, "versions.json"), JSON.stringify(versions, null, 2) + "\n")
|
|
218
|
+
}
|
|
178
219
|
git(["add", "-A"], siteDir)
|
|
179
220
|
const status = git(["status", "--porcelain"], siteDir)
|
|
180
221
|
if (!status) {
|
|
@@ -253,6 +294,7 @@ function main() {
|
|
|
253
294
|
case "finalize": {
|
|
254
295
|
const res = finalize({
|
|
255
296
|
siteDir: args.site,
|
|
297
|
+
updateVersions: !!args["update-versions"],
|
|
256
298
|
push: !!args.push,
|
|
257
299
|
commitMessage: args["commit-message"],
|
|
258
300
|
})
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "@/components/ui/card"
|
|
11
11
|
import { Input } from "@/components/ui/input"
|
|
12
12
|
import { channelLabel, type Channel } from "@/lib/showcase-routing"
|
|
13
|
-
import {
|
|
13
|
+
import { devUrl, useVersions, versionUrl } from "@/lib/showcase-versions"
|
|
14
14
|
import { cn } from "@/lib/utils"
|
|
15
15
|
|
|
16
16
|
// Shown instead of the widget tree on a specific channel build
|
|
@@ -44,7 +44,7 @@ function VersionChips({ current }: { current: Channel }) {
|
|
|
44
44
|
latest
|
|
45
45
|
</a>
|
|
46
46
|
)}
|
|
47
|
-
<a href={
|
|
47
|
+
<a href={devUrl()} className={chipClass(current.kind === "dev")}>
|
|
48
48
|
dev
|
|
49
49
|
</a>
|
|
50
50
|
{versions?.map((v) => (
|
|
@@ -2,7 +2,7 @@ import { useState } from "react"
|
|
|
2
2
|
|
|
3
3
|
import { Button } from "@/components/ui/button"
|
|
4
4
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
|
5
|
-
import {
|
|
5
|
+
import { devUrl, formatDate, useVersions, versionUrl } from "@/lib/showcase-versions"
|
|
6
6
|
|
|
7
7
|
// The showcase "hub" page: rendered whenever this deploy's URL has no
|
|
8
8
|
// recognized channel suffix (see src/lib/showcase-routing.ts) -- this repo's
|
|
@@ -178,7 +178,7 @@ git push origin dev`}</code>
|
|
|
178
178
|
Released template versions
|
|
179
179
|
</h2>
|
|
180
180
|
<a
|
|
181
|
-
href={
|
|
181
|
+
href={devUrl()}
|
|
182
182
|
className="text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground"
|
|
183
183
|
>
|
|
184
184
|
Live dev preview →
|
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import { useEffect, useState } from "react"
|
|
2
2
|
|
|
3
|
+
import { parseShowcasePath } from "@/lib/showcase-routing"
|
|
4
|
+
|
|
3
5
|
// Shared by the showcase hub (TemplateLanding) and the per-channel notice
|
|
4
|
-
// (ChannelNotice) -- both need the same released-version list
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
// (ChannelNotice) -- both need the same released-version list. URLs are
|
|
7
|
+
// root-relative to wherever THIS deploy actually lives (derived from
|
|
8
|
+
// window.location.pathname via parseShowcasePath's hubPath), not hardcoded
|
|
9
|
+
// to the grist-widget-sdk monorepo's own showcase: a real scaffolded
|
|
10
|
+
// widget has its own versions.json and its own v<version>/ + dev/ dirs,
|
|
11
|
+
// and previously showed the monorepo's version history and links instead
|
|
12
|
+
// of its own (found live on a real scaffold's landing page).
|
|
13
|
+
function hubPath(): string {
|
|
14
|
+
const path = parseShowcasePath(window.location.pathname).hubPath
|
|
15
|
+
return path.endsWith("/") ? path : `${path}/`
|
|
16
|
+
}
|
|
11
17
|
|
|
12
18
|
export type ReleasedVersion = {
|
|
13
19
|
version: string
|
|
14
20
|
publishedAt: string
|
|
15
21
|
}
|
|
16
22
|
|
|
23
|
+
export function versionsUrl(): string {
|
|
24
|
+
return `${hubPath()}versions.json`
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function devUrl(): string {
|
|
28
|
+
return `${hubPath()}dev/`
|
|
29
|
+
}
|
|
30
|
+
|
|
17
31
|
export function versionUrl(version: string): string {
|
|
18
|
-
return
|
|
32
|
+
return `${hubPath()}v${version}/`
|
|
19
33
|
}
|
|
20
34
|
|
|
21
35
|
export function useVersions() {
|
|
@@ -24,7 +38,7 @@ export function useVersions() {
|
|
|
24
38
|
|
|
25
39
|
useEffect(() => {
|
|
26
40
|
let cancelled = false
|
|
27
|
-
fetch(
|
|
41
|
+
fetch(versionsUrl(), { cache: "no-store" })
|
|
28
42
|
.then((res) => (res.ok ? res.json() : Promise.reject(res)))
|
|
29
43
|
.then((data: ReleasedVersion[]) => {
|
|
30
44
|
if (!cancelled) setVersions(data)
|