@gjsify/site 0.64.25 → 0.64.26
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 +6 -0
- package/lib/cli.js +7 -1
- package/lib/site-data/github.d.ts +5 -1
- package/lib/site-data/github.js +10 -3
- package/lib/site-data/load.d.ts +3 -0
- package/lib/site-data/load.js +7 -2
- package/lib/site.d.ts +2 -0
- package/lib/site.js +2 -0
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -46,6 +46,7 @@ gjsify site build --runtime node # build and run on a specific runtime
|
|
|
46
46
|
| `--drafts` | `build`: include blog posts marked `draft: true`. |
|
|
47
47
|
| `--no-cache` | Ignore the one-hour HTTP response cache. |
|
|
48
48
|
| `--cache-dir <dir>` | Where the response cache and the image renditions live. Default: `<root>/node_modules/.cache/gjsify-site`. |
|
|
49
|
+
| `--release-tag <tag>` | `build`: take the download links from this GitHub release (`releases/tags/<tag>`) instead of `releases/latest`, which can lag a fresh publish by minutes. Default: `$GJSIFY_SITE_RELEASE_TAG`. |
|
|
49
50
|
| `--check` | `i18n`: report what is out of date instead of writing it. |
|
|
50
51
|
| `--runtime <r>` | `gjs` \| `node` \| `bun` \| `deno`. Default: the runtime the CLI itself is on. |
|
|
51
52
|
|
|
@@ -166,6 +167,11 @@ shared package can derive.
|
|
|
166
167
|
`GITHUB_TOKEN` is optional and only raises the API rate limit. When a lookup fails the build
|
|
167
168
|
warns rather than failing: a release API outage is not a reason to have no page.
|
|
168
169
|
|
|
170
|
+
The build logs which release it used (tag, publish date, asset count) and warns when that release's
|
|
171
|
+
version differs from the version the page shows. A deploy triggered by `release: published` should
|
|
172
|
+
pass `--release-tag "$GITHUB_REF_NAME"` (or set `GJSIFY_SITE_RELEASE_TAG`): `releases/latest` can still
|
|
173
|
+
answer with the previous release for a few minutes.
|
|
174
|
+
|
|
169
175
|
The same thing from a script:
|
|
170
176
|
|
|
171
177
|
```ts
|
package/lib/cli.js
CHANGED
|
@@ -22,6 +22,9 @@ Options:
|
|
|
22
22
|
--no-cache Ignore the one-hour HTTP response cache
|
|
23
23
|
--cache-dir <dir> Where to keep the response cache and image renditions
|
|
24
24
|
(default: <root>/node_modules/.cache/gjsify-site)
|
|
25
|
+
--release-tag <t> build: take the download links from this GitHub release
|
|
26
|
+
instead of \`releases/latest\`, which lags a fresh publish
|
|
27
|
+
(default: $GJSIFY_SITE_RELEASE_TAG)
|
|
25
28
|
--check i18n: report what is out of date instead of writing it
|
|
26
29
|
--store <s> listing: cws | edge | amo | all (default: all)
|
|
27
30
|
--metainfo <path> listing: AppStream metainfo, overriding the configured one
|
|
@@ -33,7 +36,8 @@ Options:
|
|
|
33
36
|
from this module's own location)
|
|
34
37
|
-h, --help Show this text
|
|
35
38
|
|
|
36
|
-
Environment: GITHUB_TOKEN raises the GitHub API rate limit
|
|
39
|
+
Environment: GITHUB_TOKEN raises the GitHub API rate limit.
|
|
40
|
+
GJSIFY_SITE_RELEASE_TAG is the default of --release-tag.`;
|
|
37
41
|
/** The value after `--name`, or `undefined` when the flag is absent. */
|
|
38
42
|
function flagValue(flags, name) {
|
|
39
43
|
const index = flags.indexOf(name);
|
|
@@ -59,6 +63,8 @@ async function build(flags) {
|
|
|
59
63
|
cacheDir: cacheOption(flags),
|
|
60
64
|
packageDir: flagValue(flags, '--package-dir'),
|
|
61
65
|
githubToken: process.env.GITHUB_TOKEN || undefined,
|
|
66
|
+
releaseTag: flagValue(flags, '--release-tag') ?? (process.env.GJSIFY_SITE_RELEASE_TAG || undefined),
|
|
67
|
+
log: (message) => console.log(message),
|
|
62
68
|
warn: (message) => console.warn(`warning: ${message}`),
|
|
63
69
|
});
|
|
64
70
|
console.log(`Built the pages in ${result.languages.length} languages and ${result.screenshots} screenshots`);
|
|
@@ -11,5 +11,9 @@ export declare function fetchReleaseRecords(assets: readonly ReleaseAsset[], opt
|
|
|
11
11
|
/**
|
|
12
12
|
* Fetches the latest published (non-draft, non-prerelease) release; `null` when the repository has
|
|
13
13
|
* none yet, which is a state and not an error. `token` raises the rate limit.
|
|
14
|
+
*
|
|
15
|
+
* With `tag`, fetches exactly that release instead. `releases/latest` lags a fresh publish by
|
|
16
|
+
* minutes, so a deploy triggered by the release itself must be able to name it; a pinned tag that
|
|
17
|
+
* does not exist is an error, not "no release yet".
|
|
14
18
|
*/
|
|
15
|
-
export declare function fetchLatestRelease(repository: string, token: string | undefined, options: NetworkOptions): Promise<LatestRelease | null>;
|
|
19
|
+
export declare function fetchLatestRelease(repository: string, token: string | undefined, options: NetworkOptions, tag?: string): Promise<LatestRelease | null>;
|
package/lib/site-data/github.js
CHANGED
|
@@ -55,8 +55,12 @@ export async function fetchReleaseRecords(assets, options, warn) {
|
|
|
55
55
|
/**
|
|
56
56
|
* Fetches the latest published (non-draft, non-prerelease) release; `null` when the repository has
|
|
57
57
|
* none yet, which is a state and not an error. `token` raises the rate limit.
|
|
58
|
+
*
|
|
59
|
+
* With `tag`, fetches exactly that release instead. `releases/latest` lags a fresh publish by
|
|
60
|
+
* minutes, so a deploy triggered by the release itself must be able to name it; a pinned tag that
|
|
61
|
+
* does not exist is an error, not "no release yet".
|
|
58
62
|
*/
|
|
59
|
-
export async function fetchLatestRelease(repository, token, options) {
|
|
63
|
+
export async function fetchLatestRelease(repository, token, options, tag) {
|
|
60
64
|
const headers = {
|
|
61
65
|
Accept: 'application/vnd.github+json',
|
|
62
66
|
'User-Agent': `${repository.replace('/', '-')}-website`,
|
|
@@ -64,11 +68,14 @@ export async function fetchLatestRelease(repository, token, options) {
|
|
|
64
68
|
if (token)
|
|
65
69
|
headers.Authorization = `Bearer ${token}`;
|
|
66
70
|
try {
|
|
67
|
-
return parseLatestRelease(await fetchJson(`https://api.github.com/repos/${repository}/releases
|
|
71
|
+
return parseLatestRelease(await fetchJson(`https://api.github.com/repos/${repository}/releases/${tag ? `tags/${encodeURIComponent(tag)}` : 'latest'}`, headers, options));
|
|
68
72
|
}
|
|
69
73
|
catch (error) {
|
|
70
|
-
if (error instanceof HttpError && error.status === 404)
|
|
74
|
+
if (error instanceof HttpError && error.status === 404) {
|
|
75
|
+
if (tag)
|
|
76
|
+
throw new Error(`GitHub has no release tagged ${tag} in ${repository}`);
|
|
71
77
|
return null;
|
|
78
|
+
}
|
|
72
79
|
throw error;
|
|
73
80
|
}
|
|
74
81
|
}
|
package/lib/site-data/load.d.ts
CHANGED
|
@@ -9,7 +9,10 @@ export interface LoadOptions {
|
|
|
9
9
|
/** Skip every network call (release assets, stats, screenshots hosted elsewhere). */
|
|
10
10
|
offline?: boolean;
|
|
11
11
|
githubToken?: string;
|
|
12
|
+
/** Use this release tag instead of `releases/latest`, which lags a fresh publish by minutes. */
|
|
13
|
+
releaseTag?: string;
|
|
12
14
|
network?: NetworkOptions;
|
|
15
|
+
log?: (message: string) => void;
|
|
13
16
|
warn?: (message: string) => void;
|
|
14
17
|
}
|
|
15
18
|
/** Reads `<dir>/<lang>.po` for every language, trying `pt-BR` and `pt_BR` spellings; missing files are skipped. */
|
package/lib/site-data/load.js
CHANGED
|
@@ -90,7 +90,7 @@ export async function loadSiteData(options) {
|
|
|
90
90
|
if (!options.offline) {
|
|
91
91
|
const network = options.network ?? {};
|
|
92
92
|
const [release, flathub, summary] = await Promise.allSettled([
|
|
93
|
-
fetchLatestRelease(config.repository, options.githubToken, network),
|
|
93
|
+
fetchLatestRelease(config.repository, options.githubToken, network, options.releaseTag),
|
|
94
94
|
config.flathub ? fetchFlathubStats(config.flathub, network) : Promise.resolve(undefined),
|
|
95
95
|
config.flathub ? fetchFlathubSummary(config.flathub, network) : Promise.resolve(undefined),
|
|
96
96
|
]);
|
|
@@ -98,6 +98,11 @@ export async function loadSiteData(options) {
|
|
|
98
98
|
latestRelease = release.value;
|
|
99
99
|
hasReleases = latestRelease !== null;
|
|
100
100
|
if (latestRelease) {
|
|
101
|
+
options.log?.(`Using GitHub release ${latestRelease.tag} (published ${latestRelease.publishedAt || 'unknown'}, ${latestRelease.assets.length} assets)${options.releaseTag ? ' as pinned' : ''}`);
|
|
102
|
+
const shown = version || metainfo.releases[0]?.version || '';
|
|
103
|
+
if (shown && latestRelease.tag.replace(/^v/, '') !== shown) {
|
|
104
|
+
warn(`The release ${latestRelease.tag} does not match the version ${shown} the page shows; download links point to ${latestRelease.tag}${options.releaseTag ? '' : ' (releases/latest may lag a fresh publish; pin it with --release-tag)'}`);
|
|
105
|
+
}
|
|
101
106
|
// A release record is fetched by every site build, not by a person installing.
|
|
102
107
|
stats.githubDownloads = latestRelease.assets
|
|
103
108
|
.filter((asset) => recordedArtifact(asset.name) === undefined)
|
|
@@ -107,7 +112,7 @@ export async function loadSiteData(options) {
|
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
else {
|
|
110
|
-
warn(`Could not fetch the latest GitHub release (${String(release.reason)}); linking to the releases page instead`);
|
|
115
|
+
warn(`Could not fetch the ${options.releaseTag ? `GitHub release ${options.releaseTag}` : 'latest GitHub release'} (${String(release.reason)}); linking to the releases page instead`);
|
|
111
116
|
}
|
|
112
117
|
if (flathub.status === 'fulfilled' && flathub.value) {
|
|
113
118
|
stats.flathubInstalls = flathub.value.installsTotal;
|
package/lib/site.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface SiteBuildOptions extends SiteTarget {
|
|
|
20
20
|
cacheDir?: string | false;
|
|
21
21
|
/** Raises the GitHub API rate limit. Optional — the public limit is enough for a single build. */
|
|
22
22
|
githubToken?: string;
|
|
23
|
+
/** Pin the GitHub release the download links come from, instead of `releases/latest`. */
|
|
24
|
+
releaseTag?: string;
|
|
23
25
|
log?: (message: string) => void;
|
|
24
26
|
warn?: (message: string) => void;
|
|
25
27
|
/**
|
package/lib/site.js
CHANGED
|
@@ -212,7 +212,9 @@ async function buildAppSite(build) {
|
|
|
212
212
|
screenshotCacheDir: join(cacheDir ?? defaultCacheDir(target.root), 'screenshots'),
|
|
213
213
|
offline: options.offline ?? false,
|
|
214
214
|
githubToken: options.githubToken,
|
|
215
|
+
releaseTag: options.releaseTag,
|
|
215
216
|
network: cacheDir ? { cacheDir: join(cacheDir, 'http') } : {},
|
|
217
|
+
log: options.log,
|
|
216
218
|
warn: options.warn,
|
|
217
219
|
});
|
|
218
220
|
const images = await processScreenshots(data, target, cacheDir ?? defaultCacheDir(target.root));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/site",
|
|
3
|
-
"version": "0.64.
|
|
3
|
+
"version": "0.64.26",
|
|
4
4
|
"description": "Static landing page generator for a GNOME-style app, rendered from its AppStream metainfo — downloads, screenshots, release notes, support links, no JavaScript required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -54,21 +54,21 @@
|
|
|
54
54
|
"license": "MIT",
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@girs/gdkpixbuf-2.0": "5.4.0",
|
|
57
|
-
"@gjsify/console": "^0.64.
|
|
58
|
-
"@gjsify/crypto": "^0.64.
|
|
59
|
-
"@gjsify/fs": "^0.64.
|
|
60
|
-
"@gjsify/module": "^0.64.
|
|
61
|
-
"@gjsify/os": "^0.64.
|
|
62
|
-
"@gjsify/path": "^0.64.
|
|
63
|
-
"@gjsify/process": "^0.64.
|
|
64
|
-
"@gjsify/url": "^0.64.
|
|
57
|
+
"@gjsify/console": "^0.64.26",
|
|
58
|
+
"@gjsify/crypto": "^0.64.26",
|
|
59
|
+
"@gjsify/fs": "^0.64.26",
|
|
60
|
+
"@gjsify/module": "^0.64.26",
|
|
61
|
+
"@gjsify/os": "^0.64.26",
|
|
62
|
+
"@gjsify/path": "^0.64.26",
|
|
63
|
+
"@gjsify/process": "^0.64.26",
|
|
64
|
+
"@gjsify/url": "^0.64.26",
|
|
65
65
|
"fast-xml-parser": "^5.11.2",
|
|
66
66
|
"qrcode-generator": "^2.0.4"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@gjsify/cli": "^0.64.
|
|
69
|
+
"@gjsify/cli": "^0.64.26",
|
|
70
70
|
"@gjsify/node-gi": "file:../../node-gi/node-gi",
|
|
71
|
-
"@gjsify/unit": "^0.64.
|
|
71
|
+
"@gjsify/unit": "^0.64.26",
|
|
72
72
|
"@types/node": "^25.9.2",
|
|
73
73
|
"typescript": "^6.0.3"
|
|
74
74
|
},
|