@smoothbricks/cli 0.11.16 → 0.11.18

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 (79) hide show
  1. package/README.md +65 -4
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +47 -0
  4. package/dist/github-ci/index.d.ts +1 -1
  5. package/dist/github-ci/index.d.ts.map +1 -1
  6. package/dist/github-ci/index.js +7 -10
  7. package/dist/lib/secret-names.d.ts +35 -0
  8. package/dist/lib/secret-names.d.ts.map +1 -0
  9. package/dist/lib/secret-names.js +61 -0
  10. package/dist/monorepo/ci-workflow.d.ts +56 -0
  11. package/dist/monorepo/ci-workflow.d.ts.map +1 -1
  12. package/dist/monorepo/ci-workflow.js +214 -8
  13. package/dist/monorepo/managed-files.d.ts +23 -0
  14. package/dist/monorepo/managed-files.d.ts.map +1 -1
  15. package/dist/monorepo/managed-files.js +39 -1
  16. package/dist/monorepo/publish-workflow.d.ts +10 -1
  17. package/dist/monorepo/publish-workflow.d.ts.map +1 -1
  18. package/dist/monorepo/publish-workflow.js +58 -20
  19. package/dist/release/github-release.d.ts +10 -0
  20. package/dist/release/github-release.d.ts.map +1 -1
  21. package/dist/release/github-release.js +11 -5
  22. package/dist/release/index.d.ts.map +1 -1
  23. package/dist/release/index.js +4 -5
  24. package/dist/secrets/commands.d.ts +84 -0
  25. package/dist/secrets/commands.d.ts.map +1 -0
  26. package/dist/secrets/commands.js +375 -0
  27. package/dist/secrets/index.d.ts +103 -0
  28. package/dist/secrets/index.d.ts.map +1 -0
  29. package/dist/secrets/index.js +255 -0
  30. package/dist/secrets/repository.d.ts +60 -0
  31. package/dist/secrets/repository.d.ts.map +1 -0
  32. package/dist/secrets/repository.js +145 -0
  33. package/dist/wrangler/cloudflare.d.ts +7 -0
  34. package/dist/wrangler/cloudflare.d.ts.map +1 -1
  35. package/dist/wrangler/cloudflare.js +10 -0
  36. package/dist/wrangler/deploy-stage.d.ts +13 -2
  37. package/dist/wrangler/deploy-stage.d.ts.map +1 -1
  38. package/dist/wrangler/deploy-stage.js +89 -78
  39. package/dist/wrangler/deployed-version.d.ts +44 -0
  40. package/dist/wrangler/deployed-version.d.ts.map +1 -0
  41. package/dist/wrangler/deployed-version.js +87 -0
  42. package/dist/wrangler/live-version.d.ts +146 -0
  43. package/dist/wrangler/live-version.d.ts.map +1 -0
  44. package/dist/wrangler/live-version.js +326 -0
  45. package/dist/wrangler/stage-secrets.d.ts +57 -0
  46. package/dist/wrangler/stage-secrets.d.ts.map +1 -0
  47. package/dist/wrangler/stage-secrets.js +178 -0
  48. package/managed/raw/tooling/direnv/devenv.smoo.nix +9 -1
  49. package/managed/raw/tooling/git-hooks/pre-push.sh +30 -29
  50. package/package.json +2 -2
  51. package/src/cli.ts +69 -1
  52. package/src/github-ci/index.test.ts +92 -8
  53. package/src/github-ci/index.ts +7 -10
  54. package/src/lib/secret-names.ts +70 -0
  55. package/src/monorepo/__tests__/ci-workflow.test.ts +188 -2
  56. package/src/monorepo/__tests__/publish-workflow.test.ts +33 -15
  57. package/src/monorepo/ci-workflow.ts +294 -8
  58. package/src/monorepo/managed-files.test.ts +28 -1
  59. package/src/monorepo/managed-files.ts +56 -2
  60. package/src/monorepo/package-policy.test.ts +1 -1
  61. package/src/monorepo/publish-workflow.ts +65 -19
  62. package/src/monorepo/secret-references.test.ts +1 -1
  63. package/src/release/__tests__/github-release.test.ts +8 -4
  64. package/src/release/__tests__/private-npm-status.test.ts +2 -2
  65. package/src/release/github-release.ts +13 -5
  66. package/src/release/index.ts +4 -4
  67. package/src/secrets/commands.test.ts +28 -0
  68. package/src/secrets/commands.ts +412 -0
  69. package/src/secrets/index.test.ts +209 -0
  70. package/src/secrets/index.ts +287 -0
  71. package/src/secrets/repository.test.ts +98 -0
  72. package/src/secrets/repository.ts +164 -0
  73. package/src/wrangler/cloudflare.ts +18 -0
  74. package/src/wrangler/deploy-stage.test.ts +448 -23
  75. package/src/wrangler/deploy-stage.ts +142 -83
  76. package/src/wrangler/deployed-version.test.ts +150 -0
  77. package/src/wrangler/deployed-version.ts +130 -0
  78. package/src/wrangler/live-version.ts +363 -0
  79. package/src/wrangler/stage-secrets.ts +146 -0
