@capuchoo/cli 0.2.0
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 +351 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +5 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +5 -0
- package/dist/base-command.d.ts +15 -0
- package/dist/base-command.d.ts.map +1 -0
- package/dist/base-command.js +61 -0
- package/dist/base-command.js.map +1 -0
- package/dist/commands/auth/login.d.ts +19 -0
- package/dist/commands/auth/login.d.ts.map +1 -0
- package/dist/commands/auth/login.js +74 -0
- package/dist/commands/auth/login.js.map +1 -0
- package/dist/commands/auth/logout.d.ts +6 -0
- package/dist/commands/auth/logout.d.ts.map +1 -0
- package/dist/commands/auth/logout.js +22 -0
- package/dist/commands/auth/logout.js.map +1 -0
- package/dist/commands/auth/whoami.d.ts +9 -0
- package/dist/commands/auth/whoami.d.ts.map +1 -0
- package/dist/commands/auth/whoami.js +77 -0
- package/dist/commands/auth/whoami.js.map +1 -0
- package/dist/commands/channel/list.d.ts +9 -0
- package/dist/commands/channel/list.d.ts.map +1 -0
- package/dist/commands/channel/list.js +47 -0
- package/dist/commands/channel/list.js.map +1 -0
- package/dist/commands/config/list.d.ts +9 -0
- package/dist/commands/config/list.d.ts.map +1 -0
- package/dist/commands/config/list.js +116 -0
- package/dist/commands/config/list.js.map +1 -0
- package/dist/commands/config/set.d.ts +11 -0
- package/dist/commands/config/set.d.ts.map +1 -0
- package/dist/commands/config/set.js +44 -0
- package/dist/commands/config/set.js.map +1 -0
- package/dist/commands/deploy/native.d.ts +23 -0
- package/dist/commands/deploy/native.d.ts.map +1 -0
- package/dist/commands/deploy/native.js +39 -0
- package/dist/commands/deploy/native.js.map +1 -0
- package/dist/commands/deploy/ota.d.ts +20 -0
- package/dist/commands/deploy/ota.d.ts.map +1 -0
- package/dist/commands/deploy/ota.js +20 -0
- package/dist/commands/deploy/ota.js.map +1 -0
- package/dist/commands/init.d.ts +17 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +232 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/version/bump.d.ts +13 -0
- package/dist/commands/version/bump.d.ts.map +1 -0
- package/dist/commands/version/bump.js +52 -0
- package/dist/commands/version/bump.js.map +1 -0
- package/dist/commands/version/sync.d.ts +12 -0
- package/dist/commands/version/sync.d.ts.map +1 -0
- package/dist/commands/version/sync.js +81 -0
- package/dist/commands/version/sync.js.map +1 -0
- package/dist/deploy/execute.d.ts +48 -0
- package/dist/deploy/execute.d.ts.map +1 -0
- package/dist/deploy/execute.js +280 -0
- package/dist/deploy/execute.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/android.d.ts +37 -0
- package/dist/pipeline/android.d.ts.map +1 -0
- package/dist/pipeline/android.js +96 -0
- package/dist/pipeline/android.js.map +1 -0
- package/dist/pipeline/build.d.ts +69 -0
- package/dist/pipeline/build.d.ts.map +1 -0
- package/dist/pipeline/build.js +138 -0
- package/dist/pipeline/build.js.map +1 -0
- package/dist/pipeline/deploy.d.ts +74 -0
- package/dist/pipeline/deploy.d.ts.map +1 -0
- package/dist/pipeline/deploy.js +198 -0
- package/dist/pipeline/deploy.js.map +1 -0
- package/dist/pipeline/flavour.d.ts +66 -0
- package/dist/pipeline/flavour.d.ts.map +1 -0
- package/dist/pipeline/flavour.js +120 -0
- package/dist/pipeline/flavour.js.map +1 -0
- package/dist/pipeline/native-config.d.ts +43 -0
- package/dist/pipeline/native-config.d.ts.map +1 -0
- package/dist/pipeline/native-config.js +127 -0
- package/dist/pipeline/native-config.js.map +1 -0
- package/dist/pipeline/toolchain.d.ts +80 -0
- package/dist/pipeline/toolchain.d.ts.map +1 -0
- package/dist/pipeline/toolchain.js +146 -0
- package/dist/pipeline/toolchain.js.map +1 -0
- package/dist/pipeline/zip.d.ts +22 -0
- package/dist/pipeline/zip.d.ts.map +1 -0
- package/dist/pipeline/zip.js +188 -0
- package/dist/pipeline/zip.js.map +1 -0
- package/dist/services/cloud.d.ts +58 -0
- package/dist/services/cloud.d.ts.map +1 -0
- package/dist/services/cloud.js +89 -0
- package/dist/services/cloud.js.map +1 -0
- package/dist/utils/config.d.ts +52 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +144 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/exec.d.ts +44 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +136 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/http.d.ts +37 -0
- package/dist/utils/http.d.ts.map +1 -0
- package/dist/utils/http.js +137 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/reporter.d.ts +48 -0
- package/dist/utils/reporter.d.ts.map +1 -0
- package/dist/utils/reporter.js +108 -0
- package/dist/utils/reporter.js.map +1 -0
- package/oclif.manifest.json +568 -0
- package/package.json +81 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { run } from "../utils/exec.js";
|
|
4
|
+
import { readScript, resolveBin } from "./toolchain.js";
|
|
5
|
+
/**
|
|
6
|
+
* Generates launcher icons and splash screens.
|
|
7
|
+
*
|
|
8
|
+
* Optional by design: icons rarely change and an app may not ship source
|
|
9
|
+
* artwork at all, so a missing tool or asset directory is a skip, not a
|
|
10
|
+
* failure.
|
|
11
|
+
*/
|
|
12
|
+
export async function generateAssets(context, platform) {
|
|
13
|
+
const { toolchain, flavour } = context;
|
|
14
|
+
if (!flavour.assetPath) {
|
|
15
|
+
return { ran: false, reason: `no asset directory at ${flavour.config.assetPath}` };
|
|
16
|
+
}
|
|
17
|
+
const sources = fs
|
|
18
|
+
.readdirSync(flavour.assetPath)
|
|
19
|
+
.filter((name) => /^(icon|splash)(-dark)?\.(png|svg)$/.test(name));
|
|
20
|
+
if (sources.length === 0) {
|
|
21
|
+
return {
|
|
22
|
+
ran: false,
|
|
23
|
+
reason: `${flavour.config.assetPath} has no icon.png or splash.png`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const bin = resolveBin("capacitor-assets", toolchain.appDir);
|
|
27
|
+
if (!bin) {
|
|
28
|
+
return { ran: false, reason: "@capacitor/assets is not installed" };
|
|
29
|
+
}
|
|
30
|
+
await run(bin, ["generate", `--${platform}`, "--assetPath", flavour.assetPath], {
|
|
31
|
+
...context.runOptions,
|
|
32
|
+
cwd: toolchain.appDir,
|
|
33
|
+
env: context.env,
|
|
34
|
+
});
|
|
35
|
+
return { ran: true, via: "@capacitor/assets" };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Builds the web assets.
|
|
39
|
+
*
|
|
40
|
+
* Resolution order, most explicit first:
|
|
41
|
+
* 1. `build.command` in project.json - the app has said exactly what to run.
|
|
42
|
+
* 2. A `build:<mode>` script, if the app already has one that works.
|
|
43
|
+
* 3. Vite directly, with `--mode <flavour>`.
|
|
44
|
+
*
|
|
45
|
+
* The flavour's variables are passed as environment rather than through
|
|
46
|
+
* `dotenv-cli`, so no extra dependency is needed and the values are identical
|
|
47
|
+
* to the ones the native configuration step receives.
|
|
48
|
+
*/
|
|
49
|
+
export async function buildWeb(context, build) {
|
|
50
|
+
const { toolchain, flavour } = context;
|
|
51
|
+
const cwd = build.cwd ? path.resolve(toolchain.appDir, build.cwd) : toolchain.appDir;
|
|
52
|
+
const options = { ...context.runOptions, cwd, env: context.env };
|
|
53
|
+
if (build.command) {
|
|
54
|
+
const [file, ...args] = tokenize(build.command);
|
|
55
|
+
if (!file)
|
|
56
|
+
throw new Error("build.command in project.json is empty");
|
|
57
|
+
// A workspace-local binary beats whatever is on PATH.
|
|
58
|
+
const resolved = resolveBin(file, toolchain.appDir) ?? file;
|
|
59
|
+
await run(resolved, args, options);
|
|
60
|
+
return { ran: true, via: build.command };
|
|
61
|
+
}
|
|
62
|
+
const scriptName = `build:${flavour.mode}`;
|
|
63
|
+
if (readScript(toolchain.appDir, scriptName)) {
|
|
64
|
+
await run(toolchain.packageManager, ["run", scriptName], options);
|
|
65
|
+
return { ran: true, via: `${toolchain.packageManager} run ${scriptName}` };
|
|
66
|
+
}
|
|
67
|
+
const viteBin = resolveBin("vite", toolchain.appDir);
|
|
68
|
+
if (viteBin) {
|
|
69
|
+
await run(viteBin, ["build", "--mode", flavour.mode], options);
|
|
70
|
+
return { ran: true, via: `vite build --mode ${flavour.mode}` };
|
|
71
|
+
}
|
|
72
|
+
const vpBin = resolveBin("vp", toolchain.appDir);
|
|
73
|
+
if (vpBin) {
|
|
74
|
+
await run(vpBin, ["build", "--mode", flavour.mode], options);
|
|
75
|
+
return { ran: true, via: `vp build --mode ${flavour.mode}` };
|
|
76
|
+
}
|
|
77
|
+
throw new Error("Nothing to build with: no build.command in .capucho/project.json, no " +
|
|
78
|
+
`"${scriptName}" script, and neither vite nor vp is installed.`);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Copies the built web assets into the native project and updates plugins.
|
|
82
|
+
*
|
|
83
|
+
* Runs after the native configuration step, because `cap sync` regenerates
|
|
84
|
+
* plugin registration files and rewriting the identity afterwards would leave
|
|
85
|
+
* those pointing at the previous package name.
|
|
86
|
+
*/
|
|
87
|
+
export async function syncCapacitor(context, platform) {
|
|
88
|
+
const bin = resolveBin("cap", context.toolchain.appDir);
|
|
89
|
+
if (!bin) {
|
|
90
|
+
return { ran: false, reason: "@capacitor/cli is not installed" };
|
|
91
|
+
}
|
|
92
|
+
await run(bin, ["sync", platform], {
|
|
93
|
+
...context.runOptions,
|
|
94
|
+
cwd: context.toolchain.appDir,
|
|
95
|
+
env: context.env,
|
|
96
|
+
});
|
|
97
|
+
return { ran: true, via: `cap sync ${platform}` };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Splits a command string into argv, honouring quoted segments.
|
|
101
|
+
*
|
|
102
|
+
* Needed because `build.command` comes from a config file as one string. The
|
|
103
|
+
* previous code passed such strings straight to a shell, so a path containing a
|
|
104
|
+
* space became two arguments.
|
|
105
|
+
*/
|
|
106
|
+
export function tokenize(command) {
|
|
107
|
+
const tokens = [];
|
|
108
|
+
let current = "";
|
|
109
|
+
let quote = null;
|
|
110
|
+
for (const char of command.trim()) {
|
|
111
|
+
if (quote) {
|
|
112
|
+
if (char === quote)
|
|
113
|
+
quote = null;
|
|
114
|
+
else
|
|
115
|
+
current += char;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (char === '"' || char === "'") {
|
|
119
|
+
quote = char;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (/\s/.test(char)) {
|
|
123
|
+
if (current) {
|
|
124
|
+
tokens.push(current);
|
|
125
|
+
current = "";
|
|
126
|
+
}
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
current += char;
|
|
130
|
+
}
|
|
131
|
+
if (quote) {
|
|
132
|
+
throw new Error(`Unbalanced ${quote} in command: ${command}`);
|
|
133
|
+
}
|
|
134
|
+
if (current)
|
|
135
|
+
tokens.push(current);
|
|
136
|
+
return tokens;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/pipeline/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAmB,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAkB,MAAM,gBAAgB,CAAC;AAwBxE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAoB,EACpB,QAA2B;IAE3B,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAEvC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;IACrF,CAAC;IAED,MAAM,OAAO,GAAG,EAAE;SACf,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC;SAC9B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,oCAAoC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAErE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,GAAG,EAAE,KAAK;YACV,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,gCAAgC;SACpE,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,kBAAkB,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC;IACtE,CAAC;IAED,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,KAAK,QAAQ,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE;QAC9E,GAAG,OAAO,CAAC,UAAU;QACrB,GAAG,EAAE,SAAS,CAAC,MAAM;QACrB,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,mBAAmB,EAAE,CAAC;AACjD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAAoB,EACpB,KAAyC;IAEzC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACvC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;IAErF,MAAM,OAAO,GAAG,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;IAEjE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAErE,sDAAsD;QACtD,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;QAC5D,MAAM,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,UAAU,GAAG,SAAS,OAAO,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;QAC7C,MAAM,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;QAClE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,cAAc,QAAQ,UAAU,EAAE,EAAE,CAAC;IAC7E,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACrD,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,qBAAqB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;IACjE,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAC7D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,mBAAmB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;IAC/D,CAAC;IAED,MAAM,IAAI,KAAK,CACb,uEAAuE;QACrE,IAAI,UAAU,iDAAiD,CAClE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAoB,EACpB,QAA2B;IAE3B,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACxD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;IACnE,CAAC;IAED,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;QACjC,GAAG,OAAO,CAAC,UAAU;QACrB,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM;QAC7B,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,YAAY,QAAQ,EAAE,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,KAAK,GAAqB,IAAI,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,IAAI,KAAK,KAAK;gBAAE,KAAK,GAAG,IAAI,CAAC;;gBAC5B,OAAO,IAAI,IAAI,CAAC;YACrB,SAAS;QACX,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjC,KAAK,GAAG,IAAI,CAAC;YACb,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACrB,OAAO,GAAG,EAAE,CAAC;YACf,CAAC;YACD,SAAS;QACX,CAAC;QAED,OAAO,IAAI,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,gBAAgB,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type Environment, type ResolvedProjectConfig } from "@capuchoo/core";
|
|
2
|
+
import { Reporter, type Step } from "../utils/reporter.js";
|
|
3
|
+
import { type BuildType } from "./android.js";
|
|
4
|
+
import { type ResolvedFlavour } from "./flavour.js";
|
|
5
|
+
/**
|
|
6
|
+
* The deploy pipeline.
|
|
7
|
+
*
|
|
8
|
+
* One code path for OTA and native deploys, and one place where the step list
|
|
9
|
+
* is decided. The steps that will run are computed *before* anything executes,
|
|
10
|
+
* which is what makes the progress numbers true and lets the whole thing be
|
|
11
|
+
* validated with `--dry-run` without touching the project.
|
|
12
|
+
*/
|
|
13
|
+
export type DeployKind = "ota" | "native";
|
|
14
|
+
export type Platform = "android" | "ios";
|
|
15
|
+
export interface DeployRequest {
|
|
16
|
+
appDir: string;
|
|
17
|
+
project: ResolvedProjectConfig;
|
|
18
|
+
kind: DeployKind;
|
|
19
|
+
platform: Platform;
|
|
20
|
+
channel: string;
|
|
21
|
+
environment: Environment;
|
|
22
|
+
/** Semantic version being published, already bumped if requested. */
|
|
23
|
+
version: string;
|
|
24
|
+
buildType: BuildType;
|
|
25
|
+
skipAssets: boolean;
|
|
26
|
+
skipBuild: boolean;
|
|
27
|
+
allowUnsigned: boolean;
|
|
28
|
+
dryRun: boolean;
|
|
29
|
+
verbose: boolean;
|
|
30
|
+
quiet: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface DeployArtifact {
|
|
33
|
+
kind: DeployKind;
|
|
34
|
+
filePath: string;
|
|
35
|
+
byteSize: number;
|
|
36
|
+
/** Native only. */
|
|
37
|
+
signed?: boolean;
|
|
38
|
+
/** OTA only. */
|
|
39
|
+
fileCount?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface DeployOutcome {
|
|
42
|
+
version: string;
|
|
43
|
+
versionCode: number;
|
|
44
|
+
environment: Environment;
|
|
45
|
+
artifact: DeployArtifact | null;
|
|
46
|
+
nativeConfigMethod: string;
|
|
47
|
+
warnings: string[];
|
|
48
|
+
/** Steps that were planned but skipped, with reasons. */
|
|
49
|
+
skipped: Array<{
|
|
50
|
+
step: string;
|
|
51
|
+
reason: string;
|
|
52
|
+
}>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Builds the step list for a request.
|
|
56
|
+
*
|
|
57
|
+
* Conditional work is resolved here rather than inside the run loop, so a
|
|
58
|
+
* skipped step never leaves a gap in the numbering.
|
|
59
|
+
*/
|
|
60
|
+
export declare function planSteps(request: DeployRequest): Step[];
|
|
61
|
+
/**
|
|
62
|
+
* Checks the request against the project before any work happens.
|
|
63
|
+
*
|
|
64
|
+
* Cheap validation up front matters more than it sounds: the old pipeline
|
|
65
|
+
* bumped the version in `package.json` as step 1, then discovered a missing env
|
|
66
|
+
* file at step 2, leaving the repository holding a version that was never
|
|
67
|
+
* published.
|
|
68
|
+
*/
|
|
69
|
+
export declare function validateRequest(request: DeployRequest, flavour: ResolvedFlavour): string[];
|
|
70
|
+
export declare function runDeploy(request: DeployRequest, reporter: Reporter): Promise<DeployOutcome>;
|
|
71
|
+
export declare function formatBytes(bytes: number): string;
|
|
72
|
+
/** Turns a pipeline failure into something worth printing. */
|
|
73
|
+
export declare function describeFailure(error: unknown, appDir: string): string;
|
|
74
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/pipeline/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAA2C,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAEvF,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,cAAc,CAAC;AAKtB;;;;;;;GAOG;AAEH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,CAAC;AAC1C,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,qBAAqB,CAAC;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;IACzB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gBAAgB;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,yDAAyD;IACzD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAID;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,EAAE,CAuBxD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAkC1F;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,aAAa,CAAC,CA8IxB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKtE"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { describeEnvironmentMismatch, } from "@capuchoo/core";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { CommandError } from "../utils/exec.js";
|
|
5
|
+
import { Reporter } from "../utils/reporter.js";
|
|
6
|
+
import { assembleAndroid, collectAndroidArtifact } from "./android.js";
|
|
7
|
+
import { buildWeb, generateAssets, syncCapacitor } from "./build.js";
|
|
8
|
+
import { buildEnvironment, describeFlavourProblems, resolveFlavour, resolveVersionState, writeVersionCodes, } from "./flavour.js";
|
|
9
|
+
import { applyNativeConfig, builtinConfigLimitations } from "./native-config.js";
|
|
10
|
+
import { detectToolchain } from "./toolchain.js";
|
|
11
|
+
import { bundleFileName, createBundleZip } from "./zip.js";
|
|
12
|
+
const LOG_FILE = "capuchoo-deploy.log";
|
|
13
|
+
/**
|
|
14
|
+
* Builds the step list for a request.
|
|
15
|
+
*
|
|
16
|
+
* Conditional work is resolved here rather than inside the run loop, so a
|
|
17
|
+
* skipped step never leaves a gap in the numbering.
|
|
18
|
+
*/
|
|
19
|
+
export function planSteps(request) {
|
|
20
|
+
const steps = [{ id: "resolve", label: "Resolving flavour and version" }];
|
|
21
|
+
if (!request.skipBuild) {
|
|
22
|
+
if (!request.skipAssets) {
|
|
23
|
+
steps.push({ id: "assets", label: "Generating launcher assets" });
|
|
24
|
+
}
|
|
25
|
+
steps.push({ id: "web", label: "Building web assets" });
|
|
26
|
+
steps.push({ id: "native-config", label: "Applying native configuration" });
|
|
27
|
+
steps.push({ id: "sync", label: "Syncing Capacitor" });
|
|
28
|
+
}
|
|
29
|
+
steps.push(request.kind === "ota"
|
|
30
|
+
? { id: "bundle", label: "Packaging OTA bundle" }
|
|
31
|
+
: { id: "compile", label: `Compiling ${request.platform} (${request.buildType})` });
|
|
32
|
+
if (!request.dryRun) {
|
|
33
|
+
steps.push({ id: "upload", label: "Uploading to Capucho" });
|
|
34
|
+
}
|
|
35
|
+
return steps;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Checks the request against the project before any work happens.
|
|
39
|
+
*
|
|
40
|
+
* Cheap validation up front matters more than it sounds: the old pipeline
|
|
41
|
+
* bumped the version in `package.json` as step 1, then discovered a missing env
|
|
42
|
+
* file at step 2, leaving the repository holding a version that was never
|
|
43
|
+
* published.
|
|
44
|
+
*/
|
|
45
|
+
export function validateRequest(request, flavour) {
|
|
46
|
+
const problems = describeFlavourProblems(flavour);
|
|
47
|
+
const declaredAppId = flavour.fileEnv.VITE_APP_ID;
|
|
48
|
+
if (declaredAppId) {
|
|
49
|
+
// Uses the shared rule rather than a plain equality check, so the CLI
|
|
50
|
+
// rejects exactly what the server rejects and nothing more. A production
|
|
51
|
+
// build on a staging channel is deliberately allowed - that is how a
|
|
52
|
+
// release candidate gets beta-tested - and an equality check here blocked
|
|
53
|
+
// it, which is a legitimate setup the CLI has no business refusing.
|
|
54
|
+
const mismatch = describeEnvironmentMismatch(declaredAppId, request.environment, request.channel);
|
|
55
|
+
if (mismatch)
|
|
56
|
+
problems.push(`${mismatch} (from ${flavour.config.envFile})`);
|
|
57
|
+
}
|
|
58
|
+
if (request.kind === "native" && request.platform === "ios") {
|
|
59
|
+
problems.push("iOS native builds are not driven by this CLI yet - archive and upload " +
|
|
60
|
+
"through Xcode, then register the build in the dashboard.");
|
|
61
|
+
}
|
|
62
|
+
const webDir = path.resolve(request.appDir, request.project.webDir);
|
|
63
|
+
if (request.skipBuild && !fs.existsSync(webDir)) {
|
|
64
|
+
problems.push(`--skip-build was passed but ${request.project.webDir} does not exist, ` +
|
|
65
|
+
"so there is nothing to publish.");
|
|
66
|
+
}
|
|
67
|
+
return problems;
|
|
68
|
+
}
|
|
69
|
+
export async function runDeploy(request, reporter) {
|
|
70
|
+
const warnings = [];
|
|
71
|
+
const skipped = [];
|
|
72
|
+
const toolchain = detectToolchain(request.appDir);
|
|
73
|
+
const flavour = resolveFlavour(request.appDir, request.project, request.environment);
|
|
74
|
+
const problems = validateRequest(request, flavour);
|
|
75
|
+
if (problems.length > 0) {
|
|
76
|
+
throw new Error(`This deploy cannot proceed:\n - ${problems.join("\n - ")}`);
|
|
77
|
+
}
|
|
78
|
+
reporter.plan(planSteps(request));
|
|
79
|
+
// Only a native build changes the installed binary, so only a native build
|
|
80
|
+
// needs a new versionCode.
|
|
81
|
+
const state = resolveVersionState(request.appDir, request.project, request.environment, request.version, request.kind === "native");
|
|
82
|
+
const env = buildEnvironment(flavour, state);
|
|
83
|
+
const runOptions = {
|
|
84
|
+
logFile: path.join(request.appDir, LOG_FILE),
|
|
85
|
+
verbose: request.verbose,
|
|
86
|
+
};
|
|
87
|
+
const context = { toolchain, flavour, env, runOptions };
|
|
88
|
+
reporter.begin("resolve");
|
|
89
|
+
reporter.note(`${request.environment} flavour, v${state.version} (build ${state.versionCode}), ` +
|
|
90
|
+
`${toolchain.packageManager} workspace`);
|
|
91
|
+
let nativeConfigMethod = "not run";
|
|
92
|
+
if (!request.skipBuild) {
|
|
93
|
+
if (!request.skipAssets) {
|
|
94
|
+
reporter.begin("assets");
|
|
95
|
+
const outcome = await generateAssets(context, request.platform);
|
|
96
|
+
if (!outcome.ran) {
|
|
97
|
+
reporter.skip(outcome.reason);
|
|
98
|
+
skipped.push({ step: "assets", reason: outcome.reason });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
reporter.begin("web");
|
|
102
|
+
const web = await buildWeb(context, request.project.build);
|
|
103
|
+
if (web.ran)
|
|
104
|
+
reporter.note(web.via);
|
|
105
|
+
reporter.begin("native-config");
|
|
106
|
+
const nativeConfig = await applyNativeConfig({
|
|
107
|
+
appDir: request.appDir,
|
|
108
|
+
androidDir: request.project.androidDir,
|
|
109
|
+
iosDir: request.project.iosDir,
|
|
110
|
+
flavour,
|
|
111
|
+
env,
|
|
112
|
+
platform: request.platform,
|
|
113
|
+
runOptions,
|
|
114
|
+
});
|
|
115
|
+
nativeConfigMethod = nativeConfig.method;
|
|
116
|
+
if (nativeConfig.method === "trapeze") {
|
|
117
|
+
reporter.note("Trapeze applied the flavour configuration");
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
reporter.note(`Built-in configuration (${nativeConfig.reason}): ` +
|
|
121
|
+
`${nativeConfig.changed.length} file(s) updated`);
|
|
122
|
+
for (const limitation of builtinConfigLimitations(request.platform)) {
|
|
123
|
+
warnings.push(limitation);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
reporter.begin("sync");
|
|
127
|
+
const sync = await syncCapacitor(context, request.platform);
|
|
128
|
+
if (!sync.ran) {
|
|
129
|
+
reporter.skip(sync.reason);
|
|
130
|
+
skipped.push({ step: "sync", reason: sync.reason });
|
|
131
|
+
warnings.push("Capacitor sync did not run, so the native project may still hold the " +
|
|
132
|
+
"previous build's web assets");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
skipped.push({ step: "build", reason: "--skip-build" });
|
|
137
|
+
}
|
|
138
|
+
let artifact = null;
|
|
139
|
+
if (request.kind === "ota") {
|
|
140
|
+
reporter.begin("bundle");
|
|
141
|
+
const webDir = path.resolve(request.appDir, request.project.webDir);
|
|
142
|
+
const outFile = path.join(request.appDir, bundleFileName(request.project.appId, state.version));
|
|
143
|
+
const bundle = createBundleZip({ webDir, outFile });
|
|
144
|
+
reporter.note(`${bundle.fileCount} files, ${formatBytes(bundle.byteSize)} -> ${path.basename(bundle.zipPath)}`);
|
|
145
|
+
artifact = {
|
|
146
|
+
kind: "ota",
|
|
147
|
+
filePath: bundle.zipPath,
|
|
148
|
+
byteSize: bundle.byteSize,
|
|
149
|
+
fileCount: bundle.fileCount,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
reporter.begin("compile");
|
|
154
|
+
const androidDir = path.resolve(request.appDir, request.project.androidDir);
|
|
155
|
+
await assembleAndroid(androidDir, request.buildType, runOptions);
|
|
156
|
+
const built = collectAndroidArtifact(androidDir, request.buildType, request.allowUnsigned);
|
|
157
|
+
reporter.note(`${path.basename(built.apkPath)}, ${formatBytes(built.byteSize)}` +
|
|
158
|
+
(built.signed ? "" : " (unsigned)"));
|
|
159
|
+
if (!built.signed) {
|
|
160
|
+
warnings.push("This artefact is not signed. Android will not install it as-is.");
|
|
161
|
+
}
|
|
162
|
+
artifact = {
|
|
163
|
+
kind: "native",
|
|
164
|
+
filePath: built.apkPath,
|
|
165
|
+
byteSize: built.byteSize,
|
|
166
|
+
signed: built.signed,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// The version code is persisted only once the artefact exists, so a failed
|
|
170
|
+
// build does not consume a build number.
|
|
171
|
+
if (request.kind === "native" && !request.dryRun) {
|
|
172
|
+
writeVersionCodes(request.appDir, request.project, state.codes);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
version: state.version,
|
|
176
|
+
versionCode: state.versionCode,
|
|
177
|
+
environment: request.environment,
|
|
178
|
+
artifact,
|
|
179
|
+
nativeConfigMethod,
|
|
180
|
+
warnings,
|
|
181
|
+
skipped,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
export function formatBytes(bytes) {
|
|
185
|
+
if (bytes < 1024)
|
|
186
|
+
return `${bytes} B`;
|
|
187
|
+
if (bytes < 1024 * 1024)
|
|
188
|
+
return `${(bytes / 1024).toFixed(1)} KiB`;
|
|
189
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;
|
|
190
|
+
}
|
|
191
|
+
/** Turns a pipeline failure into something worth printing. */
|
|
192
|
+
export function describeFailure(error, appDir) {
|
|
193
|
+
if (error instanceof CommandError) {
|
|
194
|
+
return `${error.message}\n\n Full output: ${path.join(appDir, LOG_FILE)}`;
|
|
195
|
+
}
|
|
196
|
+
return error instanceof Error ? error.message : String(error);
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/pipeline/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type Environment, type FlavourConfig, type ResolvedProjectConfig, type VersionCodes } from "@capuchoo/core";
|
|
2
|
+
/**
|
|
3
|
+
* Resolves everything a single build flavour needs.
|
|
4
|
+
*
|
|
5
|
+
* The previous implementation rewrote `VITE_APP_VERSION`, `VERSION_CODE` and
|
|
6
|
+
* `BUILD_NUMBER` *into* the committed `build/<env>/.env.<env>` file on every
|
|
7
|
+
* deploy. That had three consequences: every deploy left the working tree
|
|
8
|
+
* dirty, two deploys running at once corrupted each other's values, and a
|
|
9
|
+
* failed deploy left the file holding a version that was never published.
|
|
10
|
+
*
|
|
11
|
+
* Here the env file is read and never written. The computed values are merged
|
|
12
|
+
* on top in memory and handed to the build and to Trapeze as environment
|
|
13
|
+
* variables - which is where both of them look anyway.
|
|
14
|
+
*/
|
|
15
|
+
export interface ResolvedFlavour {
|
|
16
|
+
environment: Environment;
|
|
17
|
+
config: FlavourConfig;
|
|
18
|
+
/** Absolute path, or null when the flavour declares none. */
|
|
19
|
+
envFile: string | null;
|
|
20
|
+
trapezeConfig: string | null;
|
|
21
|
+
assetPath: string | null;
|
|
22
|
+
/** Values parsed from the env file. */
|
|
23
|
+
fileEnv: Record<string, string>;
|
|
24
|
+
/** Vite mode for this flavour. */
|
|
25
|
+
mode: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parses a dotenv file.
|
|
29
|
+
*
|
|
30
|
+
* Deliberately small and dependency-free: `KEY=value`, `#` comments, optional
|
|
31
|
+
* surrounding quotes, `export ` prefix tolerated. Anything more exotic belongs
|
|
32
|
+
* in the app's own tooling, not in a deploy tool.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseEnvFile(contents: string): Record<string, string>;
|
|
35
|
+
export declare function resolveFlavour(appDir: string, project: ResolvedProjectConfig, environment: Environment): ResolvedFlavour;
|
|
36
|
+
/**
|
|
37
|
+
* Problems that make a flavour unbuildable, as actionable messages.
|
|
38
|
+
*
|
|
39
|
+
* The old `syncVersion` threw `Env file for staging not found` from deep inside
|
|
40
|
+
* the pipeline, *after* the version had been bumped. Checking up front means a
|
|
41
|
+
* misconfigured flavour costs nothing.
|
|
42
|
+
*/
|
|
43
|
+
export declare function describeFlavourProblems(flavour: ResolvedFlavour): string[];
|
|
44
|
+
export interface VersionState {
|
|
45
|
+
/** Semantic version from the app's package.json. */
|
|
46
|
+
version: string;
|
|
47
|
+
versionCode: number;
|
|
48
|
+
codes: VersionCodes;
|
|
49
|
+
}
|
|
50
|
+
export declare function readVersionCodes(appDir: string, project: ResolvedProjectConfig): VersionCodes;
|
|
51
|
+
export declare function writeVersionCodes(appDir: string, project: ResolvedProjectConfig, codes: VersionCodes): void;
|
|
52
|
+
/**
|
|
53
|
+
* Computes the version state for a deploy.
|
|
54
|
+
*
|
|
55
|
+
* `bumpCode` should be true for a native build - Android refuses an APK whose
|
|
56
|
+
* versionCode did not increase - and false for an OTA bundle, which does not
|
|
57
|
+
* change the installed binary.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolveVersionState(appDir: string, project: ResolvedProjectConfig, environment: Environment, version: string, bumpCode: boolean): VersionState;
|
|
60
|
+
/**
|
|
61
|
+
* The environment a build step runs with: the flavour's own values, plus the
|
|
62
|
+
* resolved version. Version values win, because they are computed for *this*
|
|
63
|
+
* deploy while the file holds whatever the last one left behind.
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildEnvironment(flavour: ResolvedFlavour, state: VersionState): Record<string, string>;
|
|
66
|
+
//# sourceMappingURL=flavour.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flavour.d.ts","sourceRoot":"","sources":["../../src/pipeline/flavour.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAIxB;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA8BrE;AAQD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,EAC9B,WAAW,EAAE,WAAW,GACvB,eAAe,CAajB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAsB1E;AAED,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,YAAY,CAY7F;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,YAAY,GAClB,IAAI,CAGN;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,EAC9B,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,GAChB,YAAY,CAKd;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,YAAY,GAClB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKxB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { INITIAL_VERSION_CODES, nextVersionCode, versionEnv, } from "@capuchoo/core";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* Parses a dotenv file.
|
|
6
|
+
*
|
|
7
|
+
* Deliberately small and dependency-free: `KEY=value`, `#` comments, optional
|
|
8
|
+
* surrounding quotes, `export ` prefix tolerated. Anything more exotic belongs
|
|
9
|
+
* in the app's own tooling, not in a deploy tool.
|
|
10
|
+
*/
|
|
11
|
+
export function parseEnvFile(contents) {
|
|
12
|
+
const values = {};
|
|
13
|
+
for (const rawLine of contents.split(/\r?\n/)) {
|
|
14
|
+
const line = rawLine.trim();
|
|
15
|
+
if (!line || line.startsWith("#"))
|
|
16
|
+
continue;
|
|
17
|
+
const withoutExport = line.startsWith("export ") ? line.slice(7).trim() : line;
|
|
18
|
+
const separator = withoutExport.indexOf("=");
|
|
19
|
+
if (separator <= 0)
|
|
20
|
+
continue;
|
|
21
|
+
const key = withoutExport.slice(0, separator).trim();
|
|
22
|
+
if (!/^[A-Za-z_]\w*$/.test(key))
|
|
23
|
+
continue;
|
|
24
|
+
let value = withoutExport.slice(separator + 1).trim();
|
|
25
|
+
if ((value.startsWith('"') && value.endsWith('"') && value.length > 1) ||
|
|
26
|
+
(value.startsWith("'") && value.endsWith("'") && value.length > 1)) {
|
|
27
|
+
value = value.slice(1, -1);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// Strip a trailing inline comment on unquoted values only.
|
|
31
|
+
const comment = value.indexOf(" #");
|
|
32
|
+
if (comment >= 0)
|
|
33
|
+
value = value.slice(0, comment).trimEnd();
|
|
34
|
+
}
|
|
35
|
+
values[key] = value;
|
|
36
|
+
}
|
|
37
|
+
return values;
|
|
38
|
+
}
|
|
39
|
+
function existingPath(appDir, relative) {
|
|
40
|
+
if (!relative)
|
|
41
|
+
return null;
|
|
42
|
+
const absolute = path.resolve(appDir, relative);
|
|
43
|
+
return fs.existsSync(absolute) ? absolute : null;
|
|
44
|
+
}
|
|
45
|
+
export function resolveFlavour(appDir, project, environment) {
|
|
46
|
+
const config = project.flavours[environment];
|
|
47
|
+
const envFile = existingPath(appDir, config.envFile);
|
|
48
|
+
return {
|
|
49
|
+
environment,
|
|
50
|
+
config,
|
|
51
|
+
envFile,
|
|
52
|
+
trapezeConfig: existingPath(appDir, config.trapezeConfig),
|
|
53
|
+
assetPath: existingPath(appDir, config.assetPath),
|
|
54
|
+
fileEnv: envFile ? parseEnvFile(fs.readFileSync(envFile, "utf8")) : {},
|
|
55
|
+
mode: config.mode ?? environment,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Problems that make a flavour unbuildable, as actionable messages.
|
|
60
|
+
*
|
|
61
|
+
* The old `syncVersion` threw `Env file for staging not found` from deep inside
|
|
62
|
+
* the pipeline, *after* the version had been bumped. Checking up front means a
|
|
63
|
+
* misconfigured flavour costs nothing.
|
|
64
|
+
*/
|
|
65
|
+
export function describeFlavourProblems(flavour) {
|
|
66
|
+
const problems = [];
|
|
67
|
+
if (!flavour.envFile) {
|
|
68
|
+
problems.push(`No env file at "${flavour.config.envFile}" for the ${flavour.environment} flavour. ` +
|
|
69
|
+
"Create it, or point the flavour at another path in .capucho/project.json.");
|
|
70
|
+
return problems;
|
|
71
|
+
}
|
|
72
|
+
if (!flavour.fileEnv.VITE_APP_ID) {
|
|
73
|
+
problems.push(`${flavour.config.envFile} does not set VITE_APP_ID`);
|
|
74
|
+
}
|
|
75
|
+
if (!flavour.fileEnv.VITE_UPDATE_API_URL) {
|
|
76
|
+
problems.push(`${flavour.config.envFile} does not set VITE_UPDATE_API_URL, so the built app ` +
|
|
77
|
+
"would ship with updates disabled");
|
|
78
|
+
}
|
|
79
|
+
return problems;
|
|
80
|
+
}
|
|
81
|
+
export function readVersionCodes(appDir, project) {
|
|
82
|
+
const file = path.resolve(appDir, project.versionCodeFile);
|
|
83
|
+
if (!fs.existsSync(file))
|
|
84
|
+
return { ...INITIAL_VERSION_CODES };
|
|
85
|
+
try {
|
|
86
|
+
const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
87
|
+
return { ...INITIAL_VERSION_CODES, ...parsed };
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
throw new Error(`${project.versionCodeFile} is not valid JSON. Fix or delete it before deploying.`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function writeVersionCodes(appDir, project, codes) {
|
|
94
|
+
const file = path.resolve(appDir, project.versionCodeFile);
|
|
95
|
+
fs.writeFileSync(file, `${JSON.stringify(codes, null, 2)}\n`);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Computes the version state for a deploy.
|
|
99
|
+
*
|
|
100
|
+
* `bumpCode` should be true for a native build - Android refuses an APK whose
|
|
101
|
+
* versionCode did not increase - and false for an OTA bundle, which does not
|
|
102
|
+
* change the installed binary.
|
|
103
|
+
*/
|
|
104
|
+
export function resolveVersionState(appDir, project, environment, version, bumpCode) {
|
|
105
|
+
const current = readVersionCodes(appDir, project);
|
|
106
|
+
const codes = bumpCode ? nextVersionCode(current, environment) : current;
|
|
107
|
+
return { version, versionCode: codes[environment], codes };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The environment a build step runs with: the flavour's own values, plus the
|
|
111
|
+
* resolved version. Version values win, because they are computed for *this*
|
|
112
|
+
* deploy while the file holds whatever the last one left behind.
|
|
113
|
+
*/
|
|
114
|
+
export function buildEnvironment(flavour, state) {
|
|
115
|
+
return {
|
|
116
|
+
...flavour.fileEnv,
|
|
117
|
+
...versionEnv(state.version, state.versionCode),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=flavour.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flavour.js","sourceRoot":"","sources":["../../src/pipeline/flavour.ts"],"names":[],"mappings":"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"}
|