@akanjs/cli 3.1.0-rc.1 → 3.1.0-rc.3
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/.build-stamp +1 -1
- package/{CodeAgent-kyprmy06.js → CodeAgent-ctk4fh2b.js} +2 -2
- package/{CodeTui-21mtze3j.js → CodeTui-mrxtrdzw.js} +1 -1
- package/TunnelShare-rj74jd6x.js +13 -0
- package/{agent.command-f3gsc1gd.js → agent.command-ncre6kwz.js} +5 -5
- package/akanCode.js +2 -2
- package/{application.command-5s780vnz.js → application.command-54mawreg.js} +52 -41
- package/{applicationBuildRunner-1yaqsrdq.js → applicationBuildRunner-8573zr2w.js} +16 -30
- package/buildBatch.proc.js +22 -13
- package/{cloud.command-yj6xb2a7.js → cloud.command-nyemv0m3.js} +57 -65
- package/cloud.script-ht6yb203.js +23 -0
- package/{code.command-3wkn4ja5.js → code.command-spsrzg63.js} +6 -6
- package/{context.command-9jjn3gcw.js → context.command-768zv7z4.js} +16 -13
- package/context.runner-tf1b53qq.js +24 -0
- package/{guideline.command-dtczrqpf.js → guideline.command-4ycwc51q.js} +2 -2
- package/guidelines/conventions/conventions.instruction.md +28 -15
- package/guidelines/cssRule/cssRule.instruction.md +12 -6
- package/guidelines/mcpRule/mcpRule.instruction.md +27 -11
- package/guidelines/runtimeRule/runtimeRule.instruction.md +24 -15
- package/guidelines/transportRule/transportRule.instruction.md +28 -5
- package/incrementalBuilder.proc.js +9 -6
- package/{index-2etcv0sc.js → index-00seamy5.js} +1 -1
- package/{index-jx4bzvwg.js → index-1a7nhq56.js} +92 -52
- package/{index-e0cvze1s.js → index-1nyxvz8j.js} +4 -4
- package/index-2z3kykvd.js +248 -0
- package/{index-rtct7d43.js → index-3675mvjw.js} +1 -1
- package/{index-56d2g8ms.js → index-3ddt3qjg.js} +1 -1
- package/{index-6jjtnhkw.js → index-3x7yeecy.js} +51 -9
- package/{index-ww9bhp67.js → index-4pf8g7ff.js} +1 -1
- package/index-8935h3n1.js +33 -0
- package/{index-v29746vb.js → index-8eqkxwsx.js} +3 -3
- package/{index-c2yrsxdh.js → index-91rt5bye.js} +96 -320
- package/{index-55mynnqs.js → index-bv210r6t.js} +459 -210
- package/{index-c76k723e.js → index-c4h5b5nq.js} +2 -2
- package/{index-qt22xstj.js → index-c9zjb3tw.js} +5 -3
- package/{index-c1x0be5j.js → index-dmsvd2rv.js} +2 -2
- package/index-ec080x99.js +1124 -0
- package/{index-ctanya41.js → index-fjqvd5mx.js} +4 -4
- package/{index-aprt7pkz.js → index-fvn6f5wx.js} +229 -1327
- package/{index-rc5rwyps.js → index-jj7yapwq.js} +71 -60
- package/index-kmamh5bv.js +241 -0
- package/{index-fm46xrf1.js → index-q5abh0jq.js} +3 -3
- package/{index-1w2qaee2.js → index-qf8g88j9.js} +361 -291
- package/{index-gnyf1fqy.js → index-qvghfv6v.js} +2 -2
- package/{index-ae5pwhgs.js → index-r5d6rq19.js} +10 -8
- package/{index-2mx692qq.js → index-vhfjzda3.js} +2 -2
- package/{index-8r4d7cmt.js → index-w9b71b6y.js} +4 -4
- package/{index-8ggztp8k.js → index-wanhh011.js} +42 -177
- package/{index-05g3jayg.js → index-wdze51wz.js} +1 -1
- package/index-wjqbc7sf.js +668 -0
- package/{index-rwq3ekqc.js → index-xf40a295.js} +7 -7
- package/{index-krq7btbt.js → index-xm5tmpv0.js} +3 -3
- package/index.js +22 -22
- package/{library.command-gaga5bmq.js → library.command-88ahgych.js} +3 -3
- package/{localRegistry.command-vsreyy42.js → localRegistry.command-ykea1m7b.js} +12 -9
- package/{module.command-7vpf6db4.js → module.command-zky4b7m9.js} +5 -5
- package/{package.command-twmvvf69.js → package.command-vh8pcedh.js} +3 -3
- package/package.json +2 -2
- package/{page.command-5asq7fdf.js → page.command-fyqeqxc3.js} +3 -3
- package/{pipeline.command-d0v38572.js → pipeline.command-r5t30py6.js} +220 -219
- package/{primitive.command-dyrs2fm8.js → primitive.command-a0516zfk.js} +6 -6
- package/{projectTypecheck-cvtkrzp2.js → projectTypecheck-7djd4z50.js} +1 -1
- package/{quality.command-6emsqpbg.js → quality.command-k7jcnfn0.js} +2 -2
- package/{repair.command-8t6aegv5.js → repair.command-85zg2an3.js} +5 -5
- package/{scalar.command-bnggy1x7.js → scalar.command-g5vmqwca.js} +4 -4
- package/{subspace.command-md2teygq.js → subspace.command-mp4evgsj.js} +421 -362
- package/{tunnel.command-jx3tdm2d.js → tunnel.command-kbnr99sj.js} +7 -4
- package/{workflow.command-jx0wag5r.js → workflow.command-9y9p1n8y.js} +10 -10
- package/{workspace.command-yxd7rr7g.js → workspace.command-jmec2kjg.js} +33 -30
- package/TunnelShare-q4jq08qg.js +0 -9
- package/cloud.script-h6pvcpa2.js +0 -20
- package/context.runner-atcrzz5b.js +0 -21
- package/index-6w0rbr9d.js +0 -68
- package/index-pgj2rt78.js +0 -404
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runner,
|
|
4
4
|
script
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-3x7yeecy.js";
|
|
6
6
|
import {
|
|
7
7
|
FileSys2
|
|
8
8
|
} from "./index-52w0fvh8.js";
|
|
9
9
|
import {
|
|
10
10
|
PkgExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-bv210r6t.js";
|
|
12
12
|
import {
|
|
13
13
|
TypeScriptDependencyScanner2
|
|
14
14
|
} from "./index-2ahj896a.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
AppExecutor
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-bv210r6t.js";
|
|
5
5
|
import {
|
|
6
6
|
jsonText,
|
|
7
7
|
createWorkflowBaselineSummary,
|
|
8
8
|
buildAkanModuleContextIndex,
|
|
9
9
|
toolingRolloutGate
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-wdze51wz.js";
|
|
11
11
|
import {
|
|
12
12
|
buildResourceList,
|
|
13
13
|
codexMcpConfigPath,
|
|
@@ -17,23 +17,25 @@ import {
|
|
|
17
17
|
upsertCodexMcpServerBlock,
|
|
18
18
|
renderDoctorText,
|
|
19
19
|
AkanContextAnalyzer
|
|
20
|
-
} from "./index-
|
|
20
|
+
} from "./index-vhfjzda3.js";
|
|
21
21
|
import {
|
|
22
22
|
runner
|
|
23
|
-
} from "./index-
|
|
23
|
+
} from "./index-3x7yeecy.js";
|
|
24
24
|
import {
|
|
25
|
-
NativeApp,
|
|
26
25
|
isPlaceholderAppId
|
|
27
|
-
} from "./index-
|
|
26
|
+
} from "./index-kmamh5bv.js";
|
|
27
|
+
import {
|
|
28
|
+
NativeApp
|
|
29
|
+
} from "./index-qf8g88j9.js";
|
|
28
30
|
import {
|
|
29
31
|
Prompter2
|
|
30
32
|
} from "./index-zzvvc845.js";
|
|
31
33
|
import {
|
|
32
34
|
RepairRunner
|
|
33
|
-
} from "./index-
|
|
35
|
+
} from "./index-q5abh0jq.js";
|
|
34
36
|
import {
|
|
35
37
|
WorkflowRunner
|
|
36
|
-
} from "./index-
|
|
38
|
+
} from "./index-xf40a295.js";
|
|
37
39
|
import {
|
|
38
40
|
getMobileTargets,
|
|
39
41
|
appIdsOf
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
isScannedRootEntry,
|
|
11
11
|
AppExecutor,
|
|
12
12
|
LibExecutor
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-bv210r6t.js";
|
|
14
14
|
import {
|
|
15
15
|
FileSys2
|
|
16
16
|
} from "./index-52w0fvh8.js";
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
workflowPathsForPlan,
|
|
24
24
|
workflowRunArtifactPath,
|
|
25
25
|
workflowSyncDir
|
|
26
|
-
} from "./index-
|
|
26
|
+
} from "./index-wdze51wz.js";
|
|
27
27
|
|
|
28
28
|
// pkgs/@akanjs/devkit/akanContext.ts
|
|
29
29
|
import { readdir } from "fs/promises";
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
jsonText
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-wdze51wz.js";
|
|
5
5
|
import {
|
|
6
6
|
akanMcpInstallTargets
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-vhfjzda3.js";
|
|
8
8
|
import {
|
|
9
9
|
script
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-3x7yeecy.js";
|
|
11
11
|
import {
|
|
12
12
|
ContextRunner2
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-r5d6rq19.js";
|
|
14
14
|
|
|
15
15
|
// pkgs/@akanjs/cli/context/context.script.ts
|
|
16
16
|
import { Logger } from "akanjs/common";
|
|
@@ -3,24 +3,20 @@ import {
|
|
|
3
3
|
getDefaultHostConfig,
|
|
4
4
|
GlobalConfig,
|
|
5
5
|
CloudApi,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
runner
|
|
10
|
-
} from "./index-6jjtnhkw.js";
|
|
6
|
+
CloudUpdates,
|
|
7
|
+
PipelineSecrets
|
|
8
|
+
} from "./index-wjqbc7sf.js";
|
|
11
9
|
import {
|
|
12
10
|
WorkspaceExecutor,
|
|
13
11
|
AppExecutor
|
|
14
|
-
} from "./index-
|
|
12
|
+
} from "./index-bv210r6t.js";
|
|
15
13
|
import {
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
runner,
|
|
15
|
+
assertPromptable
|
|
16
|
+
} from "./index-3x7yeecy.js";
|
|
18
17
|
import {
|
|
19
18
|
SubspaceConfig
|
|
20
|
-
} from "./index-
|
|
21
|
-
import {
|
|
22
|
-
resolveMobileTargets
|
|
23
|
-
} from "./index-q958tqqg.js";
|
|
19
|
+
} from "./index-4pf8g7ff.js";
|
|
24
20
|
import {
|
|
25
21
|
openBrowser
|
|
26
22
|
} from "./index-9dp031by.js";
|
|
@@ -657,11 +653,9 @@ class PlatformTestRun {
|
|
|
657
653
|
}
|
|
658
654
|
|
|
659
655
|
// pkgs/@akanjs/cli/cloud/cloud.runner.ts
|
|
660
|
-
import { rm } from "fs/promises";
|
|
661
|
-
import os3 from "os";
|
|
662
656
|
import path7 from "path";
|
|
663
|
-
import { confirm, input,
|
|
664
|
-
import { Logger,
|
|
657
|
+
import { confirm, input, select } from "@inquirer/prompts";
|
|
658
|
+
import { Logger, sleep } from "akanjs/common";
|
|
665
659
|
import chalk2 from "chalk";
|
|
666
660
|
import * as QRcode from "qrcode";
|
|
667
661
|
|
|
@@ -766,6 +760,9 @@ class CloudRunner extends runner("cloud") {
|
|
|
766
760
|
return { name: `${name} (${this.#getSshTarget(config)}${config.port ? `:${config.port}` : ""})`, value: name };
|
|
767
761
|
}
|
|
768
762
|
async#getRemoteEnvServerWithUsername() {
|
|
763
|
+
assertPromptable("The env archive goes over scp to a remote server picked here, as AKAN_WORKSPACE_ID is not set", {
|
|
764
|
+
remedy: "set AKAN_WORKSPACE_ID in the workspace .env to use Akan Cloud, or run it once in a terminal"
|
|
765
|
+
});
|
|
769
766
|
const remoteServer = await this.#selectRemoteEnvServer();
|
|
770
767
|
if (remoteServer.config.username)
|
|
771
768
|
return remoteServer;
|
|
@@ -891,6 +888,9 @@ ${run.format(results)}
|
|
|
891
888
|
const reason = result.infraError ?? "failing tests";
|
|
892
889
|
if (!interactive)
|
|
893
890
|
continue;
|
|
891
|
+
assertPromptable(`${result.platform} did not pass (${reason}) \u2014 ${run.logDir}`, {
|
|
892
|
+
remedy: "leave it out of --platforms to publish without it, or run it in a terminal to be asked"
|
|
893
|
+
});
|
|
894
894
|
const proceed = await confirm({
|
|
895
895
|
message: `${result.platform} did not pass (${reason}). Continue without it?`,
|
|
896
896
|
default: false
|
|
@@ -909,6 +909,9 @@ ${run.format(results)}
|
|
|
909
909
|
return results;
|
|
910
910
|
}
|
|
911
911
|
async#askWindowsTestTarget() {
|
|
912
|
+
assertPromptable("No Windows test target is configured", {
|
|
913
|
+
remedy: "run it once in a terminal, which saves the target to ~/.akan/config.json"
|
|
914
|
+
});
|
|
912
915
|
Logger.info("No Windows test target is configured yet; it is saved to ~/.akan/config.json once entered.");
|
|
913
916
|
const required = (value) => !!value.trim();
|
|
914
917
|
const host = await this.#ask("Windows host (ip or name): ", required);
|
|
@@ -944,11 +947,15 @@ ${run.format(results)}
|
|
|
944
947
|
for (const library of akanPkgs) {
|
|
945
948
|
const packageJson = await workspace.readJson(`pkgs/${library}/package.json`);
|
|
946
949
|
const newPackageJson = this.#normalizeAkanPackageJson(packageJson, library, nextVersion);
|
|
947
|
-
await workspace.
|
|
950
|
+
await workspace.writeJson(`pkgs/${library}/package.json`, newPackageJson);
|
|
948
951
|
const distPackageJson = await workspace.readJson(`dist/pkgs/${library}/package.json`);
|
|
949
952
|
const newDistPackageJson = this.#normalizeAkanPackageJson(distPackageJson, library, nextVersion);
|
|
950
953
|
await workspace.writeJson(`dist/pkgs/${library}/package.json`, newDistPackageJson);
|
|
951
954
|
}
|
|
955
|
+
if (confirmPublish)
|
|
956
|
+
assertPromptable(`Publishing ${akanPkgs.join(", ")}@${nextVersion} asks for a confirmation`, {
|
|
957
|
+
remedy: "run it in a terminal"
|
|
958
|
+
});
|
|
952
959
|
if (confirmPublish && !await confirm({ message: "Are you sure you want to deploy the libraries?" })) {
|
|
953
960
|
Logger.error("Deployment cancelled");
|
|
954
961
|
return;
|
|
@@ -1014,7 +1021,7 @@ ${run.format(results)}
|
|
|
1014
1021
|
async downloadEnv(cloudApi, workspace, workspaceId) {
|
|
1015
1022
|
await workspace.mkdir("local");
|
|
1016
1023
|
const localPath = await cloudApi.downloadEnv(workspaceId).catch((error) => {
|
|
1017
|
-
throw
|
|
1024
|
+
throw CloudApi.refusal(error, "downloading its env archive takes the project owner's own `akan login`");
|
|
1018
1025
|
});
|
|
1019
1026
|
const relativePath = path7.relative(workspace.workspaceRoot, localPath).split(path7.sep).join("/");
|
|
1020
1027
|
await workspace.spawn("tar", ["-xf", relativePath], { cwd: workspace.workspaceRoot });
|
|
@@ -1023,7 +1030,7 @@ ${run.format(results)}
|
|
|
1023
1030
|
async uploadEnv(cloudApi, workspaceId, filePath) {
|
|
1024
1031
|
const file = new File([Bun.file(filePath)], path7.basename(filePath));
|
|
1025
1032
|
await cloudApi.uploadEnv(workspaceId, file).catch((error) => {
|
|
1026
|
-
throw
|
|
1033
|
+
throw CloudApi.refusal(error, "an env archive is uploaded by a project member signed in with `akan login`");
|
|
1027
1034
|
});
|
|
1028
1035
|
}
|
|
1029
1036
|
async downloadEnvByScp(workspace) {
|
|
@@ -1096,7 +1103,7 @@ ${run.format(results)}
|
|
|
1096
1103
|
}));
|
|
1097
1104
|
return secretPaths.flat();
|
|
1098
1105
|
}
|
|
1099
|
-
async
|
|
1106
|
+
async projectOf(workspace, subspace, appName) {
|
|
1100
1107
|
if (!subspace) {
|
|
1101
1108
|
const workspaceId = workspace.getWorkspaceId({ allowEmpty: true });
|
|
1102
1109
|
if (!workspaceId)
|
|
@@ -1109,172 +1116,30 @@ ${run.format(results)}
|
|
|
1109
1116
|
const [declaration] = config.select([subspace]);
|
|
1110
1117
|
if (!declaration?.workspaceId)
|
|
1111
1118
|
throw new Error(`Subspace "${subspace}" declares no workspaceId in ${SubspaceConfig.source}.`);
|
|
1119
|
+
if (appName && !declaration.apps.includes(appName))
|
|
1120
|
+
throw new Error(`Subspace "${subspace}" declares no app ${appName} in ${SubspaceConfig.source}; it serves ${declaration.apps.join(", ")}.`);
|
|
1112
1121
|
return declaration.workspaceId;
|
|
1113
1122
|
}
|
|
1114
1123
|
async readSecretValue(name, file) {
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
const bytes = new TextEncoder().encode(value).length;
|
|
1120
|
-
if (bytes > CloudRunner.#secretBytes)
|
|
1121
|
-
throw new Error(`The value of ${name} is ${bytes} bytes, over ${CloudRunner.#secretBytes}.`);
|
|
1122
|
-
return value;
|
|
1123
|
-
}
|
|
1124
|
-
async uploadSecret(cloudApi, devProjectId, { name, branch, value }) {
|
|
1125
|
-
CloudRunner.#assertSecretName(name);
|
|
1126
|
-
CloudRunner.#assertSecretBranch(branch);
|
|
1127
|
-
const saved = await cloudApi.uploadSecret(devProjectId, { scope: branch ?? "*", name, value }).catch((error) => {
|
|
1128
|
-
throw CloudRunner.#refusal(error, "a secret is written by a project member signed in with `akan login`", {
|
|
1129
|
-
unavailable: CloudRunner.#secretsUnavailable
|
|
1130
|
-
});
|
|
1131
|
-
});
|
|
1132
|
-
Logger.rawLog(`Saved ${saved.name} for ${saved.scope === "*" ? "every branch" : `branch ${saved.scope}`}. Builds that start from now on use it.`);
|
|
1124
|
+
return await PipelineSecrets.readValue(name, file);
|
|
1125
|
+
}
|
|
1126
|
+
async uploadSecret(cloudApi, devProjectId, secret) {
|
|
1127
|
+
await new PipelineSecrets(cloudApi, devProjectId).upload(secret);
|
|
1133
1128
|
}
|
|
1134
1129
|
async listSecrets(cloudApi, devProjectId, branch) {
|
|
1135
|
-
|
|
1136
|
-
const listed = await cloudApi.listSecrets(devProjectId).catch((error) => {
|
|
1137
|
-
throw CloudRunner.#refusal(error, "the secrets are listed for a project member", {
|
|
1138
|
-
unavailable: CloudRunner.#secretsUnavailable
|
|
1139
|
-
});
|
|
1140
|
-
});
|
|
1141
|
-
const secrets = listed.filter((secret) => !branch || secret.scope === "*" || secret.scope === branch);
|
|
1142
|
-
Logger.rawLog(CloudRunner.formatSecrets(secrets));
|
|
1143
|
-
}
|
|
1144
|
-
async removeSecret(cloudApi, devProjectId, { name, branch }) {
|
|
1145
|
-
CloudRunner.#assertSecretName(name);
|
|
1146
|
-
CloudRunner.#assertSecretBranch(branch);
|
|
1147
|
-
const removed = await cloudApi.removeSecret(devProjectId, { scope: branch ?? "*", name }).catch((error) => {
|
|
1148
|
-
throw CloudRunner.#refusal(error, "a secret is removed by a project member signed in with `akan login`", {
|
|
1149
|
-
unavailable: CloudRunner.#secretsUnavailable
|
|
1150
|
-
});
|
|
1151
|
-
});
|
|
1152
|
-
Logger.rawLog(removed ? `Removed ${name} for ${branch ? `branch ${branch}` : "every branch"}.` : `No ${name} for ${branch ? `branch ${branch}` : "every branch"} to remove.`);
|
|
1153
|
-
}
|
|
1154
|
-
static #packRecords = ["manifest.template.json", "bundle.json", "pack.json", "compat.json"];
|
|
1155
|
-
static async#tarPack(pack) {
|
|
1156
|
-
const templateFile = Bun.file(path7.join(pack.out, "manifest.template.json"));
|
|
1157
|
-
if (!await templateFile.exists())
|
|
1158
|
-
throw new Error(`${pack.out} holds no manifest.template.json: give the folder \`akan pack-update\` wrote.`);
|
|
1159
|
-
const template = await templateFile.json();
|
|
1160
|
-
const hashes = new Set((template.files ?? []).map((file) => file.sha256));
|
|
1161
|
-
if (![...hashes].every((hash) => typeof hash === "string" && /^[0-9a-f]{64}$/.test(hash)))
|
|
1162
|
-
throw new Error(`${pack.out}/manifest.template.json lists a file whose sha256 is not 64 hex digits.`);
|
|
1163
|
-
const present = await Promise.all(CloudRunner.#packRecords.map((name) => Bun.file(path7.join(pack.out, name)).exists()));
|
|
1164
|
-
const entries = [
|
|
1165
|
-
...CloudRunner.#packRecords.filter((_, idx) => present[idx]),
|
|
1166
|
-
...[...hashes].map((hash) => `files/${hash}`)
|
|
1167
|
-
];
|
|
1168
|
-
const base = path7.join(os3.tmpdir(), `akan-pack-${pack.app}-${pack.target}-${pack.platform}-${process.pid}`);
|
|
1169
|
-
await Bun.write(`${base}.list`, entries.map((entry) => `./${entry}
|
|
1170
|
-
`).join(""));
|
|
1171
|
-
try {
|
|
1172
|
-
const tar = Bun.spawn(["tar", "-czf", `${base}.tgz`, "-C", pack.out, "-T", `${base}.list`], {
|
|
1173
|
-
stdout: "ignore",
|
|
1174
|
-
stderr: "pipe"
|
|
1175
|
-
});
|
|
1176
|
-
if (await tar.exited !== 0)
|
|
1177
|
-
throw new Error(`tar of ${pack.out} failed: ${(await new Response(tar.stderr).text()).trim()}`);
|
|
1178
|
-
} finally {
|
|
1179
|
-
await rm(`${base}.list`, { force: true });
|
|
1180
|
-
}
|
|
1181
|
-
return `${base}.tgz`;
|
|
1130
|
+
await new PipelineSecrets(cloudApi, devProjectId).list(branch);
|
|
1182
1131
|
}
|
|
1183
|
-
async
|
|
1184
|
-
|
|
1185
|
-
const target = channel ?? pack.channel;
|
|
1186
|
-
try {
|
|
1187
|
-
const release = await new UpdatePackUpload(cloudApi, devProjectId).send(archive, { appName: pack.app, target: pack.target, platform: pack.platform, channel: target, notes }).catch((error) => {
|
|
1188
|
-
throw CloudRunner.#refusal(error, "a pack is uploaded by a project member signed in with `akan login`");
|
|
1189
|
-
});
|
|
1190
|
-
const label = `${pack.app} ${pack.target} ${pack.platform} on channel ${target}: release ${release.id}`;
|
|
1191
|
-
if (release.status === "rejected") {
|
|
1192
|
-
process.exitCode = 2;
|
|
1193
|
-
Logger.error(`The project rejected ${label}:
|
|
1194
|
-
${(release.problems ?? []).map((problem) => ` - ${problem}`).join(`
|
|
1195
|
-
`)}`);
|
|
1196
|
-
} else if (release.status === "published")
|
|
1197
|
-
Logger.rawLog(`Published ${label} (${pack.files} files, native API ${pack.nativeApi}).`);
|
|
1198
|
-
else
|
|
1199
|
-
Logger.rawLog(`Staged ${label} (${pack.files} files, native API ${pack.nativeApi}). Publish it from the project's release screen.`);
|
|
1200
|
-
return release;
|
|
1201
|
-
} finally {
|
|
1202
|
-
await rm(archive, { force: true });
|
|
1203
|
-
}
|
|
1132
|
+
async removeSecret(cloudApi, devProjectId, secret) {
|
|
1133
|
+
await new PipelineSecrets(cloudApi, devProjectId).remove(secret);
|
|
1204
1134
|
}
|
|
1205
|
-
async
|
|
1206
|
-
|
|
1207
|
-
if (!mobileTarget)
|
|
1208
|
-
throw new Error(`Native target '${pack.target}' was not found.`);
|
|
1209
|
-
const bundlePath = path7.join(new NativeApp(app, mobileTarget).outDir(pack.platform), "bundle.json");
|
|
1210
|
-
const bundleFile = Bun.file(bundlePath);
|
|
1211
|
-
if (!await bundleFile.exists())
|
|
1212
|
-
throw new Error(`No store build at ${bundlePath}: run \`akan release-${pack.platform} ${app.name} --target ${pack.target} --env ${env}\` first.`);
|
|
1213
|
-
const bundle = await bundleFile.json();
|
|
1214
|
-
if (!bundle.updates)
|
|
1215
|
-
throw new Error(`The store build at ${bundlePath} takes no updates: give the target native.updates.`);
|
|
1216
|
-
if (bundle.nativeApi?.hash !== pack.nativeApi)
|
|
1217
|
-
throw new Error(`The store build at ${bundlePath} provides native API ${bundle.nativeApi?.hash}, and this commit's pack needs ${pack.nativeApi}: build the store binary from this commit.`);
|
|
1218
|
-
const archive = await CloudRunner.#tarPack(pack);
|
|
1219
|
-
const channel = bundle.updates.channel ?? pack.channel;
|
|
1220
|
-
const upload = new UpdatePackUpload(cloudApi, devProjectId);
|
|
1221
|
-
try {
|
|
1222
|
-
const binary = await upload.stage(archive, { appName: pack.app, target: pack.target, platform: pack.platform, channel, notes: null }).then((packUploadId) => upload.settle(() => cloudApi.registerAppBinary(devProjectId, {
|
|
1223
|
-
appName: pack.app,
|
|
1224
|
-
target: pack.target,
|
|
1225
|
-
distribution,
|
|
1226
|
-
bundle: bundleFile,
|
|
1227
|
-
packUploadId,
|
|
1228
|
-
channel
|
|
1229
|
-
}))).catch((error) => {
|
|
1230
|
-
throw CloudRunner.#refusal(error, "a binary is registered by a project member signed in with `akan login`");
|
|
1231
|
-
});
|
|
1232
|
-
Logger.rawLog(`Registered ${pack.app} ${pack.target} ${pack.platform} (${distribution}): binary ${binary.id}, native API ${pack.nativeApi}.`);
|
|
1233
|
-
return binary;
|
|
1234
|
-
} finally {
|
|
1235
|
-
await rm(archive, { force: true });
|
|
1236
|
-
}
|
|
1135
|
+
async readPack(app, dir, flags) {
|
|
1136
|
+
return await CloudUpdates.readPack(app, dir, flags);
|
|
1237
1137
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
return "No pipeline secrets.";
|
|
1241
|
-
const rows = [...secrets].sort((a, b) => a.name.localeCompare(b.name) || a.scope.localeCompare(b.scope)).map((secret) => [
|
|
1242
|
-
secret.name,
|
|
1243
|
-
secret.scope === "*" ? "every branch" : secret.scope,
|
|
1244
|
-
secret.updatedAt,
|
|
1245
|
-
secret.updatedBy
|
|
1246
|
-
]);
|
|
1247
|
-
const header = ["NAME", "SCOPE", "UPDATED", "BY"];
|
|
1248
|
-
const widths = header.map((title, column) => Math.max(title.length, ...rows.map((row) => row[column]?.length ?? 0)));
|
|
1249
|
-
return [header, ...rows].map((row) => row.map((cell, column) => cell.padEnd(widths[column] ?? 0)).join(" ").trimEnd()).join(`
|
|
1250
|
-
`);
|
|
1138
|
+
async pushUpdate(cloudApi, devProjectId, pack, options) {
|
|
1139
|
+
return await new CloudUpdates(cloudApi, devProjectId).push(pack, options);
|
|
1251
1140
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
static #secretsUnavailable = "The server is not configured for pipeline secrets yet.";
|
|
1255
|
-
static #assertSecretName(name) {
|
|
1256
|
-
const problem = PipelineNames.secretNameError(name);
|
|
1257
|
-
if (problem)
|
|
1258
|
-
throw new Error(problem);
|
|
1259
|
-
}
|
|
1260
|
-
static #assertSecretBranch(branch) {
|
|
1261
|
-
if (branch !== null && !CloudRunner.#secretBranches.includes(branch))
|
|
1262
|
-
throw new Error(`--branch ${branch} is not a deployed branch: ${CloudRunner.#secretBranches.join(", ")}.`);
|
|
1263
|
-
}
|
|
1264
|
-
static #refusal(error, who, { unavailable } = {}) {
|
|
1265
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1266
|
-
const status = CloudApi.statusOf(error);
|
|
1267
|
-
if (status === 401)
|
|
1268
|
-
return new Error("The server did not accept your sign-in: run `akan login`, then try again.");
|
|
1269
|
-
if (status === 403)
|
|
1270
|
-
return new Error(`The project refused: ${who}.`);
|
|
1271
|
-
if (status === 400) {
|
|
1272
|
-
const key = /"error"\s*:\s*"([^"]+)"/.exec(message)?.[1];
|
|
1273
|
-
return new Error(`The project refused the request${key ? `: ${key}` : ""}.`);
|
|
1274
|
-
}
|
|
1275
|
-
if (status === 503 && unavailable)
|
|
1276
|
-
return new Error(unavailable);
|
|
1277
|
-
return error;
|
|
1141
|
+
async registerBinary(cloudApi, devProjectId, app, pack, options) {
|
|
1142
|
+
return await new CloudUpdates(cloudApi, devProjectId).registerBinary(app, pack, options);
|
|
1278
1143
|
}
|
|
1279
1144
|
async#syncSecretGitignore(workspace, appNames) {
|
|
1280
1145
|
const patterns = (await Promise.all(appNames.map(async (appName) => {
|