package/README.md CHANGED
@@ -351,10 +351,18 @@ wraps prose body paragraphs through `fmt -w 72` while preserving fenced code blo
351
351
  bullets, trailers, URLs, and comment lines.
352
352
 
353
353
  The generated pre-push hook runs only on macOS. Linux `nx lint` already compiles the Linux `cfg(target_os)` arm; Darwin
354
- does not. The hook runs `nx run-many -t cargo-lint-cross`. Nx caches that target on the Cargo inputs, so a hit is a
355
- prior real Linux clippy and never enters linux-cross. A miss falls through to `bun run check:linux`, which is
356
- `tooling/devenv --quiet -P linux-cross shell --` around that same Nx target and writes the cache. `git push --no-verify`
357
- skips the hook.
354
+ does not. The hook is a probe: it runs `env -u CC_x86_64_unknown_linux_gnu nx run-many -t cargo-lint-cross` and nothing
355
+ else. Nx caches that target on the Cargo inputs, so a hit is a prior real Linux clippy and the push proceeds. A miss
356
+ refuses the push and names `bun run check:linux` the hook never enters linux-cross and never starts a compile, so what
357
+ it costs is one Nx graph construction rather than an unbounded clippy. `bun run check:linux` is
358
+ `tooling/devenv -P linux-cross shell --` around that same Nx target; it is the only place the gate actually runs, so it
359
+ is deliberately not quiet. `git push --no-verify` skips the hook.
360
+
361
+ The toolchain variable is unset for the probe on purpose. The target's own command reads it to decide whether the cross
362
+ toolchain is present, so a push made from inside an already-entered linux-cross shell would otherwise fall through into
363
+ a real multi-minute compile — the thing the probe exists to avoid. It is not a declared input of the target, so
364
+ unsetting it cannot change the task hash: a warm entry still hits. Measured both ways, including with the variable set
365
+ to a nonexistent compiler.
358
366
 
359
367
  Conventional commit scopes should use Nx project names. For packages in the same npm scope as the root package, smoo
360
368
  requires `package.json` `nx.name` to be the unscoped package name, such as `cli` for `@smoothbricks/cli`, so subjects
@@ -428,6 +436,49 @@ that runs after Validate and the e2e job succeed on a push to the staging push b
428
436
  stage-derived — carry `stage-deploy-target` or deploy through `smoo wrangler deploy-stage` — otherwise `--select-tag`
429
437
  finds nothing and the job logs `No run-many deploy projects; skipping production.`
430
438
 
