@smoothbricks/cli 0.11.11 → 0.11.13
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 +104 -20
- package/dist/lib/json.d.ts +51 -0
- package/dist/lib/json.d.ts.map +1 -1
- package/dist/lib/json.js +111 -67
- package/dist/monorepo/cargo-policy.d.ts +25 -1
- package/dist/monorepo/cargo-policy.d.ts.map +1 -1
- package/dist/monorepo/cargo-policy.js +396 -4
- package/dist/monorepo/ci-workflow.d.ts +27 -2
- package/dist/monorepo/ci-workflow.d.ts.map +1 -1
- package/dist/monorepo/ci-workflow.js +151 -11
- package/dist/monorepo/index.d.ts.map +1 -1
- package/dist/monorepo/index.js +5 -1
- package/dist/monorepo/managed-files.d.ts +3 -1
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +3 -0
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +13 -0
- package/dist/monorepo/publish-workflow.d.ts +8 -1
- package/dist/monorepo/publish-workflow.d.ts.map +1 -1
- package/dist/monorepo/publish-workflow.js +15 -5
- package/managed/raw/tooling/direnv/devenv.smoo.nix +28 -2
- package/managed/raw/tooling/direnv/secret-references.ts +248 -51
- package/managed/templates/github/actions/save-nix-devenv/action.yml +2 -2
- package/managed/templates/github/actions/setup-devenv/action.yml +43 -5
- package/package.json +2 -2
- package/src/lib/json.ts +52 -0
- package/src/monorepo/__tests__/ci-workflow.test.ts +183 -0
- package/src/monorepo/__tests__/publish-workflow.test.ts +29 -0
- package/src/monorepo/cargo-policy.test.ts +206 -3
- package/src/monorepo/cargo-policy.ts +341 -2
- package/src/monorepo/ci-workflow.ts +180 -11
- package/src/monorepo/index.ts +5 -1
- package/src/monorepo/managed-files.ts +6 -0
- package/src/monorepo/packs/index.test.ts +32 -0
- package/src/monorepo/packs/index.ts +13 -0
- package/src/monorepo/publish-workflow.ts +24 -4
- package/src/monorepo/secret-references.test.ts +175 -2
|
@@ -80,8 +80,9 @@ jobs:
|
|
|
80
80
|
name: Validate
|
|
81
81
|
${renderRunsOnLine(options.runsOn)}
|
|
82
82
|
timeout-minutes: 45
|
|
83
|
-
${options.privateNpm?.readTokenEnv || options.cargoCredentials !== undefined
|
|
84
|
-
? ` # Fork PRs receive no secrets
|
|
83
|
+
${options.privateNpm?.readTokenEnv || options.cargoCredentials !== undefined || options.remoteCache !== undefined
|
|
84
|
+
? ` # Fork PRs receive no secrets, so neither a private dependency install nor an
|
|
85
|
+
# authenticated remote cache read can run there.
|
|
85
86
|
if: \${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
|
|
86
87
|
`
|
|
87
88
|
: ''}${environmentLine(options.deploy ? options.environments?.staging : undefined)}${options.e2eDeployment
|
|
@@ -90,7 +91,7 @@ ${options.privateNpm?.readTokenEnv || options.cargoCredentials !== undefined
|
|
|
90
91
|
`
|
|
91
92
|
: ''} env:
|
|
92
93
|
GH_TOKEN: ${githubExpression('github.token')}
|
|
93
|
-
${cargoCredentialJobEnvLines(options.cargoCredentials)}${privateNpmReadTokenJobEnv(options)} steps:
|
|
94
|
+
${remoteCacheJobEnvLines(options.remoteCache)}${cargoCredentialJobEnvLines(options.cargoCredentials)}${privateNpmReadTokenJobEnv(options)} steps:
|
|
94
95
|
`;
|
|
95
96
|
}
|
|
96
97
|
function githubExpression(expression) {
|
|
@@ -343,6 +344,68 @@ export function normalizeSourceCheckout(config) {
|
|
|
343
344
|
}
|
|
344
345
|
return config;
|
|
345
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Job env lines carrying the declared Nx remote cache. The pair rides the job
|
|
349
|
+
* env rather than a step because every Nx invocation in the job — build, lint,
|
|
350
|
+
* tests, deploy — reads it, and Nx enables the cache on a nonempty server
|
|
351
|
+
* alone: an empty or absent token would make it authenticate with nothing and
|
|
352
|
+
* fail every task on 401, which is why the job carries the same fork-PR gate
|
|
353
|
+
* as a private dependency install (see `renderCiWorkflowHeader`).
|
|
354
|
+
*
|
|
355
|
+
* A declared `internalServer` is the address managed runners use, exactly as a
|
|
356
|
+
* git origin's `internalMirror` is: both say this repository's runners sit
|
|
357
|
+
* inside that network, and shells outside it keep the public origin.
|
|
358
|
+
* Mechanism errors surface at managed-file render time, never inside CI.
|
|
359
|
+
*/
|
|
360
|
+
export function remoteCacheJobEnvLines(config) {
|
|
361
|
+
if (config === undefined) {
|
|
362
|
+
return '';
|
|
363
|
+
}
|
|
364
|
+
const normalized = normalizeRemoteCache(config);
|
|
365
|
+
return [
|
|
366
|
+
` NX_SELF_HOSTED_REMOTE_CACHE_SERVER: ${normalized.internalServer ?? normalized.server}\n`,
|
|
367
|
+
` NX_SELF_HOSTED_REMOTE_CACHE_ACCESS_TOKEN: ${githubExpression(`secrets.${normalized.tokenSecret}`)}\n`,
|
|
368
|
+
].join('');
|
|
369
|
+
}
|
|
370
|
+
/** Mechanism errors surface at managed-file render time, never inside CI. */
|
|
371
|
+
export function normalizeRemoteCache(config) {
|
|
372
|
+
assertCacheOrigin('server', config.server);
|
|
373
|
+
if (config.internalServer !== undefined) {
|
|
374
|
+
assertCacheOrigin('internalServer', config.internalServer);
|
|
375
|
+
if (config.internalServer === config.server) {
|
|
376
|
+
throw new Error(`smoo.remoteCache internalServer repeats server ${config.server}; drop internalServer or point it at the address internal runners reach`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (!/^[A-Z_][A-Z0-9_]*$/.test(config.tokenSecret)) {
|
|
380
|
+
throw new Error(`smoo.remoteCache needs an upper-case secret name for tokenSecret, got ${JSON.stringify(config.tokenSecret)}`);
|
|
381
|
+
}
|
|
382
|
+
return config;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* A cache origin is exactly `scheme://host[:port]`. Nx appends
|
|
386
|
+
* `/v1/cache/<hash>` to it, so a trailing slash silently requests a doubled
|
|
387
|
+
* slash the server routes nowhere, and a path or credential would be dropped
|
|
388
|
+
* or leaked rather than honored.
|
|
389
|
+
*/
|
|
390
|
+
function assertCacheOrigin(field, value) {
|
|
391
|
+
let url = null;
|
|
392
|
+
try {
|
|
393
|
+
url = new URL(value);
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
url = null;
|
|
397
|
+
}
|
|
398
|
+
if (url === null ||
|
|
399
|
+
(url.protocol !== 'https:' && url.protocol !== 'http:') ||
|
|
400
|
+
url.pathname !== '/' ||
|
|
401
|
+
value.endsWith('/') ||
|
|
402
|
+
url.username !== '' ||
|
|
403
|
+
url.password !== '' ||
|
|
404
|
+
url.search !== '' ||
|
|
405
|
+
url.hash !== '') {
|
|
406
|
+
throw new Error(`smoo.remoteCache ${field} needs a credential-free http(s) origin with no path and no trailing slash, got ${JSON.stringify(value)}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
346
409
|
/**
|
|
347
410
|
* Job env lines carrying the declared Cargo credential secrets. Both registry
|
|
348
411
|
* tokens and git-origin tokens ride the job env so the credential helper is
|
|
@@ -371,7 +434,10 @@ export function cargoCredentialJobEnvLines(config) {
|
|
|
371
434
|
* `internalMirror` are rewritten to the mirror with `url.<mirror>.insteadOf`
|
|
372
435
|
* and the helper answers the same credential for the mirror's host, since git
|
|
373
436
|
* passes helpers the rewritten URL. The helper reads the environment at call
|
|
374
|
-
* time and answers only for declared origins.
|
|
437
|
+
* time and answers only for declared origins. Declared `sshOrigins` rewrite
|
|
438
|
+
* onto the same mirror and stay credential-free: the rewrite happens before
|
|
439
|
+
* transport, so git only ever asks for the mirror, and an SSH pin the runner
|
|
440
|
+
* has no key for fails loudly instead of collecting a token.
|
|
375
441
|
* Mechanism errors surface at managed-file render time, never inside CI.
|
|
376
442
|
*/
|
|
377
443
|
export function cargoCredentialStepLines(step, config) {
|
|
@@ -451,22 +517,49 @@ export function cargoCredentialStepLines(step, config) {
|
|
|
451
517
|
lines.push(' fi');
|
|
452
518
|
lines.push(' # Internal mirrors rewrite the declared origin prefix so runners');
|
|
453
519
|
lines.push(' # that cannot reach the public URL fetch over guest networking.');
|
|
520
|
+
if (origins.some((origin) => origin.sshOrigins !== undefined)) {
|
|
521
|
+
lines.push(' # The same forge over SSH, as Cargo and uv pin it: git matches');
|
|
522
|
+
lines.push(' # insteadOf values as literal URL prefixes, so every declared');
|
|
523
|
+
lines.push(' # spelling rewrites onto the mirror on its own line.');
|
|
524
|
+
}
|
|
454
525
|
for (const origin of origins) {
|
|
455
526
|
if (origin.internalMirror === undefined) {
|
|
456
527
|
continue;
|
|
457
528
|
}
|
|
458
|
-
const originUrl = new URL(origin.origin);
|
|
459
529
|
const mirrorUrl = new URL(origin.internalMirror);
|
|
460
|
-
const originBase = `${originUrl.protocol}//${originUrl.host}/`.replaceAll("'", "'\\''");
|
|
461
530
|
const mirrorBase = `${mirrorUrl.protocol}//${mirrorUrl.host}/`.replaceAll("'", "'\\''");
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
531
|
+
for (const prefix of mirrorRewritePrefixes(origin)) {
|
|
532
|
+
lines.push(' echo "GIT_CONFIG_KEY_${idx}=url.' + mirrorBase + '.insteadOf"');
|
|
533
|
+
lines.push(' echo "GIT_CONFIG_VALUE_${idx}=' + prefix.replaceAll("'", "'\\''") + '"');
|
|
534
|
+
lines.push(' idx=$((idx + 1))');
|
|
535
|
+
}
|
|
465
536
|
}
|
|
466
537
|
lines.push(' echo "GIT_CONFIG_COUNT=${idx}"');
|
|
467
538
|
lines.push(' } >> "$GITHUB_ENV"');
|
|
468
539
|
return lines;
|
|
469
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Every URL prefix a mirrored origin rewrites from: the declared https origin
|
|
543
|
+
* first, then each declared SSH spelling of the same forge. One `insteadOf`
|
|
544
|
+
* value per prefix, because git matches them as literal prefixes and derives
|
|
545
|
+
* no spelling from another. Rendering runs after `normalizeCargoCredentials`,
|
|
546
|
+
* which parsed and refused every malformed entry.
|
|
547
|
+
*/
|
|
548
|
+
function mirrorRewritePrefixes(origin) {
|
|
549
|
+
const originUrl = new URL(origin.origin);
|
|
550
|
+
return [
|
|
551
|
+
`${originUrl.protocol}//${originUrl.host}/`,
|
|
552
|
+
...(origin.sshOrigins ?? []).map((spelling) => sshRewritePrefix(new URL(spelling))),
|
|
553
|
+
];
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* The SSH spelling as a rewritable prefix: userinfo is part of the spelling
|
|
557
|
+
* git matches, and the trailing slash keeps `ssh://host:2223` from also
|
|
558
|
+
* rewriting `ssh://host:22230/`.
|
|
559
|
+
*/
|
|
560
|
+
function sshRewritePrefix(spelling) {
|
|
561
|
+
return `ssh://${spelling.username === '' ? '' : `${spelling.username}@`}${spelling.host}/`;
|
|
562
|
+
}
|
|
470
563
|
function distinctCargoTokenEnvs(config) {
|
|
471
564
|
const seen = new Set();
|
|
472
565
|
for (const env of config.registryTokenEnvs ?? []) {
|
|
@@ -485,12 +578,22 @@ export function normalizeCargoCredentials(config) {
|
|
|
485
578
|
}
|
|
486
579
|
}
|
|
487
580
|
const hosts = new Set();
|
|
581
|
+
const sshPrefixes = new Set();
|
|
488
582
|
for (const origin of config.gitOrigins ?? []) {
|
|
489
583
|
const host = new URL(normalizeCargoGitOrigin(origin).origin).host;
|
|
490
584
|
if (hosts.has(host)) {
|
|
491
585
|
throw new Error(`smoo.github.cargoCredentials repeats git origin host ${host}; declare one token per origin`);
|
|
492
586
|
}
|
|
493
587
|
hosts.add(host);
|
|
588
|
+
for (const spelling of origin.sshOrigins ?? []) {
|
|
589
|
+
// One spelling, one rewrite, whole config: a repeat renders two
|
|
590
|
+
// identical insteadOf keys and git silently keeps the last one read.
|
|
591
|
+
const prefix = sshRewritePrefix(assertSshOrigin(spelling));
|
|
592
|
+
if (sshPrefixes.has(prefix)) {
|
|
593
|
+
throw new Error(`smoo.github.cargoCredentials repeats the sshOrigins spelling ${prefix}; declare each spelling once, on the origin whose mirror rewrites it`);
|
|
594
|
+
}
|
|
595
|
+
sshPrefixes.add(prefix);
|
|
596
|
+
}
|
|
494
597
|
}
|
|
495
598
|
if ((config.registryTokenEnvs?.length ?? 0) === 0 && (config.gitOrigins?.length ?? 0) === 0) {
|
|
496
599
|
throw new Error('smoo.github.cargoCredentials needs at least one gitOrigins or registryTokenEnvs entry, got an empty configuration');
|
|
@@ -538,8 +641,45 @@ function normalizeCargoGitOrigin(origin) {
|
|
|
538
641
|
throw new Error(`smoo.github.cargoCredentials gitOrigins entry rewrites ${origin.origin} to itself; drop internalMirror or point it at the internal mirror`);
|
|
539
642
|
}
|
|
540
643
|
}
|
|
644
|
+
if (origin.sshOrigins !== undefined) {
|
|
645
|
+
if (origin.internalMirror === undefined) {
|
|
646
|
+
throw new Error(`smoo.github.cargoCredentials gitOrigins entry declares sshOrigins for ${origin.origin} without an internalMirror to rewrite them onto; an SSH spelling is a rewrite source and nothing else`);
|
|
647
|
+
}
|
|
648
|
+
if (origin.sshOrigins.length === 0) {
|
|
649
|
+
throw new Error(`smoo.github.cargoCredentials gitOrigins entry for ${origin.origin} declares an empty sshOrigins list; name every SSH spelling a lockfile can carry, or omit the field`);
|
|
650
|
+
}
|
|
651
|
+
for (const spelling of origin.sshOrigins) {
|
|
652
|
+
assertSshOrigin(spelling);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
541
655
|
return origin;
|
|
542
656
|
}
|
|
657
|
+
/**
|
|
658
|
+
* One declared SSH spelling, parsed. Credential-free and path-free: a
|
|
659
|
+
* password here would be a secret committed in package.json, and a path
|
|
660
|
+
* would rewrite a single repository instead of the forge. scp syntax
|
|
661
|
+
* (`git@host:org/repo.git`) is no URL, so git cannot rewrite it from a Cargo
|
|
662
|
+
* or uv pin at all; the `ssh://` spelling is the one to declare.
|
|
663
|
+
*/
|
|
664
|
+
function assertSshOrigin(spelling) {
|
|
665
|
+
let ssh = null;
|
|
666
|
+
try {
|
|
667
|
+
ssh = new URL(spelling);
|
|
668
|
+
}
|
|
669
|
+
catch {
|
|
670
|
+
ssh = null;
|
|
671
|
+
}
|
|
672
|
+
if (ssh === null ||
|
|
673
|
+
ssh.protocol !== 'ssh:' ||
|
|
674
|
+
ssh.host === '' ||
|
|
675
|
+
(ssh.pathname !== '' && ssh.pathname !== '/') ||
|
|
676
|
+
ssh.password !== '' ||
|
|
677
|
+
ssh.search !== '' ||
|
|
678
|
+
ssh.hash !== '') {
|
|
679
|
+
throw new Error(`smoo.github.cargoCredentials gitOrigins entry needs credential-free ssh:// sshOrigins without a path, got ${JSON.stringify(spelling)}`);
|
|
680
|
+
}
|
|
681
|
+
return ssh;
|
|
682
|
+
}
|
|
543
683
|
/**
|
|
544
684
|
* The same-repo gate as prettier folds it: the raw single line exceeds the
|
|
545
685
|
* print width, so the generator emits the folded form itself to keep the
|
|
@@ -660,7 +800,7 @@ ${renderRunsOnLine(options.runsOn)}
|
|
|
660
800
|
${environmentLine(options.environments?.staging)} if: \${{ needs.main.result == 'success' && needs.main.outputs.deployment-stage != '' }}
|
|
661
801
|
env:
|
|
662
802
|
GH_TOKEN: \${{ github.token }}
|
|
663
|
-
${cargoCredentialJobEnvLines(options.cargoCredentials)}${privateNpmReadTokenJobEnv(options)} steps:
|
|
803
|
+
${remoteCacheJobEnvLines(options.remoteCache)}${cargoCredentialJobEnvLines(options.cargoCredentials)}${privateNpmReadTokenJobEnv(options)} steps:
|
|
664
804
|
${renderCiWorkflowSteps(followUpSetupSteps(options, numbers), options)}
|
|
665
805
|
# Step ${numbers.middle}
|
|
666
806
|
- name: E2E Tests (Deployed Stage)
|
|
@@ -691,7 +831,7 @@ ${renderRunsOnLine(options.runsOn)}
|
|
|
691
831
|
if: \${{ !cancelled() && github.event_name == 'push' && github.ref == ${stagingRefLiteral(options)} && needs.main.result == 'success'${e2eGate} }}
|
|
692
832
|
${environmentLine(options.environments?.production)} env:
|
|
693
833
|
GH_TOKEN: \${{ github.token }}
|
|
694
|
-
${cargoCredentialJobEnvLines(options.cargoCredentials)}${privateNpmReadTokenJobEnv(options)} steps:
|
|
834
|
+
${remoteCacheJobEnvLines(options.remoteCache)}${cargoCredentialJobEnvLines(options.cargoCredentials)}${privateNpmReadTokenJobEnv(options)} steps:
|
|
695
835
|
${renderCiWorkflowSteps(followUpSetupSteps(options, numbers), options)}
|
|
696
836
|
# Step ${numbers.middle}
|
|
697
837
|
- name: 🚀 Deploy Production
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/monorepo/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AA2BxD,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,4BAA4B;IAC3C,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBjG;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/monorepo/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AA2BxD,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,4BAA4B;IAC3C,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBjG;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBpE;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBrG;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAElE;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,GAAE,4BAAiC,EAC1C,IAAI,SAAgB,GACnB,IAAI,CAoBN;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,MAAM,CAW3G;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI5D;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,uBAAuB,EAChC,KAAK,GAAE,qBAAoD,GAC1D,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,CAAC"}
|
package/dist/monorepo/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { appendFileSync, readFileSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { printCommandOutput, run, runResult } from '../lib/run.js';
|
|
3
3
|
import { escapeRegex, getWorkspacePackages, getWorkspacePatterns, listReleasePackages } from '../lib/workspace.js';
|
|
4
4
|
import { readProjectTargets } from '../nx/index.js';
|
|
5
|
-
import { validateCargoCachePolicy } from './cargo-policy.js';
|
|
5
|
+
import { applyCargoFeatureUnification, validateCargoCachePolicy } from './cargo-policy.js';
|
|
6
6
|
import { formatCommitMessage, stagedDeletedPublicPackages, validateBreakingDisclosure, validateCommitMessage, } from './commit-msg.js';
|
|
7
7
|
import { applyWorkspaceGitConfig } from './git-config.js';
|
|
8
8
|
import { syncBunLockfileVersions } from './lockfile.js';
|
|
@@ -49,6 +49,10 @@ export async function updateManagedFiles(root) {
|
|
|
49
49
|
// Tool dependency policy (typescript API 6, @typescript/native for ttsc, nx, …)
|
|
50
50
|
// lives next to managed templates — update must install them, not only rewrite files.
|
|
51
51
|
await applyToolConfigDefaults(root);
|
|
52
|
+
// Rust's half of the same job: a multi-crate Cargo workspace must resolve
|
|
53
|
+
// features once for every member, or each per-crate cargo invocation
|
|
54
|
+
// recompiles the shared graph for its own selection.
|
|
55
|
+
applyCargoFeatureUnification(root);
|
|
52
56
|
syncBunLockfileVersions(root, { mode: 'install' });
|
|
53
57
|
console.log('installing workspace dependencies (bun install)');
|
|
54
58
|
await run('bun', ['install', '--no-summary'], root);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type NonEmptyArray, type PackageCargoCredentialsConfig, type PackagePrivateNpmConfig, type PackageSmooGithub, type PackageSmooGithubEnvironments, type PackageSourceCheckoutConfig } from '../lib/json.js';
|
|
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
3
|
/**
|
|
4
4
|
* Repos may append their own content to a managed file below this marker —
|
|
@@ -77,6 +77,8 @@ export interface ManagedFileContext {
|
|
|
77
77
|
sourceCheckouts?: PackageSourceCheckoutConfig[];
|
|
78
78
|
/** Declared Cargo private-dependency credentials from the root smoo config; absent means none. */
|
|
79
79
|
cargoCredentials?: PackageCargoCredentialsConfig;
|
|
80
|
+
/** Declared self-hosted Nx remote cache from the root smoo config; absent means local caching only. */
|
|
81
|
+
remoteCache?: PackageRemoteCacheConfig;
|
|
80
82
|
}
|
|
81
83
|
interface DeployTargetInfo {
|
|
82
84
|
exists: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,aAAa,EAElB,KAAK,6BAA6B,EAElC,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAEjC,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAkB,KAAK,UAAU,EAA2B,MAAM,gBAAgB,CAAC;AAS1F;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,yEAAyE,CAAC;AAW3G,sFAAsF;AACtF,iBAAS,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAIlF;AAED,uCAAuC;AACvC,eAAO,MAAM,wBAAwB,0BAAoB,CAAC;AAE1D;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;8BAE8B;AAC9B,iBAAS,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,EAAE,CAAA;CAAE,CAkCxG;AAED,wCAAwC;AACxC,eAAO,MAAM,+BAA+B,iCAA2B,CAAC;AAExE;+EAC+E;AAC/E,iBAAS,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAuBtF;AAED,yCAAyC;AACzC,eAAO,MAAM,gCAAgC,kCAA4B,CAAC;AAE1E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,GAAG,YAAY,CAAC;CACxG;AAED,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,uBAAuB,EAAE,OAAO,CAAC;IACjC,0BAA0B,EAAE,OAAO,CAAC;IACpC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uBAAuB,EAAE,OAAO,CAAC;IACjC,8BAA8B,EAAE,OAAO,CAAC;IACxC,qBAAqB,CAAC,EAAE,YAAY,CAAC;IACrC,wBAAwB,CAAC,EAAE,YAAY,CAAC;IACxC,cAAc,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,yFAAyF;IACzF,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IACzD,eAAe,CAAC,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACvD,cAAc,CAAC,EAAE,6BAA6B,CAAC;IAC/C,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,0BAA0B,EAAE,MAAM,EAAE,CAAC;IACrC,wFAAwF;IACxF,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,sFAAsF;IACtF,eAAe,CAAC,EAAE,2BAA2B,EAAE,CAAC;IAChD,kGAAkG;IAClG,gBAAgB,CAAC,EAAE,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -294,6 +294,7 @@ function getManagedContent(file, context) {
|
|
|
294
294
|
privateNpm: context.privateNpm,
|
|
295
295
|
sourceCheckouts: context.sourceCheckouts,
|
|
296
296
|
cargoCredentials: context.cargoCredentials,
|
|
297
|
+
remoteCache: context.remoteCache,
|
|
297
298
|
environments: context.ciEnvironments,
|
|
298
299
|
deploySecrets: context.ciDeploySecrets,
|
|
299
300
|
e2eSecrets: context.ciE2eSecrets,
|
|
@@ -317,6 +318,7 @@ function getManagedContent(file, context) {
|
|
|
317
318
|
privateNpm: context.privateNpm,
|
|
318
319
|
sourceCheckouts: context.sourceCheckouts,
|
|
319
320
|
cargoCredentials: context.cargoCredentials,
|
|
321
|
+
remoteCache: context.remoteCache,
|
|
320
322
|
deploySecrets: context.ciDeploySecrets,
|
|
321
323
|
});
|
|
322
324
|
}
|
|
@@ -378,6 +380,7 @@ async function getManagedFileContext(root) {
|
|
|
378
380
|
platformTargetGlobs,
|
|
379
381
|
sourceCheckouts,
|
|
380
382
|
cargoCredentials,
|
|
383
|
+
remoteCache: manifest?.smoo?.remoteCache,
|
|
381
384
|
macosPlatformArchitectures: macosPlatformArchitecturesForTest(targetNames),
|
|
382
385
|
privateNpm,
|
|
383
386
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/monorepo/packs/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAsB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/monorepo/packs/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAsB,MAAM,mBAAmB,CAAC;AAO5E,OAAO,EAKL,KAAK,sBAAsB,EAS5B,MAAM,sBAAsB,CAAC;AAU9B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClD,WAAW,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD,YAAY,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,gBAAgB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAClE,iBAAiB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CACpE;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC9F;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AA8ID,0DAA0D;AAC1D,eAAO,MAAM,YAAY,gBAAQ,CAAC;AAElC,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAItE;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,mBAAwB,EACjC,KAAK,GAAE,oBAAyB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAuMD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAexG"}
|
|
@@ -2,6 +2,7 @@ import { chmodSync, existsSync, statSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { printCommandOutput, runResult, runStatus } from '../../lib/run.js';
|
|
4
4
|
import { readProjectTargets } from '../../nx/index.js';
|
|
5
|
+
import { applyCargoFeatureUnification, validateCargoCachePolicy } from '../cargo-policy.js';
|
|
5
6
|
import { validateGoToolchainAgreement } from '../go-toolchain.js';
|
|
6
7
|
import { syncBunLockfileVersions, validateBunLockfileVersions } from '../lockfile.js';
|
|
7
8
|
import { validateDevenvModuleImport, warnOnManagedFileDrift } from '../managed-files.js';
|
|
@@ -64,6 +65,18 @@ const packs = [
|
|
|
64
65
|
return validateDevenvModuleImport(ctx.root);
|
|
65
66
|
},
|
|
66
67
|
},
|
|
68
|
+
{
|
|
69
|
+
// Cargo's build-cache and feature-unification conventions. `--fix` writes
|
|
70
|
+
// the workspace feature unification a multi-crate workspace needs; the rest
|
|
71
|
+
// of the policy is a verdict a human has to act on.
|
|
72
|
+
name: 'cargo',
|
|
73
|
+
fixPreBuild(ctx) {
|
|
74
|
+
applyCargoFeatureUnification(ctx.root);
|
|
75
|
+
},
|
|
76
|
+
validatePreBuild(ctx) {
|
|
77
|
+
return validateCargoCachePolicy(ctx.root);
|
|
78
|
+
},
|
|
79
|
+
},
|
|
67
80
|
{
|
|
68
81
|
name: 'publishing',
|
|
69
82
|
init(ctx) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PackageCargoCredentialsConfig, PackagePrivateNpmConfig, PackageSmooGithub, PackageSourceCheckoutConfig } from '../lib/json.js';
|
|
1
|
+
import type { PackageCargoCredentialsConfig, PackagePrivateNpmConfig, PackageRemoteCacheConfig, PackageSmooGithub, PackageSourceCheckoutConfig } from '../lib/json.js';
|
|
2
2
|
import { type DeployStepSecretConfig } from './ci-workflow.js';
|
|
3
3
|
import { type WorkflowRunsOn } from './github-runs-on.js';
|
|
4
4
|
export type PublishWorkflowBump = 'auto' | 'patch' | 'minor' | 'major' | 'prerelease';
|
|
@@ -72,6 +72,13 @@ export interface PublishWorkflowDefinitionOptions extends DeployStepSecretConfig
|
|
|
72
72
|
* become job env because every later cargo fetch resolves them.
|
|
73
73
|
*/
|
|
74
74
|
cargoCredentials?: PackageCargoCredentialsConfig;
|
|
75
|
+
/**
|
|
76
|
+
* Declared self-hosted Nx remote cache. Every job here runs Nx targets —
|
|
77
|
+
* the release-candidate build, the platform build, the publish gate — so
|
|
78
|
+
* each carries the server and access token and reuses what CI already
|
|
79
|
+
* built for the same hashes.
|
|
80
|
+
*/
|
|
81
|
+
remoteCache?: PackageRemoteCacheConfig;
|
|
75
82
|
}
|
|
76
83
|
export interface PublishWorkflowInputs {
|
|
77
84
|
bump: PublishWorkflowBump;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,6BAA6B,EAC7B,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAKL,KAAK,sBAAsB,
|
|
1
|
+
{"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { LINUX_PLATFORM_TARGET_GLOBS, MACOS_PLATFORM_TARGET_GLOBS, } from '@smoothbricks/nx-plugin/workspace-config-policy';
|
|
3
3
|
import { makeModuleSynchronized } from 'make-synchronized';
|
|
4
4
|
import { isSmoothBricksCodebasePackageName } from '../lib/cli-package.js';
|
|
5
|
-
import { artifactStepLines, CiWorkflowStepKind, cargoCredentialJobEnvLines, cargoCredentialStepLines, deployStepSecretEnvLines, sourceCheckoutsStepLines, } from './ci-workflow.js';
|
|
5
|
+
import { artifactStepLines, CiWorkflowStepKind, cargoCredentialJobEnvLines, cargoCredentialStepLines, deployStepSecretEnvLines, remoteCacheJobEnvLines, sourceCheckoutsStepLines, } from './ci-workflow.js';
|
|
6
6
|
import { GITHUB_HOSTED_LINUX_RUNNER, renderRunsOnLine } from './github-runs-on.js';
|
|
7
7
|
const PUBLISH_WORKFLOW_FORMAT_OPTIONS = Object.freeze({
|
|
8
8
|
parser: 'yaml',
|
|
@@ -321,7 +321,7 @@ jobs:
|
|
|
321
321
|
publish:
|
|
322
322
|
${options.release === false ? renderRunsOnLine(options.runsOn) : publishJobRunsOnLine(options)}
|
|
323
323
|
env:
|
|
324
|
-
GH_TOKEN: ${githubExpression('github.token')}${cargoCredentialsJobEnv(options)}${privateNpmInstallJobEnv(options)}
|
|
324
|
+
GH_TOKEN: ${githubExpression('github.token')}${remoteCacheJobEnv(options)}${cargoCredentialsJobEnv(options)}${privateNpmInstallJobEnv(options)}
|
|
325
325
|
steps:
|
|
326
326
|
`;
|
|
327
327
|
}
|
|
@@ -538,6 +538,16 @@ function cargoCredentialsJobEnv(options) {
|
|
|
538
538
|
const rendered = cargoCredentialJobEnvLines(options.cargoCredentials).trimEnd();
|
|
539
539
|
return rendered === '' ? '' : `\n${rendered}`;
|
|
540
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* The remote cache is job env for the same reason: every Nx target in the job
|
|
543
|
+
* reads it, and a release build that missed the cache would rebuild what CI
|
|
544
|
+
* already built for the identical hashes. Only `${{ secrets.NAME }}` is
|
|
545
|
+
* rendered for the token. Malformed declarations throw here, not in CI.
|
|
546
|
+
*/
|
|
547
|
+
function remoteCacheJobEnv(options) {
|
|
548
|
+
const rendered = remoteCacheJobEnvLines(options.remoteCache).trimEnd();
|
|
549
|
+
return rendered === '' ? '' : `\n${rendered}`;
|
|
550
|
+
}
|
|
541
551
|
function renderSingleJobPublishWorkflowSteps(steps, options) {
|
|
542
552
|
const lines = [];
|
|
543
553
|
for (const step of steps) {
|
|
@@ -605,7 +615,7 @@ ${renderRunsOnLine(options.runsOn)}
|
|
|
605
615
|
mode: ${githubExpression('steps.version.outputs.mode')}
|
|
606
616
|
release-sha: ${githubExpression('steps.release-state.outputs.sha')}
|
|
607
617
|
env:
|
|
608
|
-
GH_TOKEN: ${githubExpression('github.token')}${cargoCredentialsJobEnv(options)}${privateNpmInstallJobEnv(options)}
|
|
618
|
+
GH_TOKEN: ${githubExpression('github.token')}${remoteCacheJobEnv(options)}${cargoCredentialsJobEnv(options)}${privateNpmInstallJobEnv(options)}
|
|
609
619
|
steps:
|
|
610
620
|
${renderLinuxReleaseCandidateSteps(steps, options)}
|
|
611
621
|
|
|
@@ -615,7 +625,7 @@ ${renderMacosJobHeaderLines(options)}
|
|
|
615
625
|
contents: read
|
|
616
626
|
id-token: none
|
|
617
627
|
env:
|
|
618
|
-
GH_TOKEN: ${githubExpression('github.token')}${cargoCredentialsJobEnv(options)}${privateNpmInstallJobEnv(options)}
|
|
628
|
+
GH_TOKEN: ${githubExpression('github.token')}${remoteCacheJobEnv(options)}${cargoCredentialsJobEnv(options)}${privateNpmInstallJobEnv(options)}
|
|
619
629
|
${Object.entries(options.platformProducer?.env ?? {})
|
|
620
630
|
.map(([name, value]) => ` ${name}: ${JSON.stringify(value)}`)
|
|
621
631
|
.join('\n')}
|
|
@@ -630,7 +640,7 @@ ${publishJobRunsOnLine(options)}
|
|
|
630
640
|
id-token: write
|
|
631
641
|
env:
|
|
632
642
|
TTSC_TSGO_BINARY: ${githubExpression('github.workspace')}/node_modules/@typescript/native/bin/tsc
|
|
633
|
-
GH_TOKEN: ${githubExpression('github.token')}${cargoCredentialsJobEnv(options)}${privateNpmInstallJobEnv(options)}
|
|
643
|
+
GH_TOKEN: ${githubExpression('github.token')}${remoteCacheJobEnv(options)}${cargoCredentialsJobEnv(options)}${privateNpmInstallJobEnv(options)}
|
|
634
644
|
steps:
|
|
635
645
|
${renderFinalLinuxPublishSteps(options)}
|
|
636
646
|
`;
|
|
@@ -221,6 +221,12 @@
|
|
|
221
221
|
# variants per crate and 26 GB of junk before this existed), and a sweep
|
|
222
222
|
# prunes them without touching the warm current-fingerprint surface.
|
|
223
223
|
pkgs.cargo-sweep
|
|
224
|
+
# The stable-toolchain arm of smoo's workspace feature-unification policy:
|
|
225
|
+
# `cargo hakari` generates and wires the workspace-hack crate that unifies
|
|
226
|
+
# features when `[resolver] feature-unification` — nightly-only, and what
|
|
227
|
+
# the channel above selects — is unavailable. `smoo monorepo validate` runs
|
|
228
|
+
# `cargo hakari verify` for a workspace that took that route.
|
|
229
|
+
pkgs.cargo-hakari
|
|
224
230
|
];
|
|
225
231
|
|
|
226
232
|
enterShell = lib.mkMerge [
|
|
@@ -268,7 +274,17 @@
|
|
|
268
274
|
# 5. The shared setup-environment.ts bootstraps repository dependencies; a
|
|
269
275
|
# failure aborts shell entry instead of yielding a half-working shell.
|
|
270
276
|
# Repo-owned enterShell bodies merge after this prologue.
|
|
271
|
-
# 6.
|
|
277
|
+
# 6. The declared Nx remote cache (`smoo.remoteCache`), if the repository
|
|
278
|
+
# has one. secret-references.ts prints the two variables Nx reads — the
|
|
279
|
+
# server and the access token — and prints nothing at all unless the
|
|
280
|
+
# declared token has a value, because Nx accepts only 200 or 404 from a
|
|
281
|
+
# cache server: an unauthenticated one fails every task on 401 instead
|
|
282
|
+
# of missing quietly. It is eval-ed into THIS shell because that is
|
|
283
|
+
# where Nx runs; the export covers those two variables only, so the rule
|
|
284
|
+
# that keeps `smoo.secrets` inside the setup child still holds. An
|
|
285
|
+
# inherited server wins, so a CI job env is never overwritten, and a
|
|
286
|
+
# missing token costs a stderr line rather than shell entry.
|
|
287
|
+
# 7. GOROOT is unset rather than set. With devenv's Go pinned to the patch
|
|
272
288
|
# release ttsc vendors, a GOROOT crossing cannot misfire on version at all,
|
|
273
289
|
# so this is belt-and-braces rather than the fix — it keeps the isolation
|
|
274
290
|
# boundary intact even while the two are momentarily out of step, e.g. after
|
|
@@ -280,7 +296,7 @@
|
|
|
280
296
|
# resolves its own GOROOT from its own binary, which makes "whose Go is
|
|
281
297
|
# whose" a property of which binary is invoked — the only thing that can
|
|
282
298
|
# actually be reasoned about.
|
|
283
|
-
#
|
|
299
|
+
# 8. On Darwin, drop nix CC/CXX so xcodebuild finds Xcode's clang (it supports
|
|
284
300
|
# -index-store-path); bun/node native addons find compilers through
|
|
285
301
|
# node-gyp. CC/CXX are what xcodebuild reads, which is why they go rather
|
|
286
302
|
# than being pointed somewhere else.
|
|
@@ -310,6 +326,15 @@
|
|
|
310
326
|
(lib.mkBefore ''
|
|
311
327
|
cd "$DEVENV_ROOT/../.."
|
|
312
328
|
export PATH="$("$PWD/tooling/direnv/repo-path")"
|
|
329
|
+
# devenv enters the shell with TMPDIR unset (not empty) on every platform.
|
|
330
|
+
# Tools then fall back to /tmp, which on Darwin is not the per-user
|
|
331
|
+
# temporary directory the OS hands out, and a test that asserts the
|
|
332
|
+
# parent carries TMPDIR (so its env_clear check means something) fails in
|
|
333
|
+
# the shell and passes outside it. Ask the OS; an explicit value wins.
|
|
334
|
+
if [ -z "''${TMPDIR:-}" ]; then
|
|
335
|
+
TMPDIR="$(getconf DARWIN_USER_TEMP_DIR 2>/dev/null || true)"
|
|
336
|
+
export TMPDIR="''${TMPDIR:-/tmp}"
|
|
337
|
+
fi
|
|
313
338
|
export TTSC_TSGO_BINARY="$PWD/node_modules/@typescript/native/bin/tsc"
|
|
314
339
|
if [ -d "$HOME/.cowshed/caches" ]; then
|
|
315
340
|
export TTSC_CACHE_DIR="''${TTSC_CACHE_DIR:-$HOME/.cowshed/caches/ttsc}"
|
|
@@ -324,6 +349,7 @@
|
|
|
324
349
|
export GOFLAGS="''${GOFLAGS:--trimpath}"
|
|
325
350
|
unset GOROOT
|
|
326
351
|
bun "$DEVENV_ROOT/setup-environment.ts" || exit $?
|
|
352
|
+
eval "$(bun "$DEVENV_ROOT/secret-references.ts" "$PWD")"
|
|
327
353
|
export NX_SOCKET_DIR="''${NX_SOCKET_DIR:-$DEVENV_RUNTIME/nx}"
|
|
328
354
|
mkdir -p "$NX_SOCKET_DIR"
|
|
329
355
|
${lib.optionalString pkgs.stdenv.isDarwin ''
|