liftbay 0.5.0 → 0.5.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.
package/dist/index.js CHANGED
@@ -25969,7 +25969,7 @@ import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync }
25969
25969
  import { homedir } from "os";
25970
25970
  import { join } from "path";
25971
25971
 
25972
- // ../sdk/node_modules/openapi-fetch/dist/index.mjs
25972
+ // node_modules/openapi-fetch/dist/index.mjs
25973
25973
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
25974
25974
  var supportsRequestInitExt = () => {
25975
25975
  return typeof process === "object" && Number.parseInt(process?.versions?.node?.substring(0, 2)) >= 18 && process.versions.undici;
@@ -26445,7 +26445,7 @@ function removeTrailingSlash(url) {
26445
26445
  return url;
26446
26446
  }
26447
26447
 
26448
- // ../sdk/dist/index.js
26448
+ // node_modules/@liftbay/sdk/dist/index.js
26449
26449
  var LiftbayApiError = class extends Error {
26450
26450
  constructor(status2, code, message, fields = {}) {
26451
26451
  super(message);
@@ -29206,7 +29206,7 @@ async function readyToBuild(branch, interactive) {
29206
29206
  }
29207
29207
  }
29208
29208
  async function build(opts) {
29209
- let config = requireConfig();
29209
+ const config = requireConfig();
29210
29210
  const lb = client();
29211
29211
  const interactive = isInteractive();
29212
29212
  const path2 = { org: config.org, project: config.project };
@@ -29247,25 +29247,26 @@ async function build(opts) {
29247
29247
  platforms = choice === "all" ? profile.platforms : [choice];
29248
29248
  } else platforms = profile.platforms;
29249
29249
  const storeIos = platforms.includes("ios") && !opts.simulator && profile.distribution === "store";
29250
- let iosEngine = opts.engine ?? config.build?.iosEngine ?? "auto";
29250
+ let iosEngine = opts.engine ?? "auto";
29251
29251
  if (!storeIos && iosEngine === "xcode-cloud") {
29252
- if (opts.engine === "xcode-cloud") fail(`Xcode Cloud makes iOS store builds only; profile "${profileName}" is ${opts.simulator ? "a simulator" : `an ${profile.distribution}`} build. Use a store profile, or --engine github-actions.`);
29253
- iosEngine = "github-actions";
29252
+ fail(`Xcode Cloud makes iOS store builds only; profile "${profileName}" is ${opts.simulator ? "a simulator" : `an ${profile.distribution}`} build. Use a store profile, or --engine github-actions.`);
29254
29253
  }
29255
29254
  if (storeIos) {
29256
- if (!opts.engine && !config.build?.iosEngine && interactive) {
29255
+ if (!opts.engine && interactive) {
29256
+ const setting = (await unwrap(lb.GET("/v1/orgs/{org}/projects/{project}", { params: { path: path2 } }))).iosEngine ?? "github-actions";
29257
+ const label = (e) => e === "xcode-cloud" ? "Xcode Cloud" : "GitHub Actions";
29257
29258
  iosEngine = cancelled(
29258
29259
  await select({
29259
- message: "Where should iOS builds run?",
29260
- options: [
29261
- { value: "github-actions", label: "GitHub Actions", hint: "macOS runners on your GitHub minutes" },
29262
- { value: "xcode-cloud", label: "Xcode Cloud", hint: "25 free hours a month with the Apple Developer Program" }
29263
- ]
29260
+ message: "Where should this iOS build run?",
29261
+ options: ["github-actions", "xcode-cloud"].map((e) => ({
29262
+ value: e,
29263
+ label: label(e),
29264
+ hint: [e === setting ? "project default" : "", e === "xcode-cloud" ? "25 free hours a month with the Apple Developer Program" : "macOS runners on your GitHub minutes"].filter(Boolean).join(" \xB7 ")
29265
+ })),
29266
+ initialValue: setting
29264
29267
  })
29265
29268
  );
29266
- config = { ...config, build: { ...config.build, iosEngine } };
29267
- writeConfig(config);
29268
- log.info(import_picocolors7.default.dim("Saved in liftbay.json (commit it). Override once with --engine."));
29269
+ if (iosEngine !== setting) log.info(import_picocolors7.default.dim(`Just this build. Change the project default in the dashboard's project settings, or with ${cmd("liftbay ci init --ios-engine " + iosEngine)}.`));
29269
29270
  }
29270
29271
  if (iosEngine === "xcode-cloud") {
29271
29272
  const xc = await unwrap(lb.GET("/v1/orgs/{org}/projects/{project}/xcode-cloud", { params: { path: path2 } }));
@@ -30108,16 +30109,17 @@ async function ciInit(app, config, opts) {
30108
30109
  let iosEngine = opts.iosEngine;
30109
30110
  if (iosEngine && iosEngine !== "github-actions" && iosEngine !== "xcode-cloud") fail("--ios-engine must be github-actions or xcode-cloud");
30110
30111
  if (platforms.includes("ios") && !iosEngine) {
30111
- iosEngine = config.build?.iosEngine ?? (opts.yes || !isInteractive() ? "github-actions" : cancelled(
30112
+ const current = (await unwrap(lb.GET("/v1/orgs/{org}/projects/{project}", { params: { path: { org: config.org, project: config.project } } }))).iosEngine;
30113
+ iosEngine = opts.yes || !isInteractive() ? current ?? "github-actions" : cancelled(
30112
30114
  await select({
30113
- message: "Where should iOS builds run?",
30115
+ message: "Where should iOS store builds run? (you can pick for each build too)",
30114
30116
  options: [
30115
30117
  { value: "github-actions", label: "GitHub Actions", hint: "macOS runners on your GitHub minutes; ready now" },
30116
30118
  { value: "xcode-cloud", label: "Xcode Cloud", hint: "store builds, 25 free hours a month with the Apple Developer Program; one-time setup after iOS signing" }
30117
30119
  ],
30118
- initialValue: "github-actions"
30120
+ initialValue: current ?? "github-actions"
30119
30121
  })
30120
- ));
30122
+ );
30121
30123
  }
30122
30124
  if (platforms.includes("ios") && !app.bundleId) log.warn(`No iOS bundle identifier found. Set ${import_picocolors13.default.cyan("expo.ios.bundleIdentifier")} in app.json before the first iOS build.`);
30123
30125
  if (platforms.includes("android") && !app.androidPackage) log.warn(`No Android package found. Set ${import_picocolors13.default.cyan("expo.android.package")} in app.json before the first Android build.`);
@@ -30155,12 +30157,13 @@ async function ciInit(app, config, opts) {
30155
30157
  log.info(import_picocolors13.default.dim(`Variables kept on expo.dev (EAS environment variables) aren't in eas.json: ${import_picocolors13.default.cyan("npx eas env:pull --environment production")}, then ${import_picocolors13.default.cyan(cmd("liftbay env import .env.local --environment production"))}.`));
30156
30158
  }
30157
30159
  const profiles = Object.fromEntries(Object.entries(base).map(([name, prof]) => [name, { ...prof, platforms }]));
30158
- const next = { ...config, build: { profiles, triggers: config.build?.triggers ?? [], ...iosEngine ? { iosEngine } : {} } };
30160
+ if (iosEngine) await unwrap(lb.PATCH("/v1/orgs/{org}/projects/{project}", { params: { path: path2 }, body: { iosEngine } }));
30161
+ const next = { ...config, build: { profiles, triggers: config.build?.triggers ?? [] } };
30159
30162
  writeConfig(next);
30160
30163
  note(
30161
30164
  Object.entries(profiles).map(([name, prof]) => `${import_picocolors13.default.bold(name.padEnd(12))} env ${prof.environment.padEnd(12)} ${prof.distribution === "store" ? "store" : "internal"} \xB7 ${prof.platforms.join(", ")}`).join("\n") + (iosEngine ? `
30162
30165
 
30163
- iOS builds run on ${iosEngine === "xcode-cloud" ? "Xcode Cloud" : "GitHub Actions"}` : ""),
30166
+ iOS store builds run on ${iosEngine === "xcode-cloud" ? "Xcode Cloud" : "GitHub Actions"} (project setting)` : ""),
30164
30167
  "Build profiles"
30165
30168
  );
30166
30169
  if (iosEngine === "xcode-cloud") {
@@ -30635,7 +30638,7 @@ async function channels() {
30635
30638
  }
30636
30639
 
30637
30640
  // src/index.ts
30638
- var program2 = new Command("liftbay").description("Build, ship and update React Native apps").version("0.5.0").option("--json", "print the result as JSON on stdout (progress goes to stderr; never prompts). Also LIFTBAY_JSON=1").hook("preAction", () => {
30641
+ var program2 = new Command("liftbay").description("Build, ship and update React Native apps").version("0.5.1").option("--json", "print the result as JSON on stdout (progress goes to stderr; never prompts). Also LIFTBAY_JSON=1").hook("preAction", () => {
30639
30642
  if (program2.opts().json || process.env.LIFTBAY_JSON === "1") enableJson();
30640
30643
  });
30641
30644
  var wrap = (fn) => async (...args) => {
@@ -30645,14 +30648,14 @@ var wrap = (fn) => async (...args) => {
30645
30648
  reportError(e);
30646
30649
  }
30647
30650
  };
30648
- var setupOptions = (cmd2) => cmd2.option("--org <slug>", "organization").option("--project <slug>", "project slug (created if it doesn't exist)").option("--platforms <list>", "ios, android or all").option("--runtime-policy <policy>", "appVersion or fingerprint").option("--ios-engine <engine>", "where iOS builds run: github-actions or xcode-cloud").option("--no-eas", "don't use eas.json's build profiles and env, even if there is one").option("-y, --yes", "accept defaults, no prompts").option("--api-url <url>", "API URL (for self-hosted or local development)").option("--dashboard-url <url>", "dashboard URL");
30651
+ var setupOptions = (cmd2) => cmd2.option("--org <slug>", "organization").option("--project <slug>", "project slug (created if it doesn't exist)").option("--platforms <list>", "ios, android or all").option("--runtime-policy <policy>", "appVersion or fingerprint").option("--ios-engine <engine>", "project setting: where iOS store builds run, github-actions or xcode-cloud").option("--no-eas", "don't use eas.json's build profiles and env, even if there is one").option("-y, --yes", "accept defaults, no prompts").option("--api-url <url>", "API URL (for self-hosted or local development)").option("--dashboard-url <url>", "dashboard URL");
30649
30652
  program2.command("login").description("Sign in through the browser").option("--api-url <url>", "API URL").option("--dashboard-url <url>", "dashboard URL").option("--no-open", "don't open the browser").option("--no-wait", "start the sign-in and exit; run `liftbay login` again after approving to finish (for agents)").action(wrap(login));
30650
30653
  program2.command("logout").description("Sign out and remove the saved token").action(wrap(logout));
30651
30654
  program2.command("whoami").description("Show the signed-in user and organizations").action(wrap(whoami));
30652
30655
  setupOptions(program2.command("init").description("Set up this app: link the project, builds, then OTA updates").option("--no-ota", "skip OTA updates")).action(wrap(initCommand));
30653
30656
  var ci = program2.command("ci").description("Builds");
30654
30657
  setupOptions(ci.command("init").description("Set up build profiles, environments and app identifiers")).action(wrap(ciInitCommand));
30655
- program2.command("build").description("Build on your GitHub Actions (Android on Linux, iOS on macOS) and follow the logs").option("--platform <platform>", "ios, android or all (asked in a terminal; otherwise the profile's platforms)").option("--profile <name>", "build profile from liftbay.json (asked in a terminal; otherwise production)").option("--ref <ref>", "branch, tag or commit to build (default: current branch)").option("-m, --message <text>", "build message").option("--simulator", "iOS: build for the simulator instead of a signed .ipa").option("--no-wait", "queue and exit without following the logs").option("--submit", "submit store builds when they succeed: TestFlight, or a Google Play track").option("--track <track>", "Play track for --submit: internal, alpha, beta or production").option("--engine <engine>", "where iOS builds run: github-actions or xcode-cloud (default: build.iosEngine in liftbay.json; asked in a terminal)").action(wrap(build));
30658
+ program2.command("build").description("Build on your GitHub Actions (Android on Linux, iOS on macOS) and follow the logs").option("--platform <platform>", "ios, android or all (asked in a terminal; otherwise the profile's platforms)").option("--profile <name>", "build profile from liftbay.json (asked in a terminal; otherwise production)").option("--ref <ref>", "branch, tag or commit to build (default: current branch)").option("-m, --message <text>", "build message").option("--simulator", "iOS: build for the simulator instead of a signed .ipa").option("--no-wait", "queue and exit without following the logs").option("--submit", "submit store builds when they succeed: TestFlight, or a Google Play track").option("--track <track>", "Play track for --submit: internal, alpha, beta or production").option("--engine <engine>", "where this iOS store build runs: github-actions or xcode-cloud (asked in a terminal; otherwise the project's setting)").action(wrap(build));
30656
30659
  var builds = program2.command("builds").description("Look at builds: list, status, logs, artifacts");
30657
30660
  builds.command("list").description("Recent builds, newest first").option("--platform <platform>", "ios or android").option("--status <list>", "comma-separated: queued, preparing, running, uploading, succeeded, failed, cancelled").option("--limit <n>", "how many", "20").action(wrap(buildsList));
30658
30661
  builds.command("view <number>").description("Status, phases and artifacts of one build").action(wrap(buildsView));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "liftbay",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Build, sign, submit and update React Native apps from your own CI.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -49,7 +49,7 @@
49
49
  "devDependencies": {
50
50
  "@clack/core": "1.5.1",
51
51
  "@clack/prompts": "^1.8.1",
52
- "@liftbay/sdk": "^0.1.1",
52
+ "@liftbay/sdk": "^0.1.2",
53
53
  "@types/node": "^26.6.4",
54
54
  "@types/qrcode": "^1.5.6",
55
55
  "@types/node-forge": "^1.3.14",
@@ -60,7 +60,7 @@ Useful flags:
60
60
 
61
61
  To set up one part on its own, use `liftbay ci init --yes --json` (builds) or `liftbay ota init --yes --json` (OTA).
62
62
 
63
- Pass `--ios-engine github-actions|xcode-cloud` for where iOS **store** builds run; it's saved as `build.iosEngine` in `liftbay.json`. Xcode Cloud uses the Apple team's free hours, and needs iOS signing and `liftbay xcode-cloud connect` first. Internal (ad hoc) and simulator builds always run on GitHub Actions.
63
+ `--ios-engine github-actions|xcode-cloud` sets a **project setting**: where iOS **store** builds run unless a build picks. Builds you start without `--engine`, and every build started by a git push, use it. It's also in the dashboard's project settings. Xcode Cloud uses the Apple team's free hours, and needs iOS signing and `liftbay xcode-cloud connect` first; until it's connected (or when it's out of hours), those builds fall back to GitHub Actions and say so in the log. Internal (ad hoc) and simulator builds always run on GitHub Actions.
64
64
 
65
65
  Then get GitHub ready. Builds start the workflow through the Liftbay GitHub App:
66
66
 
@@ -159,7 +159,7 @@ Statuses: `queued` → `preparing` → `running` → `uploading` → `succeeded`
159
159
  Other flags:
160
160
  - `--ref <branch|tag|sha>`: defaults to the current branch, which must be pushed.
161
161
  - `--simulator`: unsigned iOS simulator build; needs no Apple account.
162
- - `--engine github-actions|xcode-cloud`: overrides `build.iosEngine` for this build (Xcode Cloud: iOS store builds only)
162
+ - `--engine github-actions|xcode-cloud`: for this build only, instead of the project's setting (Xcode Cloud: iOS store builds only)
163
163
  - `-m "message"`
164
164
 
165
165
  **Xcode Cloud (optional):** `liftbay xcode-cloud connect --json`. Its error says which one-time step the user has to do in App Store Connect.