439
+ #### Ordering one deploy after another
440
+
441
+ When a project's deploy calls into what another project deploys — a site that signs in to its stage's backend — say so
442
+ with an ordinary Nx edge on the deploying project:
443
+
444
+ ```json
445
+ { "nx": { "targets": { "deploy": { "dependsOn": ["...", "app-backend:deploy"] } } } }
446
+ ```
447
+
448
+ Nx then orders it, at any depth: `site:deploy` after `app-backend:deploy` after `db:deploy` all resolve inside the one
449
+ `nx run-many` that `smoo github-ci nx-deploy` already issues, and `nx deploy site --stage=…` run by hand gets the same
450
+ order. Keep the leading `"..."`: it expands the `deploy-build` edge the plugin infers (below), which a bare list would
451
+ drop.
452
+
453
+ What makes the edge safe is that a deploy is never cached and always cheap when there is nothing to do:
454
+
455
+ - `@smoothbricks/nx-plugin` gives every declared `deploy` target `cache: false`. An Nx cache hit on a deploy means "we
456
+ once uploaded this hash", which a rollback silently falsifies — the workspace is unchanged, so the hash is unchanged,
457
+ so a cached deploy would report success while the previous version keeps serving.
458
+ - `smoo wrangler deploy-stage` reads live state first. If the version tagged with this task's hash is already the one
459
+ serving 100% of traffic, it returns `remote-cache-hit` after two API calls: no upload, no migration, no traffic shift.
460
+ - The expensive, purely file-derived half belongs in a sibling `deploy-build` target (build the artifact, register it,
461
+ refresh what the build needs). The plugin gives that one `cache: true` and makes `deploy` depend on it, so a redundant
462
+ deploy costs two API calls rather than a rebuild.
463
+ - A deploy does not finish when Cloudflare accepts the traffic shift; it finishes when the new version is the one being
464
+ served. `deploy-stage` polls `wrangler deployments status` until the tag it activated is live, and fails with what it
465
+ expected and what it saw if that never happens. Pass `--version-endpoint <url>` to also require an endpoint served by
466
+ the worker — whose trimmed response body is the running version tag — to answer with it. Without that wait, an edge
467
+ onto a deploy orders nothing: the step returns while the edge still serves the old code.
468
+
469
+ **The policy caveat, plainly.** A cross-project edge is part of the graph, not of the selection: a run that selects only
470
+ the dependent project will still evaluate the dependency's `deploy`. When the dependency is already at that hash, that
471
+ evaluation is a no-op — two API calls. But it is not inert: if the dependency is intentionally behind (its production
472
+ deploy is being held back, say), a run that selects only the dependent project **will advance the dependency to the hash
473
+ the current workspace produces**. If you need a project to be deployable without touching what it depends on, do not add
474
+ the edge; sequence those two deploys as separate CI jobs instead.
475
+
476
+ `smoo wrangler deployed-version --stage <stage>` prints the tag serving all traffic for the project's worker on that
477
+ stage, so an operator can check the same fact the deploy checks. It caches its answer briefly under Nx's workspace data
478
+ directory; that cache is a convenience for repeated queries only. Nothing that decides whether to deploy reads it, and
479
+ it refuses — rather than answering `unknown` — without credentials, on an API error, or while traffic is split between
480
+ two versions.
481
+
431
482
  Pushes to the staging push branch queue behind a running workflow instead of canceling it, so a newer push never cancels
432
483
  a production deployment mid-flight. Pull requests and other branches keep canceling superseded runs. The e2e and
433
484
  production jobs repeat the Cargo credential and sibling-source preflight before SetupDevenv, so their `--step` anchors
@@ -675,6 +726,16 @@ resource carrying the `prN` segment, D1 included.
675
726
  fall back to that variable and rename the worker after it.
676
727
  - The secrets manifest (`.dev.vars.example`) and the temporary secrets file come from the working directory, not from
677
728
  beside the `--config` file.
729
+ - Secrets are gated per stage. `smoo.wrangler.secretStages` in the project's `package.json` maps a declared secret name
730
+ to the stages that require it, and the mapping cuts both ways: a listed stage REFUSES to deploy when that secret has
731
+ no value in the environment and none on the Worker, and an unlisted stage never RECEIVES it even when the deploying
732
+ shell exports one. `preview` matches any `prN`. A name absent from the map is required by every stage.
733
+ - The refusal happens before any Cloudflare mutation and names every missing secret at once, so a first deploy reports
734
+ the whole list instead of one name per attempt. Values never appear in a message or in argv.
735
+ - Both directions are load-bearing, and neither is a lint. `--secrets-file` applies additively — wrangler deletes
736
+ nothing it is not told about — so a secret introduced after a stage's first deploy would otherwise never arrive and
737
+ the Worker would keep serving without it, silently. And a token scoped to preview stages, exported by a shell that
738
+ also deploys production, would otherwise install a test-only capability into production.
678
739
  - Migrations run only for the D1 bindings that declare a `migrations_dir`.
679
740
  - For a `prN` stage, an R2 bucket or D1 database whose name has no exact `staging` segment is refused, before any
