@smoothbricks/cli 0.11.17 → 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.
- package/README.md +22 -4
- package/dist/cli.js +10 -7
- package/dist/monorepo/ci-workflow.d.ts +56 -0
- package/dist/monorepo/ci-workflow.d.ts.map +1 -1
- package/dist/monorepo/ci-workflow.js +199 -2
- package/dist/monorepo/managed-files.d.ts +23 -0
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +39 -1
- package/dist/release/github-release.d.ts +10 -0
- package/dist/release/github-release.d.ts.map +1 -1
- package/dist/release/github-release.js +11 -5
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +4 -5
- package/dist/secrets/commands.d.ts +52 -13
- package/dist/secrets/commands.d.ts.map +1 -1
- package/dist/secrets/commands.js +220 -34
- package/dist/secrets/index.d.ts +21 -1
- package/dist/secrets/index.d.ts.map +1 -1
- package/dist/secrets/index.js +110 -4
- package/dist/secrets/repository.d.ts +60 -0
- package/dist/secrets/repository.d.ts.map +1 -0
- package/dist/secrets/repository.js +145 -0
- package/dist/wrangler/cloudflare.d.ts +7 -0
- package/dist/wrangler/cloudflare.d.ts.map +1 -1
- package/dist/wrangler/cloudflare.js +10 -0
- package/dist/wrangler/deploy-stage.d.ts.map +1 -1
- package/dist/wrangler/deploy-stage.js +50 -24
- package/dist/wrangler/stage-secrets.d.ts +57 -0
- package/dist/wrangler/stage-secrets.d.ts.map +1 -0
- package/dist/wrangler/stage-secrets.js +178 -0
- package/managed/raw/tooling/direnv/devenv.smoo.nix +9 -1
- package/managed/raw/tooling/git-hooks/pre-push.sh +30 -29
- package/package.json +2 -2
- package/src/cli.ts +33 -10
- package/src/monorepo/__tests__/ci-workflow.test.ts +161 -0
- package/src/monorepo/ci-workflow.ts +277 -2
- package/src/monorepo/managed-files.test.ts +27 -0
- package/src/monorepo/managed-files.ts +56 -2
- package/src/monorepo/package-policy.test.ts +1 -1
- package/src/release/__tests__/github-release.test.ts +8 -4
- package/src/release/github-release.ts +13 -5
- package/src/release/index.ts +4 -4
- package/src/secrets/commands.test.ts +28 -0
- package/src/secrets/commands.ts +237 -35
- package/src/secrets/index.test.ts +118 -1
- package/src/secrets/index.ts +108 -4
- package/src/secrets/repository.test.ts +98 -0
- package/src/secrets/repository.ts +164 -0
- package/src/wrangler/cloudflare.ts +18 -0
- package/src/wrangler/deploy-stage.test.ts +258 -11
- package/src/wrangler/deploy-stage.ts +70 -38
- 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
|
|
355
|
-
prior real Linux clippy and
|
|
356
|
-
`
|
|
357
|
-
|
|
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
|
|
@@ -718,6 +726,16 @@ resource carrying the `prN` segment, D1 included.
|
|
|
718
726
|
fall back to that variable and rename the worker after it.
|
|
719
727
|
- The secrets manifest (`.dev.vars.example`) and the temporary secrets file come from the working directory, not from
|
|
720
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.
|
|
721
739
|
- Migrations run only for the D1 bindings that declare a `migrations_dir`.
|
|
722
740
|
- For a `prN` stage, an R2 bucket or D1 database whose name has no exact `staging` segment is refused, before any
|
|
723
741
|
Cloudflare resource is created: reusing the name verbatim would share staging's data with the pull request.
|
package/dist/cli.js
CHANGED
|
@@ -427,22 +427,25 @@ function buildProgram() {
|
|
|
427
427
|
.description('Reconcile declared secrets: what Workers need, what workflows pass, what the repository holds');
|
|
428
428
|
secrets
|
|
429
429
|
.command('status')
|
|
430
|
-
.description('Show every declared secret and refuse when a workflow passes one
|
|
431
|
-
.option('--repo <owner/name>',
|
|
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")
|
|
432
433
|
.action(async (options) => {
|
|
433
434
|
process.exitCode = secretsStatus(await findRepoRoot(), options);
|
|
434
435
|
});
|
|
435
436
|
secrets
|
|
436
|
-
.command('set
|
|
437
|
-
.description('Set
|
|
438
|
-
.option('--repo <owner/name>',
|
|
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")
|
|
439
441
|
.action(async (name, options) => {
|
|
440
|
-
process.exitCode = await secretsSet(name, options);
|
|
442
|
+
process.exitCode = await secretsSet(await findRepoRoot(), name, options);
|
|
441
443
|
});
|
|
442
444
|
secrets
|
|
443
445
|
.command('sync')
|
|
444
446
|
.description('Push every secret smoo.secrets can fetch locally to the repository')
|
|
445
|
-
.option('--repo <owner/name>',
|
|
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")
|
|
446
449
|
.action(async (options) => {
|
|
447
450
|
process.exitCode = await secretsSync(await findRepoRoot(), options);
|
|
448
451
|
});
|
|
@@ -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":"
|
|
1
|
+
{"version":3,"file":"ci-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/ci-workflow.ts"],"names":[],"mappings":"AAQA,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,uBAAuB,8BAA8B;IACrD,iBAAiB,wBAAwB;IACzC,uBAAuB,+BAA+B;IACtD,yBAAyB,iCAAiC;IAC1D,UAAU,gBAAgB;IAC1B,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;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;CACd;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;IAC3B;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAClD;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChC;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;CAC1D;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,EAAE,CA4CvF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,MAAM,CASjF;AAkED,mFAAmF;AACnF,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,IAAI,CAAC,2BAA2B,EAAE,YAAY,CAAC,GAAG,MAAM,CAM1G;AAiPD;;;;;;;;;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;AAiRD,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,4 +1,5 @@
|
|
|
1
1
|
/* biome-ignore-all lint/suspicious/noTemplateCurlyInString: GitHub Actions expressions are emitted literally. */
|
|
2
|
+
import { cargoCrossTestArchiveFile, cargoCrossTestArchiveTargetName, cargoCrossTestTargetName, } from '@smoothbricks/nx-plugin/cross-check-policy';
|
|
2
3
|
import { PRODUCTION_PUSH_DEPLOY_TAG } from '../lib/deploy-tags.js';
|
|
3
4
|
import { renderRunsOnLine } from './github-runs-on.js';
|
|
4
5
|
export var CiWorkflowStepKind;
|
|
@@ -13,6 +14,11 @@ export var CiWorkflowStepKind;
|
|
|
13
14
|
CiWorkflowStepKind["BrowserTests"] = "browser-tests";
|
|
14
15
|
CiWorkflowStepKind["Lint"] = "lint";
|
|
15
16
|
CiWorkflowStepKind["UnitTests"] = "unit-tests";
|
|
17
|
+
CiWorkflowStepKind["CrossToolchainPreflight"] = "cross-toolchain-preflight";
|
|
18
|
+
CiWorkflowStepKind["CrossTestArchives"] = "cross-test-archives";
|
|
19
|
+
CiWorkflowStepKind["UploadCrossTestArchives"] = "upload-cross-test-archives";
|
|
20
|
+
CiWorkflowStepKind["DownloadCrossTestArchives"] = "download-cross-test-archives";
|
|
21
|
+
CiWorkflowStepKind["CrossTests"] = "cross-tests";
|
|
16
22
|
CiWorkflowStepKind["ManagedFilesCheck"] = "managed-files-check";
|
|
17
23
|
CiWorkflowStepKind["ManagedFilesDispatch"] = "managed-files-dispatch";
|
|
18
24
|
CiWorkflowStepKind["Deploy"] = "deploy";
|
|
@@ -33,6 +39,15 @@ export function defineCiWorkflow(options) {
|
|
|
33
39
|
steps.push({ kind: CiWorkflowStepKind.Deploy, name: '🚀 Deploy Stage' });
|
|
34
40
|
}
|
|
35
41
|
steps.push({ kind: CiWorkflowStepKind.Lint, name: '🔍 Lint' }, { kind: CiWorkflowStepKind.UnitTests, name: '🧪 Unit Tests' });
|
|
42
|
+
if (options.crossTestArchives?.length) {
|
|
43
|
+
if (options.platformProducer !== undefined) {
|
|
44
|
+
steps.push({
|
|
45
|
+
kind: CiWorkflowStepKind.CrossToolchainPreflight,
|
|
46
|
+
name: 'Check cross-platform toolchain prerequisites',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
steps.push({ kind: CiWorkflowStepKind.CrossTestArchives, name: '🎯 Build cross-target test archives' }, { kind: CiWorkflowStepKind.UploadCrossTestArchives, name: '📤 Upload cross-target test archives' });
|
|
50
|
+
}
|
|
36
51
|
if (options.browserTests) {
|
|
37
52
|
steps.push({ kind: CiWorkflowStepKind.BrowserTests, name: '🌐 Browser Tests' });
|
|
38
53
|
}
|
|
@@ -44,6 +59,7 @@ export function renderCiWorkflowYaml(options) {
|
|
|
44
59
|
return [
|
|
45
60
|
renderCiWorkflowHeader(options),
|
|
46
61
|
renderCiWorkflowSteps(steps, options),
|
|
62
|
+
renderCrossTestExecutionJob(options),
|
|
47
63
|
renderE2eDeploymentJob(options),
|
|
48
64
|
renderProductionDeployJob(options),
|
|
49
65
|
].join('');
|
|
@@ -216,6 +232,61 @@ function yamlLinesForStep(step, options) {
|
|
|
216
232
|
return nxSmartStep(step, 'lint', 'Lint');
|
|
217
233
|
case CiWorkflowStepKind.UnitTests:
|
|
218
234
|
return nxSmartStep(step, 'test', 'Unit Tests');
|
|
235
|
+
case CiWorkflowStepKind.CrossToolchainPreflight:
|
|
236
|
+
// The repository's own preflight, the same one the publish workflow's
|
|
237
|
+
// cross artifact job runs — an SDK to provision, a linker to check.
|
|
238
|
+
// `working-directory: .` because this workflow's steps default to the
|
|
239
|
+
// direnv shell directory while a preflight is repository-relative.
|
|
240
|
+
return [
|
|
241
|
+
` - name: ${step.name}`,
|
|
242
|
+
' working-directory: .',
|
|
243
|
+
...platformProducerStepEnvLines(options),
|
|
244
|
+
' run: |',
|
|
245
|
+
' set -euo pipefail',
|
|
246
|
+
...crossToolchainPreflight(options).map((line) => ` ${line}`),
|
|
247
|
+
];
|
|
248
|
+
case CiWorkflowStepKind.CrossTestArchives:
|
|
249
|
+
// Cross-COMPILES the workspace's test binaries for each declared foreign
|
|
250
|
+
// triple and packs them; runs nothing. `nx-run-many` rather than
|
|
251
|
+
// `nx-smart`, because an affected-graph selection would skip the archive
|
|
252
|
+
// on a commit that changed nothing Rust — and the sibling job that
|
|
253
|
+
// executes it has no way to build one.
|
|
254
|
+
return [
|
|
255
|
+
` - name: ${step.name}`,
|
|
256
|
+
...platformProducerStepEnvLines(options),
|
|
257
|
+
` run: smoo github-ci nx-run-many --targets "${crossArchiveTargetNames(options).join(',')}"`,
|
|
258
|
+
];
|
|
259
|
+
case CiWorkflowStepKind.UploadCrossTestArchives:
|
|
260
|
+
// retention-days: 1 — the only consumer is the sibling job in this same
|
|
261
|
+
// run, and these archives are the whole workspace's test binaries.
|
|
262
|
+
return artifactStepLines(options.actionsProvider, step.name, 'upload', [
|
|
263
|
+
`name: ${CROSS_TEST_ARCHIVE_ARTIFACT}`,
|
|
264
|
+
'path: |',
|
|
265
|
+
...crossTestArchives(options).map((archive) => ` ${archive.path}`),
|
|
266
|
+
// error, not ignore: a missing archive means the cross build silently
|
|
267
|
+
// produced nothing, and the execute job would then have nothing to run
|
|
268
|
+
// and no reason to say so.
|
|
269
|
+
'if-no-files-found: error',
|
|
270
|
+
'retention-days: 1',
|
|
271
|
+
]);
|
|
272
|
+
case CiWorkflowStepKind.DownloadCrossTestArchives:
|
|
273
|
+
// Restores each archive at the path its own Nx target declares as output,
|
|
274
|
+
// which is where the runner target reads it from. upload-artifact roots
|
|
275
|
+
// the artifact at the least common ancestor of what it uploaded, so the
|
|
276
|
+
// download path is that shared directory.
|
|
277
|
+
return artifactStepLines(options.actionsProvider, step.name, 'download', [
|
|
278
|
+
`name: ${CROSS_TEST_ARCHIVE_ARTIFACT}`,
|
|
279
|
+
`path: ${crossTestArchiveDirectory(options)}`,
|
|
280
|
+
]);
|
|
281
|
+
case CiWorkflowStepKind.CrossTests:
|
|
282
|
+
// EXECUTES, and that is all it can do: every one of these targets is
|
|
283
|
+
// `nextest run --archive-file`, which extracts prebuilt binaries into its
|
|
284
|
+
// own temporary directory. nextest never invokes cargo on this path
|
|
285
|
+
// (measured), so nothing here can compile even if a toolchain is present.
|
|
286
|
+
return [
|
|
287
|
+
` - name: ${step.name}`,
|
|
288
|
+
` run: smoo github-ci nx-run-many --targets "${darwinCrossTestTargetNames(options).join(',')}"`,
|
|
289
|
+
];
|
|
219
290
|
case CiWorkflowStepKind.ManagedFilesCheck:
|
|
220
291
|
// The authoritative drift check is nearly free here (devenv is already
|
|
221
292
|
// up). --warn never fails the job and publishes the step output
|
|
@@ -765,12 +836,13 @@ function renderYamlList(values, spaces) {
|
|
|
765
836
|
const indent = ' '.repeat(spaces);
|
|
766
837
|
return values.map((value) => `${indent}- ${value}`).join('\n');
|
|
767
838
|
}
|
|
768
|
-
function followUpStepNumbers(options) {
|
|
839
|
+
function followUpStepNumbers(options, middleSteps = 1) {
|
|
769
840
|
let number = 3;
|
|
770
841
|
const cargo = options.cargoCredentials !== undefined ? number++ : undefined;
|
|
771
842
|
const sources = options.sourceCheckouts?.length ? number++ : undefined;
|
|
772
843
|
const setup = number++;
|
|
773
|
-
const middle = number
|
|
844
|
+
const middle = number;
|
|
845
|
+
number += middleSteps;
|
|
774
846
|
const cleanup = number++;
|
|
775
847
|
return { cargo, sources, setup, middle, cleanup };
|
|
776
848
|
}
|
|
@@ -794,6 +866,131 @@ function followUpSetupSteps(options, numbers) {
|
|
|
794
866
|
function followUpCleanupStep(numbers) {
|
|
795
867
|
return [{ kind: CiWorkflowStepKind.SaveNixDevenv, name: '🧹 Cleanup and cache Nix/devenv', number: numbers.cleanup }];
|
|
796
868
|
}
|
|
869
|
+
/**
|
|
870
|
+
* How long the darwin execution job may take, download included. Generous
|
|
871
|
+
* because the archive is the whole workspace's test binaries, and bounded
|
|
872
|
+
* because the runner behind `macosRunsOn` may be one person's laptop: an
|
|
873
|
+
* unreachable runner queues, and this number is when the run says so.
|
|
874
|
+
*/
|
|
875
|
+
const CROSS_TEST_JOB_TIMEOUT_MINUTES = 30;
|
|
876
|
+
/** Rust names every Apple-desktop triple this way; iOS and simulator do not. */
|
|
877
|
+
const DARWIN_TRIPLE_SUFFIX = '-apple-darwin';
|
|
878
|
+
/** One artifact carrying every triple's archive, scoped to the run that built it. */
|
|
879
|
+
const CROSS_TEST_ARCHIVE_ARTIFACT = `cross-test-archives-${githubExpression('github.run_id')}`;
|
|
880
|
+
/**
|
|
881
|
+
* Executes the cross-built test binaries on a machine where they are native.
|
|
882
|
+
*
|
|
883
|
+
* This job COMPILES NOTHING, and cannot: its only Rust input is the archive the
|
|
884
|
+
* Validate job uploaded, and `nextest run --archive-file` extracts prebuilt
|
|
885
|
+
* binaries rather than invoking cargo (measured: zero cargo invocations). It
|
|
886
|
+
* needs the checkout for the workspace `--workspace-remap .` points at and for
|
|
887
|
+
* Nx to resolve the target, and setup-devenv for `nx` and `cargo-nextest`
|
|
888
|
+
* themselves — the repository's ordinary shell, not a cross toolchain, no SDK,
|
|
889
|
+
* no `rustup target add`.
|
|
890
|
+
*
|
|
891
|
+
* `needs: main` and a success gate rather than `!cancelled()`: an archive that
|
|
892
|
+
* was never uploaded cannot be executed, and a job that starts anyway would
|
|
893
|
+
* fail on a missing artifact and report it as a test failure.
|
|
894
|
+
*
|
|
895
|
+
* Only `*-apple-darwin` archives run here, because macOS runner labels are the
|
|
896
|
+
* only native runner this declaration names. A repository declaring some other
|
|
897
|
+
* foreign triple still gets its archive BUILT — which proves that triple
|
|
898
|
+
* compiles — and no execution job, which is the honest rendering of having
|
|
899
|
+
* nowhere to run it.
|
|
900
|
+
*/
|
|
901
|
+
function renderCrossTestExecutionJob(options) {
|
|
902
|
+
const archives = darwinCrossTestArchives(options);
|
|
903
|
+
if (archives.length === 0)
|
|
904
|
+
return '';
|
|
905
|
+
const numbers = followUpStepNumbers(options, 2);
|
|
906
|
+
const middleSteps = [
|
|
907
|
+
{
|
|
908
|
+
kind: CiWorkflowStepKind.DownloadCrossTestArchives,
|
|
909
|
+
name: '📥 Download cross-target test archives',
|
|
910
|
+
number: numbers.middle,
|
|
911
|
+
},
|
|
912
|
+
{ kind: CiWorkflowStepKind.CrossTests, name: '🧪 Cross-Target Unit Tests', number: numbers.middle + 1 },
|
|
913
|
+
];
|
|
914
|
+
return `
|
|
915
|
+
macos-cross-tests:
|
|
916
|
+
name: Unit Tests (${archives.map((archive) => archive.triple).join(', ')})
|
|
917
|
+
needs: main
|
|
918
|
+
${options.macosRunsOn === undefined ? ' runs-on: macos-latest' : renderRunsOnLine(options.macosRunsOn)}
|
|
919
|
+
timeout-minutes: ${CROSS_TEST_JOB_TIMEOUT_MINUTES}
|
|
920
|
+
if: \${{ needs.main.result == 'success' }}
|
|
921
|
+
env:
|
|
922
|
+
GH_TOKEN: \${{ github.token }}
|
|
923
|
+
${remoteCacheJobEnvLines(options.remoteCache)}${cargoCredentialJobEnvLines(options.cargoCredentials)}${privateNpmReadTokenJobEnv(options)} steps:
|
|
924
|
+
${renderCiWorkflowSteps(followUpSetupSteps(options, numbers), options)}
|
|
925
|
+
${renderCiWorkflowSteps(middleSteps, options)}
|
|
926
|
+
${renderCiWorkflowSteps(followUpCleanupStep(numbers), options)}`;
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* The declared archives, checked against the naming the Nx graph would have
|
|
930
|
+
* produced. A path that is not `cargoCrossTestArchiveFile(triple)` under some
|
|
931
|
+
* project root cannot have come from that target, so it is refused here rather
|
|
932
|
+
* than uploaded as an artifact nothing on the other side can find.
|
|
933
|
+
*/
|
|
934
|
+
function crossTestArchives(options) {
|
|
935
|
+
return (options.crossTestArchives ?? []).map((archive) => {
|
|
936
|
+
const suffix = cargoCrossTestArchiveFile(archive.triple);
|
|
937
|
+
const path = archive.path.split('\\').join('/');
|
|
938
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/.test(archive.triple)) {
|
|
939
|
+
throw new Error(`smoo cross test archive triple must be a target triple, got ${JSON.stringify(archive.triple)}`);
|
|
940
|
+
}
|
|
941
|
+
if (path !== suffix && !path.endsWith(`/${suffix}`)) {
|
|
942
|
+
throw new Error(`smoo cross test archive for ${archive.triple} must be a repository-relative ${suffix}, got ${archive.path}`);
|
|
943
|
+
}
|
|
944
|
+
if (path.startsWith('/') || path.split('/').includes('..')) {
|
|
945
|
+
throw new Error(`smoo cross test archive path must stay inside the repository, got ${archive.path}`);
|
|
946
|
+
}
|
|
947
|
+
return { triple: archive.triple, path };
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
function crossArchiveTargetNames(options) {
|
|
951
|
+
return crossTestArchives(options).map((archive) => cargoCrossTestArchiveTargetName(archive.triple));
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* The declared preflight, as lines. A declaration with nothing in it is a
|
|
955
|
+
* mechanism error, and it surfaces here at render time rather than as a step
|
|
956
|
+
* whose `run:` block is empty.
|
|
957
|
+
*/
|
|
958
|
+
function crossToolchainPreflight(options) {
|
|
959
|
+
const preflight = options.platformProducer?.preflight ?? '';
|
|
960
|
+
if (preflight.trim().length === 0) {
|
|
961
|
+
throw new Error('smoo.github.platformProducer requires a nonempty toolchain preflight command.');
|
|
962
|
+
}
|
|
963
|
+
return preflight.split('\n');
|
|
964
|
+
}
|
|
965
|
+
/** The producer environment, step-scoped, quoted exactly as the publish workflow quotes it. */
|
|
966
|
+
function platformProducerStepEnvLines(options) {
|
|
967
|
+
const entries = Object.entries(options.platformProducer?.env ?? {});
|
|
968
|
+
if (entries.length === 0)
|
|
969
|
+
return [];
|
|
970
|
+
return [' env:', ...entries.map(([name, value]) => ` ${name}: ${JSON.stringify(value)}`)];
|
|
971
|
+
}
|
|
972
|
+
function darwinCrossTestArchives(options) {
|
|
973
|
+
return crossTestArchives(options).filter((archive) => archive.triple.endsWith(DARWIN_TRIPLE_SUFFIX));
|
|
974
|
+
}
|
|
975
|
+
function darwinCrossTestTargetNames(options) {
|
|
976
|
+
return darwinCrossTestArchives(options).map((archive) => cargoCrossTestTargetName(archive.triple));
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Where the download lands. upload-artifact roots an artifact at the least
|
|
980
|
+
* common ancestor of the files it uploaded, so every archive in one artifact
|
|
981
|
+
* has to share a parent directory for the restored layout to be the one the
|
|
982
|
+
* runner targets read — true for one cargo workspace, false the moment a
|
|
983
|
+
* second one also declares cross targets, which is refused here instead of
|
|
984
|
+
* silently restoring the archives one directory too high.
|
|
985
|
+
*/
|
|
986
|
+
function crossTestArchiveDirectory(options) {
|
|
987
|
+
const directories = new Set(darwinCrossTestArchives(options).map((archive) => archive.path.slice(0, archive.path.lastIndexOf('/') + 1) || './'));
|
|
988
|
+
if (directories.size > 1) {
|
|
989
|
+
throw new Error(`smoo cross test archives must share one directory to travel as one artifact, got ${[...directories].join(', ')}`);
|
|
990
|
+
}
|
|
991
|
+
const [directory] = [...directories];
|
|
992
|
+
return (directory ?? './').replace(/\/$/, '');
|
|
993
|
+
}
|
|
797
994
|
function renderE2eDeploymentJob(options) {
|
|
798
995
|
if (!options.e2eDeployment)
|
|
799
996
|
return '';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type NonEmptyArray, type PackageCargoCredentialsConfig, type PackagePrivateNpmConfig, type PackageRemoteCacheConfig, type PackageSmooGithub, type PackageSmooGithubEnvironments, type PackageSourceCheckoutConfig } from '../lib/json.js';
|
|
2
2
|
import { type NxProjects } from '../nx/index.js';
|
|
3
|
+
import { type CiCrossTestArchive } from './ci-workflow.js';
|
|
3
4
|
/**
|
|
4
5
|
* Repos may append their own content to a managed file below this marker —
|
|
5
6
|
* e.g. extra merge drivers in .gitattributes. Everything from the marker
|
|
@@ -81,6 +82,12 @@ export interface ManagedFileContext {
|
|
|
81
82
|
cargoCredentials?: PackageCargoCredentialsConfig;
|
|
82
83
|
/** Declared self-hosted Nx remote cache from the root smoo config; absent means local caching only. */
|
|
83
84
|
remoteCache?: PackageRemoteCacheConfig;
|
|
85
|
+
/**
|
|
86
|
+
* Cross-built test archives the graph can produce, one per foreign target
|
|
87
|
+
* triple the cargo workspace declares. Empty for a repository that declares
|
|
88
|
+
* none, which renders a CI workflow with no cross steps and no macOS job.
|
|
89
|
+
*/
|
|
90
|
+
crossTestArchives: CiCrossTestArchive[];
|
|
84
91
|
}
|
|
85
92
|
interface DeployTargetInfo {
|
|
86
93
|
exists: boolean;
|
|
@@ -94,6 +101,22 @@ export declare function applyManagedFiles(root: string, mode: 'update' | 'check'
|
|
|
94
101
|
/** Renders a generated workflow through its real managed-file descriptor, so the context wiring is covered. */
|
|
95
102
|
export declare function renderManagedWorkflowForTest(source: 'ci-workflow' | 'publish-workflow', context: ManagedFileContext): string;
|
|
96
103
|
export declare function hasExactTargetForTest(targetNames: Iterable<string>, target: string): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Test seam: the cross-built test archives this graph can produce, read back
|
|
106
|
+
* out of the inferred `cargo-cross-test-archive-<triple>` targets.
|
|
107
|
+
*
|
|
108
|
+
* Derived, not configured. The triple is declared exactly once — in the cargo
|
|
109
|
+
* workspace's own `[workspace.metadata.smoothbricks.test] cross-targets`, where
|
|
110
|
+
* a Rust target triple belongs — and both halves of the workflow are rendered
|
|
111
|
+
* from the targets that declaration produced. A second copy in `smoo.github`
|
|
112
|
+
* could name a triple the graph cannot build, and CI would discover that only
|
|
113
|
+
* on the runner.
|
|
114
|
+
*
|
|
115
|
+
* The path is the target's own output location, so the artifact the Linux job
|
|
116
|
+
* uploads and the file the macOS job's runner opens are the same string
|
|
117
|
+
* computed once.
|
|
118
|
+
*/
|
|
119
|
+
export declare function crossTestArchivesForTest(projects: NxProjects): CiCrossTestArchive[];
|
|
97
120
|
/**
|
|
98
121
|
* The platform families the release workflow produces: the graph's families
|
|
99
122
|
* minus the ones the repository excludes. Excluding a family the graph does not
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { appendFileSync, existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join, resolve } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { cargoCrossTestArchiveFile, cargoCrossTestTripleFromArchiveTarget, } from '@smoothbricks/nx-plugin/cross-check-policy';
|
|
4
5
|
import { MACOS_PLATFORM_TARGET_GLOBS, PLATFORM_TARGET_GLOBS } from '@smoothbricks/nx-plugin/workspace-config-policy';
|
|
5
6
|
import { isStageDerivedDeploy, PRODUCTION_PUSH_DEPLOY_TAG } from '../lib/deploy-tags.js';
|
|
6
7
|
import { ciPushBranches, readValidatedPackageJson, } from '../lib/json.js';
|
|
7
8
|
import { listReleasePackages, packageInfo } from '../lib/workspace.js';
|
|
8
|
-
import { loadNxProjects, targetNamesFromProjects } from '../nx/index.js';
|
|
9
|
+
import { loadNxProjects, projectRootFromNxProjectJson, targetNamesFromNxProjectJson, targetNamesFromProjects, } from '../nx/index.js';
|
|
9
10
|
import { resolvePrivateNpmWorkflowConfig } from '../release/private-npm.js';
|
|
10
11
|
import { privateNpmReadTokenJobEnv, renderCiWorkflowYaml } from './ci-workflow.js';
|
|
11
12
|
import { renderRunsOnLine } from './github-runs-on.js';
|
|
@@ -305,6 +306,9 @@ function getManagedContent(file, context) {
|
|
|
305
306
|
deploySecrets: context.ciDeploySecrets,
|
|
306
307
|
e2eSecrets: context.ciE2eSecrets,
|
|
307
308
|
productionOnPush: context.hasProductionPushDeployTargets,
|
|
309
|
+
crossTestArchives: context.crossTestArchives,
|
|
310
|
+
macosRunsOn: context.macosRunsOn,
|
|
311
|
+
platformProducer: context.platformProducer,
|
|
308
312
|
});
|
|
309
313
|
}
|
|
310
314
|
if (file.source === 'publish-workflow') {
|
|
@@ -397,11 +401,45 @@ async function getManagedFileContext(root) {
|
|
|
397
401
|
? macosPlatformArchitecturesForTest(targetNames)
|
|
398
402
|
: [],
|
|
399
403
|
privateNpm,
|
|
404
|
+
crossTestArchives: crossTestArchivesForTest(nxProjects),
|
|
400
405
|
};
|
|
401
406
|
}
|
|
402
407
|
export function hasExactTargetForTest(targetNames, target) {
|
|
403
408
|
return [...targetNames].includes(target);
|
|
404
409
|
}
|
|
410
|
+
/**
|
|
411
|
+
* Test seam: the cross-built test archives this graph can produce, read back
|
|
412
|
+
* out of the inferred `cargo-cross-test-archive-<triple>` targets.
|
|
413
|
+
*
|
|
414
|
+
* Derived, not configured. The triple is declared exactly once — in the cargo
|
|
415
|
+
* workspace's own `[workspace.metadata.smoothbricks.test] cross-targets`, where
|
|
416
|
+
* a Rust target triple belongs — and both halves of the workflow are rendered
|
|
417
|
+
* from the targets that declaration produced. A second copy in `smoo.github`
|
|
418
|
+
* could name a triple the graph cannot build, and CI would discover that only
|
|
419
|
+
* on the runner.
|
|
420
|
+
*
|
|
421
|
+
* The path is the target's own output location, so the artifact the Linux job
|
|
422
|
+
* uploads and the file the macOS job's runner opens are the same string
|
|
423
|
+
* computed once.
|
|
424
|
+
*/
|
|
425
|
+
export function crossTestArchivesForTest(projects) {
|
|
426
|
+
const archives = [];
|
|
427
|
+
for (const project of Object.values(projects)) {
|
|
428
|
+
const projectRoot = projectRootFromNxProjectJson(project);
|
|
429
|
+
for (const targetName of targetNamesFromNxProjectJson(project)) {
|
|
430
|
+
const triple = cargoCrossTestTripleFromArchiveTarget(targetName);
|
|
431
|
+
if (triple === null) {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
const file = cargoCrossTestArchiveFile(triple);
|
|
435
|
+
archives.push({
|
|
436
|
+
triple,
|
|
437
|
+
path: projectRoot === undefined || projectRoot === '.' ? file : `${projectRoot}/${file}`,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return archives.sort((left, right) => left.triple.localeCompare(right.triple));
|
|
442
|
+
}
|
|
405
443
|
/**
|
|
406
444
|
* The platform families the release workflow produces: the graph's families
|
|
407
445
|
* minus the ones the repository excludes. Excluding a family the graph does not
|
|
@@ -42,6 +42,16 @@ export declare function nxProjectChangelogArgs(pkg: ReleasePackageInfo, previous
|
|
|
42
42
|
dryRun: boolean;
|
|
43
43
|
firstRelease: boolean;
|
|
44
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* The release body for a version that carries no commits of its own.
|
|
47
|
+
*
|
|
48
|
+
* Nx bumps a project when a dependency it depends on was bumped, and reports
|
|
49
|
+
* that reason itself ("because a dependency was bumped"). Such a version has no
|
|
50
|
+
* commits touching the project, so Nx generates no changelog for it — which is
|
|
51
|
+
* correct, not a failure. Treating the absence as fatal made one dependency-only
|
|
52
|
+
* package abort a whole publish after the versions had already been written.
|
|
53
|
+
*/
|
|
54
|
+
export declare const DEPENDENCY_ONLY_RELEASE_NOTES = "_No changelog entries for this package: this version was released because one of its dependencies was bumped._";
|
|
45
55
|
export declare function projectChangelogContents(result: ProjectChangelogLookupResult, projectName: string): string;
|
|
46
56
|
export declare function githubReleaseLookupExists(tag: string, exitCode: number, stdout: string, stderr: string): boolean;
|
|
47
57
|
export declare function githubReleaseCommandArgs(tag: string, notesFile: string, releaseExists: boolean, version: string): string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-release.d.ts","sourceRoot":"","sources":["../../src/release/github-release.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,kBAAkB,EAAc,MAAM,WAAW,CAAC;AAYhE,UAAU,4BAA4B;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,6BAA6B,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACpG,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5G;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAc1G;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,4BAA4B,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"github-release.d.ts","sourceRoot":"","sources":["../../src/release/github-release.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,kBAAkB,EAAc,MAAM,WAAW,CAAC;AAYhE,UAAU,4BAA4B;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,6BAA6B,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACpG,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5G;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAc1G;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,mHACwE,CAAC;AAEnH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,4BAA4B,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1G;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAShH;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,EACtB,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CAgBV;AAMD;;;;;;;;;GASG;AACH,UAAU,kBAAkB;IAC1B,6BAA6B,EAAE,cAAc,gCAAgC,CAAC,CAAC;IAC/E,qCAAqC,EAAE,cAAc,wCAAwC,CAAC,CAAC;IAC/F,uCAAuC,EAAE,cAAc,0CAA0C,CAAC,CAAC;CACpG;AAED,wBAAsB,iBAAiB,CAAC,OAAO,SAAS,MAAM,kBAAkB,EAC9E,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAMtC;AAED,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAmB5F"}
|
|
@@ -49,12 +49,18 @@ export function nxProjectChangelogArgs(pkg, previousTag, dryRun) {
|
|
|
49
49
|
};
|
|
50
50
|
return previousTag ? { ...base, from: previousTag } : { ...base, firstRelease: true };
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* The release body for a version that carries no commits of its own.
|
|
54
|
+
*
|
|
55
|
+
* Nx bumps a project when a dependency it depends on was bumped, and reports
|
|
56
|
+
* that reason itself ("because a dependency was bumped"). Such a version has no
|
|
57
|
+
* commits touching the project, so Nx generates no changelog for it — which is
|
|
58
|
+
* correct, not a failure. Treating the absence as fatal made one dependency-only
|
|
59
|
+
* package abort a whole publish after the versions had already been written.
|
|
60
|
+
*/
|
|
61
|
+
export const DEPENDENCY_ONLY_RELEASE_NOTES = '_No changelog entries for this package: this version was released because one of its dependencies was bumped._';
|
|
52
62
|
export function projectChangelogContents(result, projectName) {
|
|
53
|
-
|
|
54
|
-
if (!changelog) {
|
|
55
|
-
throw new Error(`Nx did not generate a project changelog for ${projectName}.`);
|
|
56
|
-
}
|
|
57
|
-
return changelog.contents;
|
|
63
|
+
return result.projectChangelogs?.[projectName]?.contents ?? DEPENDENCY_ONLY_RELEASE_NOTES;
|
|
58
64
|
}
|
|
59
65
|
export function githubReleaseLookupExists(tag, exitCode, stdout, stderr) {
|
|
60
66
|
if (exitCode === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/release/index.ts"],"names":[],"mappings":"AA8BA,OAAO,EACL,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,WAAW,EACX,kBAAkB,GACnB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,gBAAgB,IAAI,0BAA0B,EAC9C,yBAAyB,IAAI,mCAAmC,EAChE,KAAK,kBAAkB,EACvB,KAAK,6BAA6B,EAClC,KAAK,iCAAiC,EACtC,KAAK,kBAAkB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,KAAK,MAAM,IAAI,gBAAgB,EAC/B,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,KAAK,2BAA2B,EAIjC,MAAM,6BAA6B,CAAC;AAQrC,OAAO,EAQL,KAAK,kBAAkB,EAGxB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/release/index.ts"],"names":[],"mappings":"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"}
|