@fluid-app/fluid-cli-mist 0.1.48 → 0.1.49
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/dist/index.mjs +71 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1005,6 +1005,64 @@ function readMistFileFrom(dir = process.cwd()) {
|
|
|
1005
1005
|
return readMistFile(dir);
|
|
1006
1006
|
}
|
|
1007
1007
|
//#endregion
|
|
1008
|
+
//#region src/lib/staging-revision.ts
|
|
1009
|
+
/**
|
|
1010
|
+
* Pick the commit `fluid mist staging request` stages when no `--revision`
|
|
1011
|
+
* is given: the local checkout's HEAD, but only when nothing local would be
|
|
1012
|
+
* left out or lost.
|
|
1013
|
+
*
|
|
1014
|
+
* Staging can only serve a commit the mist's repository already has, and
|
|
1015
|
+
* this never pushes or switches branches to get one there; publishing to
|
|
1016
|
+
* main would ship the work to production. So the checkout must be clean
|
|
1017
|
+
* and its HEAD must already be on the remote's main branch.
|
|
1018
|
+
*/
|
|
1019
|
+
/** The local checkout can't be staged as it is. Nothing was changed. */
|
|
1020
|
+
var StagingPreflightError = class extends Error {
|
|
1021
|
+
constructor(message) {
|
|
1022
|
+
super(`${message} Nothing was requested.`);
|
|
1023
|
+
this.name = "StagingPreflightError";
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
/**
|
|
1027
|
+
* The full SHA of the checkout's HEAD once it's clean and on the remote's
|
|
1028
|
+
* main branch. `remoteUrl` may carry a short-lived token; it only reaches
|
|
1029
|
+
* git through `gitFetch`, never argv or config.
|
|
1030
|
+
*
|
|
1031
|
+
* Raises StagingPreflightError when the directory is not a git checkout,
|
|
1032
|
+
* git can't report its status, it has uncommitted or untracked files, or
|
|
1033
|
+
* HEAD is not on the remote's main.
|
|
1034
|
+
*/
|
|
1035
|
+
async function resolveLocalStagingRevision(cwd, remoteUrl) {
|
|
1036
|
+
if (await git(cwd, ["rev-parse", "--is-inside-work-tree"]) !== "true") throw new StagingPreflightError("This directory isn't a git checkout of the mist. Run it from the mist's folder or pass --revision.");
|
|
1037
|
+
const status = await git(cwd, [
|
|
1038
|
+
"status",
|
|
1039
|
+
"--porcelain",
|
|
1040
|
+
"--untracked-files=all"
|
|
1041
|
+
]);
|
|
1042
|
+
if (status === null) throw new StagingPreflightError("Git couldn't report whether this checkout has uncommitted changes. Pass --revision to stage a specific commit.");
|
|
1043
|
+
if (status.length > 0) throw new StagingPreflightError("This checkout has uncommitted or untracked changes, and staging only serves commits already on the mist's repository. Commit and publish them, or pass --revision.");
|
|
1044
|
+
const head = await git(cwd, ["rev-parse", "HEAD"]);
|
|
1045
|
+
if (!head || !/^[0-9a-f]{40}$/.test(head)) throw new StagingPreflightError("This checkout has no commits yet.");
|
|
1046
|
+
await gitFetch(cwd, remoteUrl, "main");
|
|
1047
|
+
if ((await execa("git", [
|
|
1048
|
+
"merge-base",
|
|
1049
|
+
"--is-ancestor",
|
|
1050
|
+
head,
|
|
1051
|
+
"FETCH_HEAD"
|
|
1052
|
+
], {
|
|
1053
|
+
cwd,
|
|
1054
|
+
reject: false
|
|
1055
|
+
})).exitCode !== 0) throw new StagingPreflightError(`Commit ${head.slice(0, 7)} isn't on the mist's main branch yet, and staging only serves commits the repository already has.`);
|
|
1056
|
+
return head;
|
|
1057
|
+
}
|
|
1058
|
+
async function git(cwd, args) {
|
|
1059
|
+
const run = await execa("git", args, {
|
|
1060
|
+
cwd,
|
|
1061
|
+
reject: false
|
|
1062
|
+
});
|
|
1063
|
+
return run.exitCode === 0 ? run.stdout.trim() : null;
|
|
1064
|
+
}
|
|
1065
|
+
//#endregion
|
|
1008
1066
|
//#region src/lib/staging.ts
|
|
1009
1067
|
/** A staging step the user can act on, as opposed to a server fault. */
|
|
1010
1068
|
var StagingUnavailableError = class extends Error {
|
|
@@ -1158,7 +1216,7 @@ function handle(err) {
|
|
|
1158
1216
|
console.error(chalk.red(err.message));
|
|
1159
1217
|
process.exit(1);
|
|
1160
1218
|
}
|
|
1161
|
-
if (err instanceof StagingUnavailableError || err instanceof StagingWaitTimeoutError) {
|
|
1219
|
+
if (err instanceof StagingPreflightError || err instanceof StagingUnavailableError || err instanceof StagingWaitTimeoutError) {
|
|
1162
1220
|
console.error(chalk.yellow(err.message));
|
|
1163
1221
|
process.exit(1);
|
|
1164
1222
|
}
|
|
@@ -4193,13 +4251,15 @@ const stagingWaitCommand = new Command("wait").description("Follow a staging ope
|
|
|
4193
4251
|
//#endregion
|
|
4194
4252
|
//#region src/commands/staging/request.ts
|
|
4195
4253
|
/** `fluid mist staging request` — request staging at a revision. */
|
|
4196
|
-
const stagingRequestCommand = new Command("request").description("Request the staging environment at a pushed commit").argument("[slug]", "The mist slug (defaults to .mist file in CWD)").
|
|
4254
|
+
const stagingRequestCommand = new Command("request").description("Request the staging environment at a pushed commit").argument("[slug]", "The mist slug (defaults to .mist file in CWD)").option("--revision <sha>", "Full commit SHA to stage (defaults to this checkout's HEAD when it is clean and on main)").option("--operation-key <key>", "Resume an interrupted request with the key and --revision it printed").option("--wait", "Follow the operation until staging is ready").option("--timeout <minutes>", "How long --wait follows it (default 30)").option("--json", "Emit the operation as JSON").action((slug, opts) => runAction(async () => {
|
|
4255
|
+
if (opts.operationKey && !opts.revision) throw new Error("--operation-key needs the --revision it was first sent with. The interrupted request printed both.");
|
|
4197
4256
|
const resolved = resolveSlug(slug);
|
|
4198
4257
|
const client = createMistClient();
|
|
4258
|
+
const sourceRevision = opts.revision ?? await localRevision(client, resolved);
|
|
4199
4259
|
let operation = await admitStaging(client, resolved, {
|
|
4200
|
-
sourceRevision
|
|
4260
|
+
sourceRevision,
|
|
4201
4261
|
operationKey: opts.operationKey,
|
|
4202
|
-
onOperationKey: (key) => process.stderr.write(chalk.dim(`Operation key ${key}. If this is interrupted, rerun with --operation-key ${key}.\n`))
|
|
4262
|
+
onOperationKey: (key) => process.stderr.write(chalk.dim(`Operation key ${key}. If this is interrupted, rerun with --operation-key ${key} --revision ${sourceRevision}.\n`))
|
|
4203
4263
|
});
|
|
4204
4264
|
process.stderr.write(`Staging operation ${operation.id}: ${describeProgress(operation)}\n`);
|
|
4205
4265
|
if (opts.wait) operation = await waitForOperation(client, resolved, operation.id, waitOptions(opts.timeout));
|
|
@@ -4207,6 +4267,13 @@ const stagingRequestCommand = new Command("request").description("Request the st
|
|
|
4207
4267
|
if (operation.state === "succeeded") console.log(`✔ Staging is ready. Run \`fluid mist staging status\` for its URL.`);
|
|
4208
4268
|
else console.log(`Requested. Follow it with \`fluid mist staging wait --operation ${operation.id}\`.`);
|
|
4209
4269
|
}));
|
|
4270
|
+
/** This checkout's HEAD, once it is clean and already on the remote's main. */
|
|
4271
|
+
async function localRevision(client, slug) {
|
|
4272
|
+
const { git_credential: credential } = await createGitCredential(client, slug);
|
|
4273
|
+
const revision = await resolveLocalStagingRevision(process.cwd(), credential.remote_url);
|
|
4274
|
+
process.stderr.write(chalk.dim(`Staging this checkout's HEAD, ${revision.slice(0, 7)}.\n`));
|
|
4275
|
+
return revision;
|
|
4276
|
+
}
|
|
4210
4277
|
//#endregion
|
|
4211
4278
|
//#region src/commands/staging/index.ts
|
|
4212
4279
|
/** `fluid mist staging` — sub-command aggregator. */
|