laneyard 0.3.0 → 0.4.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.
Files changed (46) hide show
  1. package/README.md +227 -20
  2. package/dist/src/cli/detect.js +12 -3
  3. package/dist/src/cli/prompt.js +28 -3
  4. package/dist/src/cli/secret-import.js +162 -0
  5. package/dist/src/cli/secret.js +162 -1
  6. package/dist/src/cli/setup.js +44 -7
  7. package/dist/src/cli/uninstall.js +390 -0
  8. package/dist/src/credentials/kinds.js +120 -0
  9. package/dist/src/db/credentials.js +100 -0
  10. package/dist/src/db/schema.sql +39 -0
  11. package/dist/src/db/secrets.js +53 -0
  12. package/dist/src/db/sessions.js +61 -0
  13. package/dist/src/git/workspace.js +32 -6
  14. package/dist/src/heuristics/android-root.js +49 -0
  15. package/dist/src/heuristics/android-signing.js +98 -0
  16. package/dist/src/heuristics/appfile.js +60 -0
  17. package/dist/src/heuristics/blocking-actions.js +2 -0
  18. package/dist/src/heuristics/env-example.js +36 -0
  19. package/dist/src/heuristics/platforms.js +69 -10
  20. package/dist/src/heuristics/readiness.js +554 -25
  21. package/dist/src/main.js +23 -2
  22. package/dist/src/runner/gradle-properties.js +187 -0
  23. package/dist/src/runner/materialise.js +92 -0
  24. package/dist/src/runner/orchestrate.js +91 -2
  25. package/dist/src/secrets/vault.js +137 -5
  26. package/dist/src/server/app.js +30 -3
  27. package/dist/src/server/auth.js +50 -10
  28. package/dist/src/server/permissions.js +2 -0
  29. package/dist/src/server/required-secrets.js +30 -0
  30. package/dist/src/server/routes/account.js +57 -0
  31. package/dist/src/server/routes/credentials.js +108 -0
  32. package/dist/src/server/routes/projects.js +60 -2
  33. package/dist/src/server/routes/readiness.js +162 -6
  34. package/dist/src/server/routes/secrets.js +101 -0
  35. package/dist/src/sidecar/bridge.js +21 -1
  36. package/dist/src/sidecar/fastlane-dir.js +23 -0
  37. package/dist/src/sidecar/lanes.js +6 -0
  38. package/dist/src/sidecar/uses.js +21 -5
  39. package/dist/web/assets/{Editor-DNFBA4gv.js → Editor-9nLYwtg7.js} +1 -1
  40. package/dist/web/assets/index-DsjxZtsO.css +1 -0
  41. package/dist/web/assets/index-pzPa9EZr.js +62 -0
  42. package/dist/web/index.html +2 -2
  43. package/package.json +1 -1
  44. package/ruby/introspect.rb +122 -9
  45. package/dist/web/assets/index-De6sxx6G.css +0 -1
  46. package/dist/web/assets/index-TWRQ1cJg.js +0 -62
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The variable names a `.env.example` advertises.
3
+ *
4
+ * A project that keeps its variables in `fastlane/.env` almost always commits a
5
+ * `.env.example` beside it — that is what the file is *for*: telling whoever
6
+ * clones the repository which variables they need. It is the one manifest of
7
+ * required variables that is both conventional and, unlike `.env` itself,
8
+ * actually present in the clone a build runs from.
9
+ *
10
+ * It catches what parsing the Fastfile cannot. `SENTRY_AUTH_TOKEN` is read by
11
+ * `sentry-cli`, not by any `ENV.fetch` in a lane, so no amount of reading the
12
+ * Fastfile finds it — and it sits in `.env.example`, named, all along.
13
+ *
14
+ * Only names are taken. The file is an example by definition, so its values are
15
+ * placeholders; reading them would be reading fiction, and a checklist that
16
+ * compared them to anything would be worse than one that did not look.
17
+ */
18
+ export function parseEnvExample(content) {
19
+ const names = [];
20
+ for (const raw of content.split("\n")) {
21
+ const line = raw.trim();
22
+ if (line === "" || line.startsWith("#"))
23
+ continue;
24
+ // `export FOO=bar` is legal in these files and means the same thing.
25
+ const assignment = line.replace(/^export\s+/, "");
26
+ const eq = assignment.indexOf("=");
27
+ if (eq <= 0)
28
+ continue;
29
+ const name = assignment.slice(0, eq).trim();
30
+ // Shell-ish variable names only: anything else is a line this has
31
+ // misunderstood, and inventing a requirement is worse than missing one.
32
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
33
+ names.push(name);
34
+ }
35
+ return [...new Set(names)];
36
+ }
@@ -1,17 +1,76 @@
1
+ import { join } from "node:path";
1
2
  /**
2
- * Which platforms a project builds for.
3
+ * Where to look for the markers, given where the Fastfile turned out to be.
3
4
  *
4
- * Named knowledge of mobile toolchains that `.xcodeproj` means Xcode, that
5
- * `build.gradle` means Gradle — hence its place in this module, and the
6
- * boundary that comes with it: nothing here refuses anything. It answers a
7
- * question; `setup` writes the answer down and the checklist reads it.
5
+ * Two places, and the order does not matter because the answer is a union.
8
6
  *
9
- * It lives here rather than in `cli/detect.ts` because two callers need the
10
- * same answer. Setup proposes a configuration from it, and the checklist
11
- * decides which sections apply from it. Two copies of this reasoning would be
12
- * free to disagree about the same repository, and the checklist would be the
13
- * one that looked wrong.
7
+ * The repository root is the obvious one, and used to be the only one. It is
8
+ * wrong on its own: the markers sit *beside* an app's fastlane folder, not
9
+ * beside the repository root `ios/Runner.xcodeproj` and `fastlane/` are
10
+ * siblings, and both move together when the app is one directory of a
11
+ * monorepo. A repository holding `app/fastlane/Fastfile` and
12
+ * `app/ios/Runner.xcodeproj` reported "no Xcode project and no Gradle build",
13
+ * because that is three levels down and the table reaches two.
14
+ *
15
+ * The app's own directory is the second, and it is the one laneyard already
16
+ * knows: it asked where the Fastfile was during setup. Between them they cover
17
+ * the arrangements that actually occur —
18
+ *
19
+ * - `fastlane/` and `*.xcodeproj` both at the root: a plain native app;
20
+ * - `fastlane/`, `ios/`, `android/` at the root: React Native, Flutter;
21
+ * - `app/fastlane/`, `app/ios/`, `app/android/`: the same app inside a monorepo;
22
+ * - `ios/fastlane/`: a fastlane set up for one platform only, which then
23
+ * reports that one platform and not its sibling — right, since those lanes
24
+ * build one platform, and an irrelevant section is what teaches someone to
25
+ * ignore the screen.
26
+ *
27
+ * Keeping both roots rather than replacing one with the other is what makes
28
+ * this strictly an addition: nothing the old behaviour found is lost.
29
+ *
30
+ * What is deliberately *not* done is deepening the table to `*​/*​/*` or `**`.
31
+ * A third level would match `node_modules/some-package/ios/X.xcodeproj` and
32
+ * `app/ios/Pods/Pods.xcodeproj`, and report iOS for an Android-only project on
33
+ * the strength of a dependency's own Xcode project. `**` would do that and walk
34
+ * every build directory to do it. Two levels from a root that is actually the
35
+ * app is a better question than four levels from a root that is not.
36
+ */
37
+ export function appRootOf(fastlaneDir) {
38
+ if (!fastlaneDir)
39
+ return ".";
40
+ // Repository-relative and always forward-slashed, whatever the platform.
41
+ const parent = fastlaneDir.replace(/\/+$/, "").split("/").slice(0, -1).join("/");
42
+ return parent === "" ? "." : parent;
43
+ }
44
+ /**
45
+ * The one directory to list, given where the Fastfile turned out to be.
46
+ *
47
+ * Not the repository root, which is what it used to be and what made a
48
+ * repository holding `app/fastlane/Fastfile` and `app/ios/Runner.xcodeproj`
49
+ * report "no Xcode project and no Gradle build": that is three levels down and
50
+ * the table reaches two.
51
+ *
52
+ * Not both, either, though that was tempting — keeping the root as well would
53
+ * have made this purely additive. It also means a project configured with
54
+ * `ios/fastlane` is shown the Android section, on the strength of a sibling
55
+ * `android/` folder those lanes never touch. The fastlane directory is not a
56
+ * guess: setup asked for it and `laneyard.yml` records it, and it says which
57
+ * app this project *is*. Trusting it is the difference between a checklist
58
+ * about this project and a checklist about the repository it lives in.
59
+ *
60
+ * Anyone it gets wrong has the escape hatch the check itself names: `platforms`
61
+ * in `laneyard.yml` is read first and skips all of this.
62
+ *
63
+ * What is deliberately not done is deepening the table to `*​/*​/*` or `**`. A
64
+ * third level matches `node_modules/some-package/ios/X.xcodeproj` and
65
+ * `app/ios/Pods/Pods.xcodeproj`, and would report iOS for an Android-only
66
+ * project on the strength of a dependency. Two levels from a directory that is
67
+ * actually the app beats four from one that is not.
14
68
  */
69
+ export function searchDir(from, appRoot) {
70
+ if (!appRoot || appRoot === "." || appRoot.startsWith(".."))
71
+ return from;
72
+ return join(from, appRoot);
73
+ }
15
74
  /**
16
75
  * What a repository looks like from the outside, as a table.
17
76
  *