@minnovate/shadow-publisher 0.14.1 → 0.15.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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-publisher",
|
|
3
3
|
"displayName": "Git Publisher",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.1",
|
|
5
5
|
"description": "Publish an app folder's Git history to the serverless Git publishing backend and keep it updated (\"publish my app\", \"update my app\", \"fetch the engineered version\").",
|
|
6
6
|
"author": { "name": "git-publisher project" },
|
|
7
7
|
"keywords": ["git", "publish", "deploy", "serverless"]
|
|
@@ -136,9 +136,9 @@ fast-forward or a clean merge — it never rewrites the user's work), and publis
|
|
|
136
136
|
them when the person asks why it was slow. Write
|
|
137
137
|
the message in the user's words ("Add a contact page"), not git's.
|
|
138
138
|
|
|
139
|
-
A published app runs with no internet access: **
|
|
140
|
-
CDN scripts, web fonts or remote images
|
|
141
|
-
in its folder. The checks refuse an app that does not (see "When the checks find something").
|
|
139
|
+
A published app runs with no internet access: **apps can’t load anything from other sites** — no
|
|
140
|
+
CDN scripts, web fonts or remote images — and can’t call other sites for data: connect the data as
|
|
141
|
+
a data source instead. When you write or change an app, keep every file it needs in its folder. The checks refuse an app that does not (see "When the checks find something").
|
|
142
142
|
Keep it small too: each file at most 4 MB, the whole app at most 10 MB, at most 500 files —
|
|
143
143
|
a larger app is refused before it is checked, and the refusal names the file or the limit it broke.
|
|
144
144
|
|
|
@@ -220,11 +220,17 @@ sentence, and `progress.next.action` is `"fix"`. Then:
|
|
|
220
220
|
Their original app is still what is published; nothing broke.
|
|
221
221
|
2. Fix every finding in the app folder, by its `kind`:
|
|
222
222
|
- `external-resource`: the app loads `url` from another site (a CDN script, Google Fonts, an
|
|
223
|
-
image). **Apps
|
|
223
|
+
image). **Apps can’t load anything from other sites.** Download the file into the app
|
|
224
224
|
folder and point to it with a relative path, if it is at most 4 MB (a charting library
|
|
225
225
|
such as Chart.js, about 200 KB, fits). Otherwise replace it with code of your own: a
|
|
226
226
|
font falls back to a system font stack, a chart is drawn as inline SVG. Never keep the
|
|
227
227
|
external address.
|
|
228
|
+
- `external-request`: the app CALLS `url` on another site for data (`fetch`, an API).
|
|
229
|
+
**Apps can't reach other sites.** Do not copy anything: remove the call, or bring the data
|
|
230
|
+
into the app as a data source (the `data_sources` tool, or `publisher data add`), and read
|
|
231
|
+
it from there.
|
|
232
|
+
- `server-start`: the app's server stopped before it answered `/`. `message` is the error it
|
|
233
|
+
printed and where. Fix that line, and run the server with `PORT` set to try it.
|
|
228
234
|
- `console-error` / `application-error`: fix the code that logs or throws `message`.
|
|
229
235
|
- `failed-request`: the app asks for `path` on its own site and gets `status`; add the file or
|
|
230
236
|
stop requesting it.
|
|
@@ -42,6 +42,17 @@ A value that is not an option is refused before anything is sent; `error.details
|
|
|
42
42
|
the choices. Exit 4 means this sign-in may not answer (an owner or admin can); exit 3 means ask
|
|
43
43
|
again. Then `publisher follow . --publication <id> --until-change --timeout 100 --json` to see it go live, telling them each step as `publish-app` step 4 says.
|
|
44
44
|
|
|
45
|
+
## When it did not go live because of a fault on our side
|
|
46
|
+
|
|
47
|
+
When `publisher question . --json` shows a `blocked` preparation whose `message` says the fault
|
|
48
|
+
was on our side, not in the app, do not change the app. Try it again once:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
publisher retry . --json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Then follow it again. If it fails a second time, tell the person, and give them the portal page.
|
|
55
|
+
|
|
45
56
|
## After it is live
|
|
46
57
|
|
|
47
58
|
These run in the app's folder and answer `say` (tell the person) and `next` (what to do now):
|
package/dist/publisher.cjs
CHANGED
|
@@ -5417,6 +5417,16 @@ function ending(stages) {
|
|
|
5417
5417
|
return "stopped";
|
|
5418
5418
|
}
|
|
5419
5419
|
var POLL_INTERVAL_MS = 5e3;
|
|
5420
|
+
var MAX_REASON = 1e3;
|
|
5421
|
+
function settled(run2, stages, end) {
|
|
5422
|
+
const runId = isRecord(run2) && typeof run2["runId"] === "string" ? run2["runId"] : null;
|
|
5423
|
+
const failedAt = stages.find((s) => s.state === "failed")?.word ?? null;
|
|
5424
|
+
return { kind: "settled", ending: end, failedAt, stages, runId, reason: reasonOf(run2, end) };
|
|
5425
|
+
}
|
|
5426
|
+
function reasonOf(run2, end) {
|
|
5427
|
+
const summary = isRecord(run2) ? run2["summary"] : null;
|
|
5428
|
+
return end === "failed" && typeof summary === "string" && summary.trim() !== "" ? summary.trim().slice(0, MAX_REASON) : null;
|
|
5429
|
+
}
|
|
5420
5430
|
var FOLLOW_TIMEOUT_MS = 15 * 6e4;
|
|
5421
5431
|
async function followRun(input, opts) {
|
|
5422
5432
|
const portal = new PortalSession(opts);
|
|
@@ -5469,8 +5479,7 @@ async function followRun(input, opts) {
|
|
|
5469
5479
|
}
|
|
5470
5480
|
const end = ending(read2.stages);
|
|
5471
5481
|
if (end !== null) {
|
|
5472
|
-
|
|
5473
|
-
return { kind: "settled", ending: end, failedAt: read2.stages.find((s) => s.state === "failed")?.word ?? null, stages: read2.stages, runId };
|
|
5482
|
+
return settled(run2.run, read2.stages, end);
|
|
5474
5483
|
}
|
|
5475
5484
|
if (opts.untilChange === true && moved && answered) {
|
|
5476
5485
|
return { kind: "moving", stages: read2.stages };
|
|
@@ -5540,6 +5549,9 @@ function readPreparation(input, opts) {
|
|
|
5540
5549
|
function answerPreparation(input, opts) {
|
|
5541
5550
|
return call(input, opts, { id: input.id, revision: input.revision, action: "answers", answers: input.answers });
|
|
5542
5551
|
}
|
|
5552
|
+
function retryPreparation(input, opts) {
|
|
5553
|
+
return call(input, opts, { id: input.id, revision: input.revision, action: "retry" });
|
|
5554
|
+
}
|
|
5543
5555
|
async function call(input, opts, body) {
|
|
5544
5556
|
const url2 = `${input.portal.replace(/\/+$/, "")}/api/v1/terminal/repositories/${encodeURIComponent(input.repoId)}/preparation`;
|
|
5545
5557
|
const answer2 = await new PortalSession(opts).ask(url2, body);
|
|
@@ -5599,7 +5611,16 @@ function readView(body) {
|
|
|
5599
5611
|
if (isRecord(publication) && typeof publication["status"] === "string" && typeof publication["message"] === "string") {
|
|
5600
5612
|
pub = { status: publication["status"], message: publication["message"], ...typeof publication["url"] === "string" ? { url: publication["url"] } : {} };
|
|
5601
5613
|
}
|
|
5602
|
-
return {
|
|
5614
|
+
return {
|
|
5615
|
+
id,
|
|
5616
|
+
revision,
|
|
5617
|
+
status: status2,
|
|
5618
|
+
message,
|
|
5619
|
+
questions: read2,
|
|
5620
|
+
publication: pub,
|
|
5621
|
+
findings: readFindings(body["findings"]),
|
|
5622
|
+
canRetry: body["canRetry"] === true
|
|
5623
|
+
};
|
|
5603
5624
|
}
|
|
5604
5625
|
function readFindings(value) {
|
|
5605
5626
|
if (!Array.isArray(value)) {
|
|
@@ -6445,6 +6466,10 @@ var Publisher = class {
|
|
|
6445
6466
|
async answerPreparation(input) {
|
|
6446
6467
|
return answerPreparation(input, this.portalCall());
|
|
6447
6468
|
}
|
|
6469
|
+
/** The repository's current preparation tried again, when it could not finish because of a fault on our side. */
|
|
6470
|
+
async retryPreparation(input) {
|
|
6471
|
+
return retryPreparation(input, this.portalCall());
|
|
6472
|
+
}
|
|
6448
6473
|
/**
|
|
6449
6474
|
* One of the creator's tools at the portal that serves this endpoint — starters, status, history,
|
|
6450
6475
|
* going back, suggestions, sharing — with this publisher's credential and its one refresh. The
|
|
@@ -7080,7 +7105,7 @@ async function followPublication(p, endpoint, o, opts) {
|
|
|
7080
7105
|
return {
|
|
7081
7106
|
...outcome2,
|
|
7082
7107
|
portal,
|
|
7083
|
-
hint: `It
|
|
7108
|
+
hint: `It didn\u2019t pass its checks (${findings.length === 1 ? "one finding" : `${findings.length} findings`}). Fix each finding in the app folder, then run next.command to publish again.`,
|
|
7084
7109
|
findings,
|
|
7085
7110
|
next: { action: "fix", command: `publisher sync ${dir} --until-change --json` }
|
|
7086
7111
|
};
|
|
@@ -7153,7 +7178,7 @@ function progressHint(r, portal, answerable = false) {
|
|
|
7153
7178
|
case "not-deployed":
|
|
7154
7179
|
return "Published and checked; this organisation does not deploy automatically.";
|
|
7155
7180
|
case "failed":
|
|
7156
|
-
return inPortal(portal, `It stopped at "${r.failedAt ?? "a step"}"
|
|
7181
|
+
return inPortal(portal, `It stopped at "${r.failedAt ?? "a step"}".${r.reason === null ? "" : ` ${r.reason}`}`, r.reason === null ? "See why" : "See it");
|
|
7157
7182
|
case "stopped":
|
|
7158
7183
|
return "A newer publication replaced this one before it went live.";
|
|
7159
7184
|
}
|
|
@@ -7865,6 +7890,20 @@ async function answerAt(p, endpoint, repoId, specs, opts = {}) {
|
|
|
7865
7890
|
}
|
|
7866
7891
|
return shown(at.portal, await p.answerPreparation({ portal: at.portal, repoId, id: read2.preparation.id, revision: read2.preparation.revision, answers }));
|
|
7867
7892
|
}
|
|
7893
|
+
async function retryAt(p, endpoint, repoId, opts = {}) {
|
|
7894
|
+
const read2 = await questionAt(p, endpoint, repoId, opts);
|
|
7895
|
+
if (read2.kind !== "view") {
|
|
7896
|
+
return read2;
|
|
7897
|
+
}
|
|
7898
|
+
if (read2.preparation.status !== "blocked") {
|
|
7899
|
+
throw new PublisherError("LOCAL_STATE", `nothing to try again (the preparation is ${read2.preparation.status})`);
|
|
7900
|
+
}
|
|
7901
|
+
if (!read2.preparation.canRetry) {
|
|
7902
|
+
throw new PublisherError("LOCAL_STATE", "this version cannot be tried again: only one that stopped because of a fault on our side can, three times at most");
|
|
7903
|
+
}
|
|
7904
|
+
const tried = shown(read2.portal, await p.retryPreparation({ portal: read2.portal, repoId, id: read2.preparation.id, revision: read2.preparation.revision }));
|
|
7905
|
+
return tried.kind === "view" ? { ...tried, hint: "It is being tried again. Run: publisher follow, or watch it in the portal." } : tried;
|
|
7906
|
+
}
|
|
7868
7907
|
function parseSpecs(specs) {
|
|
7869
7908
|
if (specs.length === 0) {
|
|
7870
7909
|
throw new PublisherError("INVALID_REQUEST", "answer takes one or more question=value");
|
|
@@ -7951,6 +7990,16 @@ var question = {
|
|
|
7951
7990
|
return 0;
|
|
7952
7991
|
}
|
|
7953
7992
|
};
|
|
7993
|
+
var retry = {
|
|
7994
|
+
git: false,
|
|
7995
|
+
async run(inv) {
|
|
7996
|
+
const dir = inv.dirArg(1);
|
|
7997
|
+
const { p, endpoint } = await inv.client(dir);
|
|
7998
|
+
const repoId = await inv.repoId(dir);
|
|
7999
|
+
inv.out({ repoId, ...await retryAt(p, endpoint, repoId) });
|
|
8000
|
+
return 0;
|
|
8001
|
+
}
|
|
8002
|
+
};
|
|
7954
8003
|
var answer = {
|
|
7955
8004
|
git: false,
|
|
7956
8005
|
async run(inv) {
|
|
@@ -8441,6 +8490,8 @@ Usage:
|
|
|
8441
8490
|
with each option's value (answering needs owner or admin)
|
|
8442
8491
|
publisher answer <question>=<value>... [--repo <id>] answer it from this folder; a value that is not one of
|
|
8443
8492
|
the question's options is refused before anything is sent
|
|
8493
|
+
publisher retry [dir] [--repo <id>] try the app's newest version again, when it did not go
|
|
8494
|
+
live because of a fault on our side (three tries at most)
|
|
8444
8495
|
publisher starters [what you want to stop doing] working apps to start from, the ones that fit first
|
|
8445
8496
|
publisher start <starter> [--name <n>] [--replaces <what>] a new app made from a starter, live in about a minute
|
|
8446
8497
|
publisher history this folder's app: the versions that went live, newest first
|
|
@@ -8497,6 +8548,7 @@ var COMMANDS = /* @__PURE__ */ new Map([
|
|
|
8497
8548
|
["follow", follow],
|
|
8498
8549
|
["question", question],
|
|
8499
8550
|
["answer", answer],
|
|
8551
|
+
["retry", retry],
|
|
8500
8552
|
["skills", skills],
|
|
8501
8553
|
["merge-check", mergeCheck2],
|
|
8502
8554
|
["info", info],
|