680
741
  Cloudflare resource is created: reusing the name verbatim would share staging's data with the pull request.
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAWA,wBAAsB,MAAM,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAcxE;AAQD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAiBhD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAaA,wBAAsB,MAAM,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAcxE;AAQD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAiBhD"}
package/dist/cli.js CHANGED
@@ -6,7 +6,9 @@ import { cliPackageVersion } from './lib/cli-package.js';
6
6
  import { decode, findRepoRoot, printCommandOutput } from './lib/run.js';
7
7
  import { ensureChromium } from './playwright/index.js';
8
8
  import { resolvePrConflicts } from './pr/index.js';
9
+ import { secretsSet, secretsStatus, secretsSync } from './secrets/commands.js';
9
10
  import { cleanupPullRequest, deployStage } from './wrangler/deploy-stage.js';
11
+ import { deployedVersion } from './wrangler/deployed-version.js';
10
12
  import { scaffold } from './wrangler/scaffold.js';
11
13
  export async function runCli(argv = process.argv.slice(2)) {
12
14
  const program = buildProgram();
@@ -420,6 +422,33 @@ function buildProgram() {
420
422
  .action(async () => {
421
423
  await ensureChromium();
422
424
  });
425
+ const secrets = program
426
+ .command('secrets')
427
+ .description('Reconcile declared secrets: what Workers need, what workflows pass, what the repository holds');
428
+ secrets
429
+ .command('status')
430
+ .description('Show every declared secret with the scopes holding it, and refuse when a workflow passes one none has')
431
+ .option('-R, --repo <owner/name|remote>', "repository or remote name; defaults to the current branch's upstream remote")
432
+ .option('--env <environment>', "also read this GitHub Environment; its value takes precedence over the repository's for a job bound to it")
433
+ .action(async (options) => {
434
+ process.exitCode = secretsStatus(await findRepoRoot(), options);
435
+ });
436
+ secrets
437
+ .command('set [name]')
438
+ .description('Set secrets from pasted values; with no name, prompts for every secret the target scope still lacks')
439
+ .option('-R, --repo <owner/name|remote>', "repository or remote name; defaults to the current branch's upstream remote")
440
+ .option('--env <environment>', "write into this GitHub Environment; its value takes precedence over the repository's for a job bound to it")
441
+ .action(async (name, options) => {
442
+ process.exitCode = await secretsSet(await findRepoRoot(), name, options);
443
+ });
444
+ secrets
445
+ .command('sync')
446
+ .description('Push every secret smoo.secrets can fetch locally to the repository')
447
+ .option('-R, --repo <owner/name|remote>', "repository or remote name; defaults to the current branch's upstream remote")
448
+ .option('--env <environment>', "write into this GitHub Environment; its value takes precedence over the repository's for a job bound to it")
449
+ .action(async (options) => {
450
+ process.exitCode = await secretsSync(await findRepoRoot(), options);
451
+ });
423
452
  const wrangler = program.command('wrangler').description('Cloudflare wrangler project helpers');
424
453
  wrangler
425
454
  .command('scaffold <project>')
@@ -432,11 +461,29 @@ function buildProgram() {
432
461
  .command('deploy-stage')
433
462
  .requiredOption('--stage <stage>', 'staging, production, or prN')
434
463
  .option('--config <path>', 'deploy a build-generated flat wrangler.json instead of ./wrangler.toml')
464
+ .option('--version-endpoint <url>', 'URL served by this worker whose trimmed body is the running version tag')
435
465
  .action(async (options) => {
436
466
  await deployStage(process.cwd(), {
437
467
  stage: options.stage,
438
468
  ...(options.config ? { config: resolve(options.config) } : {}),
469
+ ...(options.versionEndpoint ? { versionEndpoint: options.versionEndpoint } : {}),
470
+ });
471
+ });
472
+ wrangler
473
+ .command('deployed-version')
474
+ .description('Print the version tag serving all traffic for this project\u2019s worker on a stage')
475
+ .requiredOption('--stage <stage>', 'staging, production, or prN')
476
+ .option('--config <path>', 'resolve the worker name from a build-generated flat wrangler.json')
477
+ .option('--refresh', 'ask Cloudflare even when a fresh cached answer exists')
478
+ .action(async (options) => {
479
+ const report = await deployedVersion(process.cwd(), {
480
+ stage: options.stage,
481
+ ...(options.config ? { config: resolve(options.config) } : {}),
482
+ ...(options.refresh ? { refresh: true } : {}),
439
483
  });
484
+ // The tag alone on stdout: this is read by humans and by `$(...)`, and a version deployed
485
+ // outside Nx genuinely has no tag, which `untagged` says without pretending to be one.
486
+ console.log(report.versionTag ?? 'untagged');
440
487
  });
441
488
  wrangler
442
489
  .command('cleanup-pr')
@@ -68,7 +68,7 @@ export interface GithubCiNxDeployOptions {
68
68
  selectTag?: string;
69
69
  }
70
70
  export interface GithubCiNxDeployDependencies {
71
- listProjects?: (root: string, target: string, mode: 'affected' | 'run-many', stage: DeploymentStage, selectTag?: string) => Promise<string[]>;
71
+ listProjects?: (root: string, mode: 'affected' | 'run-many', stage: DeploymentStage, selectTag?: string) => Promise<string[]>;
72
72
  runNx?: (args: string[], root: string) => Promise<number>;
73
73
  appendSummary?: (summaryPath: string, content: string) => Promise<void>;
74
74
  appendOutput?: (outputPath: string, content: string) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github-ci/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github-ci/index.ts"],"names":[],"mappings":"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"}
@@ -260,9 +260,9 @@ export async function githubCiNxDeploy(root, options, dependencies = {}) {
260
260
  const setStatus = dependencies.setStatus ??
261
261
  ((state) => state === 'pending' ? createGithubStatus(name, step) : updateGithubStatus(name, state, step));
262
262
  const mode = resolveNxSmartMode(options.mode ?? 'run-many');
263
- const listProjects = dependencies.listProjects ?? listNxProjectsWithTarget;
263
+ const listProjects = dependencies.listProjects ?? listNxDeployProjects;
264
264
  const runNx = dependencies.runNx ?? ((args, commandRoot) => runStatus('nx', args, commandRoot));
265
- const projects = await listProjects(root, 'deploy', mode, stage, options.selectTag);
265
+ const projects = await listProjects(root, mode, stage, options.selectTag);
266
266
  if (projects.length === 0) {
267
267
  console.log(`No ${mode} deploy projects; skipping ${stage}.`);
268
268
  await setStatus('pending');
@@ -275,8 +275,8 @@ export async function githubCiNxDeploy(root, options, dependencies = {}) {
275
275
  ? { stage, urls: previewUrlsForStage(github?.previewUrls, stage) }
276
276
  : undefined;
277
277
  await setStatus('pending');
278
- const projectList = projects.join(',');
279
278
  const targets = options.verify === true ? ['build', 'lint', 'test', 'deploy'] : ['deploy'];
279
+ const projectList = projects.join(',');
280
280
  for (const target of targets) {
281
281
  const nxArgs = [
282
282
  'run-many',
@@ -286,6 +286,8 @@ export async function githubCiNxDeploy(root, options, dependencies = {}) {
286
286
  `--exclude=${deployExclusions(stage)}`,
287
287
  `--parallel=${NX_PARALLEL}`,
288
288
  ];
289
+ // Deploy ordering is a `dependsOn` edge in the project graph, not a second round here: one run-many
290
+ // already sequences any depth of `a:deploy -> b:deploy -> c:deploy`.
289
291
  if (target === 'deploy') {
290
292
  nxArgs.push(`--stage=${stage}`);
291
293
  }
@@ -413,17 +415,12 @@ function previewUrlFromTemplate(template, stage) {
413
415
  throw new Error(`preview URL template "${template}" must contain {stage}`);
414
416
  return template.replaceAll('{stage}', stage);
415
417
  }
416
- async function listNxProjectsWithTarget(root, target, mode, stage, selectTag) {
418
+ async function listNxDeployProjects(root, mode, stage, selectTag) {
417
419
  const listArgs = ['show', 'projects'];
418
420
  if (mode === 'affected')
419
421
  listArgs.push('--affected');
420
- listArgs.push('--withTarget', target);
421
- if (target === 'deploy')
422
- listArgs.push(`--exclude=${deployExclusions(stage)}`);
423
- listArgs.push('--json');
422
+ listArgs.push('--withTarget', 'deploy', `--exclude=${deployExclusions(stage)}`, '--json');
424
423
  const candidates = nxProjectList(await runText('nx', listArgs, root)).sort((left, right) => left.localeCompare(right));
425
- if (target !== 'deploy')
426
- return candidates;
427
424
  return selectStageDeployProjects(candidates, stage, selectTag, async (project) => {
428
425
  const parsed = parseNxProjectDeployTarget(await runText('nx', ['show', 'project', project, '--json'], root));
429
426
  if (!parsed)
@@ -0,0 +1,35 @@
1
+ /**
2
+ * One rule for naming the repository secret behind an environment variable, so
3
+ * the workflow renderer, the reconciler and an operator all derive the same
4
+ * name instead of maintaining a map.
5
+ *
6
+ * GitHub refuses to create a secret whose name starts with `GITHUB_` (hence
7
+ * `RepositorySecretName`'s pattern), which is why a Worker's
8
+ * `GITHUB_CLIENT_SECRET` cannot be stored under its own name. Prefixing with
9
+ * the repository owner is the workaround operators already reach for by hand
10
+ * (`ACME_GITHUB_CLIENT_SECRET` for `acme/app`); making it the convention means
11
+ * nothing has to declare it.
12
+ */
13
+ /** Names GitHub reserves: it rejects `gh secret set GITHUB_*` outright. */
14
+ export declare function isReservedRepositorySecretName(envName: string): boolean;
15
+ /**
16
+ * The repository secret an env name lives in. Identity for every name GitHub
17
+ * accepts; owner-prefixed for the reserved ones. `owner` comes from the
18
+ * repository URL, so a fork or a rename derives its own names rather than
19
+ * inheriting a hardcoded prefix.
20
+ */
21
+ export declare function conventionalRepositorySecretName(envName: string, owner: string): string;
22
+ /**
23
+ * Resolve the whole env -> secret mapping for a set of declared env names.
24
+ * Explicit entries win: an exception stays expressible, but a repository that
25
+ * follows the convention declares nothing.
26
+ */
27
+ export declare function repositorySecretMapping(envNames: readonly string[], owner: string, declared?: Readonly<Record<string, string>>): Record<string, string>;
28
+ /**
29
+ * Repository owner from a repository URL — `acme` from
30
+ * `https://github.com/acme/app.git`, and the same for an ssh or forge
31
+ * URL. The owner is derived rather than configured so a fork or a rename
32
+ * carries its own prefix instead of inheriting one.
33
+ */
34
+ export declare function repositoryOwnerFromUrl(url: string): string | null;
35
+ //# sourceMappingURL=secret-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-names.d.ts","sourceRoot":"","sources":["../../src/lib/secret-names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,2EAA2E;AAC3E,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAYvF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAC9C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKjE"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * One rule for naming the repository secret behind an environment variable, so
3
+ * the workflow renderer, the reconciler and an operator all derive the same
4
+ * name instead of maintaining a map.
5
+ *
6
+ * GitHub refuses to create a secret whose name starts with `GITHUB_` (hence
7
+ * `RepositorySecretName`'s pattern), which is why a Worker's
8
+ * `GITHUB_CLIENT_SECRET` cannot be stored under its own name. Prefixing with
9
+ * the repository owner is the workaround operators already reach for by hand
10
+ * (`ACME_GITHUB_CLIENT_SECRET` for `acme/app`); making it the convention means
11
+ * nothing has to declare it.
12
+ */
13
+ /** Names GitHub reserves: it rejects `gh secret set GITHUB_*` outright. */
14
+ export function isReservedRepositorySecretName(envName) {
15
+ return /^GITHUB_/i.test(envName);
16
+ }
17
+ /**
18
+ * The repository secret an env name lives in. Identity for every name GitHub
19
+ * accepts; owner-prefixed for the reserved ones. `owner` comes from the
20
+ * repository URL, so a fork or a rename derives its own names rather than
21
+ * inheriting a hardcoded prefix.
22
+ */
23
+ export function conventionalRepositorySecretName(envName, owner) {
24
+ if (!isReservedRepositorySecretName(envName))
25
+ return envName;
26
+ const prefix = owner
27
+ .replace(/[^A-Za-z0-9]+/g, '_')
28
+ .replace(/^_+|_+$/g, '')
29
+ .toUpperCase();
30
+ if (prefix.length === 0) {
31
+ throw new Error(`Cannot derive a repository secret name for ${envName}: GitHub reserves the GITHUB_ prefix and the repository owner is empty.`);
32
+ }
33
+ return `${prefix}_${envName}`;
34
+ }
35
+ /**
36
+ * Resolve the whole env -> secret mapping for a set of declared env names.
37
+ * Explicit entries win: an exception stays expressible, but a repository that
38
+ * follows the convention declares nothing.
39
+ */
40
+ export function repositorySecretMapping(envNames, owner, declared = {}) {
41
+ const mapping = {};
42
+ for (const envName of [...envNames].sort((left, right) => left.localeCompare(right))) {
43
+ mapping[envName] = declared[envName] ?? conventionalRepositorySecretName(envName, owner);
44
+ }
45
+ for (const [envName, secretName] of Object.entries(declared)) {
46
+ mapping[envName] = secretName;
47
+ }
48
+ return mapping;
49
+ }
50
+ /**
51
+ * Repository owner from a repository URL — `acme` from
52
+ * `https://github.com/acme/app.git`, and the same for an ssh or forge
53
+ * URL. The owner is derived rather than configured so a fork or a rename
54
+ * carries its own prefix instead of inheriting one.
55
+ */
56
+ export function repositoryOwnerFromUrl(url) {
57
+ const withoutProtocol = url.replace(/^[a-z+]+:\/\//i, '').replace(/^git@/i, '');
58
+ const path = withoutProtocol.replace(/^[^/:]+[/:]/, '');
59
+ const owner = path.split('/')[0];
60
+ return owner && owner.length > 0 ? owner.replace(/\.git$/i, '') : null;
61
+ }
@@ -10,6 +10,11 @@ export declare enum CiWorkflowStepKind {
10
10
  BrowserTests = "browser-tests",
11
11
  Lint = "lint",
12
12
  UnitTests = "unit-tests",
13
+ CrossToolchainPreflight = "cross-toolchain-preflight",
14
+ CrossTestArchives = "cross-test-archives",
15
+ UploadCrossTestArchives = "upload-cross-test-archives",
16
+ DownloadCrossTestArchives = "download-cross-test-archives",
17
+ CrossTests = "cross-tests",
13
18
  ManagedFilesCheck = "managed-files-check",
14
19
  ManagedFilesDispatch = "managed-files-dispatch",
15
20
  Deploy = "deploy",
@@ -34,6 +39,22 @@ export interface DeployStepSecretConfig {
34
39
  /** Extra deploy-step secrets, env var name → repository secret name. */
35
40
  deploySecrets?: Record<string, string>;
36
41
  }
42
+ /**
43
+ * One foreign target triple's test archive: what the Linux job cross-builds and
44
+ * a native runner executes.
45
+ *
46
+ * Both fields are DERIVED, never hand-written: the triple comes from the cargo
47
+ * workspace's `[workspace.metadata.smoothbricks.test] cross-targets`, and the
48
+ * path is where the inferred `cargo-cross-test-archive-<triple>` target
49
+ * declares its output. That is why this is not a `smoo.github` key — a triple
50
+ * repeated in CI config could name an archive the graph cannot build, and the
51
+ * workflow would only find out on the runner.
52
+ */
53
+ export interface CiCrossTestArchive {
54
+ triple: string;
55
+ /** Repository-relative path of the archive file, from the target's output. */
56
+ path: string;
57
+ }
37
58
  export interface CiWorkflowDefinitionOptions extends DeployStepSecretConfig {
38
59
  actionsProvider?: PackageSmooGithub['actionsProvider'];
39
60
  deploy: boolean;
@@ -75,6 +96,41 @@ export interface CiWorkflowDefinitionOptions extends DeployStepSecretConfig {
75
96
  e2eSecrets?: Record<string, string>;
76
97
  /** Emit the production-on-push job (some project carries PRODUCTION_PUSH_DEPLOY_TAG). */
77
98
  productionOnPush?: boolean;
99
+ /**
100
+ * Cross-built test archives, one per foreign target triple the cargo
101
+ * workspace declares. The Linux job builds and uploads each one; a second job
102
+ * downloads the `*-apple-darwin` ones and EXECUTES them on `macosRunsOn`,
103
+ * which is how a cross compile gets proved by running rather than by linking.
104
+ *
105
+ * Empty or absent renders exactly what a repository without cross archives
106
+ * renders — no step, no job, no numbering shift.
107
+ */
108
+ crossTestArchives?: readonly CiCrossTestArchive[];
109
+ /**
110
+ * macOS runner labels for the darwin execution job
111
+ * (`smoo.github.macosRunsOn`, the same labels the publish workflow's macOS
112
+ * legs use). Default macos-latest.
113
+ *
114
+ * A self-hosted label here is one specific machine. That machine being asleep
115
+ * does not skip the job: it queues, and the run FAILS on the job's
116
+ * `timeout-minutes`. That is the trade this opt-in buys — a red run when the
117
+ * Mac is unreachable, in exchange for the darwin binaries being tested by
118
+ * execution at all. `continue-on-error` would buy the green back by making
119
+ * the job unable to report anything, which is worse than not having it.
120
+ */
121
+ macosRunsOn?: string | string[];
122
+ /**
123
+ * Declared Linux cross-platform producer (`smoo.github.platformProducer`):
124
+ * the toolchain preflight and the environment a foreign-target build needs on
125
+ * a Linux runner. The publish workflow already renders this declaration for
126
+ * its cross artifact job, so the cross test archive reuses it rather than
127
+ * carrying a second copy of one repository's SDK and linker setup.
128
+ *
129
+ * Rendered STEP-scoped here, never as job env: this environment turns the
130
+ * repository's native producers into cross producers, and Validate's other
131
+ * steps are host builds that must stay host builds.
132
+ */
133
+ platformProducer?: PackageSmooGithub['platformProducer'];
78
134
  }
79
135
  export declare function defineCiWorkflow(options: CiWorkflowDefinitionOptions): CiWorkflowStep[];
80
136
  export declare function renderCiWorkflowYaml(options: CiWorkflowDefinitionOptions): string;
@@ -1 +1 @@
1
- {"version":3,"file":"ci-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/ci-workflow.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EACb,6BAA6B,EAE7B,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EACjB,6BAA6B,EAC7B,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AAGxB,oBAAY,kBAAkB;IAC5B,QAAQ,aAAa;IACrB,eAAe,qBAAqB;IACpC,WAAW,iBAAiB;IAC5B,gBAAgB,sBAAsB;IACtC,SAAS,gBAAgB;IACzB,cAAc,qBAAqB;IACnC,KAAK,UAAU;IACf,YAAY,kBAAkB;IAC9B,IAAI,SAAS;IACb,SAAS,eAAe;IACxB,iBAAiB,wBAAwB;IACzC,oBAAoB,2BAA2B;IAC/C,MAAM,WAAW;IACjB,WAAW,kBAAkB;IAC7B,cAAc,qBAAqB;IACnC,aAAa,oBAAoB;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,eAAe,CAAC,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACvD,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,2EAA2E;IAC3E,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC;;;;OAIG;IACH,eAAe,CAAC,EAAE,2BAA2B,EAAE,CAAC;IAChD;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,6BAA6B,CAAC;IACjD;;;;OAIG;IACH,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,yGAAyG;IACzG,YAAY,CAAC,EAAE,6BAA6B,CAAC;IAC7C,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,EAAE,CAgCvF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,MAAM,CAQjF;AAyDD,mFAAmF;AACnF,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,IAAI,CAAC,2BAA2B,EAAE,YAAY,CAAC,GAAG,MAAM,CAM1G;AA0LD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,SAAS,2BAA2B,EAAE,GAChD,MAAM,EAAE,CA+BV;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,2BAA2B,GAAG,2BAA2B,CA8BxG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,wBAAwB,GAAG,SAAS,GAAG,MAAM,CAS3F;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,wBAAwB,GAAG,wBAAwB,CAgB/F;AA+BD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,6BAA6B,GAAG,SAAS,GAAG,MAAM,CASpG;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,6BAA6B,GAAG,MAAM,EAAE,CAyG9G;AAqCD,6EAA6E;AAC7E,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,6BAA6B,GAAG,6BAA6B,CAkC9G;AAqGD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,UAIjC,CAAC;AAiCF;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,EAAE,CAMjF;AA8HD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,EAC9C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,GAAG,UAAU,EAC3B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,SAAS,SAAc,GACtB,MAAM,EAAE,CAmBV"}
1
+ {"version":3,"file":"ci-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/ci-workflow.ts"],"names":[],"mappings":"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"}