@smoothbricks/cli 0.10.5 โ 0.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2 -2
- package/dist/github-ci/index.d.ts.map +1 -1
- package/dist/github-ci/index.js +5 -3
- package/dist/lib/json.d.ts +2 -0
- package/dist/lib/json.d.ts.map +1 -1
- package/dist/lib/json.js +2 -2
- package/dist/monorepo/ci-workflow.d.ts +2 -0
- package/dist/monorepo/ci-workflow.d.ts.map +1 -1
- package/dist/monorepo/ci-workflow.js +10 -4
- package/dist/monorepo/github-runs-on.d.ts +14 -0
- package/dist/monorepo/github-runs-on.d.ts.map +1 -0
- package/dist/monorepo/github-runs-on.js +43 -0
- package/dist/monorepo/index.d.ts +2 -2
- package/dist/monorepo/index.d.ts.map +1 -1
- package/dist/monorepo/index.js +7 -7
- package/dist/monorepo/managed-files.d.ts +30 -3
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +78 -63
- package/dist/monorepo/packs/index.js +1 -1
- package/dist/monorepo/publish-workflow.d.ts +3 -0
- package/dist/monorepo/publish-workflow.d.ts.map +1 -1
- package/dist/monorepo/publish-workflow.js +17 -14
- package/managed/raw/tooling/direnv/github-actions-bootstrap.sh +24 -7
- package/managed/templates/github/actions/cache-nix-devenv/action.yml +13 -11
- package/managed/templates/github/actions/save-nix-devenv/action.yml +34 -3
- package/managed/templates/github/actions/setup-devenv/action.yml +44 -15
- package/managed/templates/github/workflows/managed-files.yml +64 -12
- package/package.json +1 -1
- package/src/cli.ts +2 -2
- package/src/github-ci/index.test.ts +3 -3
- package/src/github-ci/index.ts +6 -3
- package/src/lib/json.ts +2 -0
- package/src/monorepo/__tests__/ci-workflow.test.ts +37 -1
- package/src/monorepo/__tests__/publish-workflow.test.ts +28 -1
- package/src/monorepo/ci-workflow.ts +14 -4
- package/src/monorepo/github-runs-on.ts +45 -0
- package/src/monorepo/index.ts +7 -7
- package/src/monorepo/managed-files.test.ts +49 -0
- package/src/monorepo/managed-files.ts +100 -64
- package/src/monorepo/packs/index.ts +1 -1
- package/src/monorepo/publish-workflow.ts +23 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import synchronizedPrettier from '@prettier/sync';
|
|
3
3
|
import { LINUX_PLATFORM_TARGET_GLOBS, MACOS_PLATFORM_TARGET_GLOBS, } from '@smoothbricks/nx-plugin/workspace-config-policy';
|
|
4
4
|
import { isSmoothBricksCodebasePackageName } from '../lib/cli-package.js';
|
|
5
|
+
import { renderRunsOnLine } from './github-runs-on.js';
|
|
5
6
|
const PUBLISH_WORKFLOW_FORMAT_OPTIONS = Object.freeze({
|
|
6
7
|
parser: 'yaml',
|
|
7
8
|
printWidth: 120,
|
|
@@ -338,7 +339,8 @@ function yamlLinesForStep(step, options) {
|
|
|
338
339
|
case PublishWorkflowStepKind.UploadTraceDbs:
|
|
339
340
|
return [
|
|
340
341
|
` - name: ${step.name}`,
|
|
341
|
-
|
|
342
|
+
' # Default is success(); failure() uploads traces only when the job already failed.',
|
|
343
|
+
' if: failure()',
|
|
342
344
|
' uses: actions/upload-artifact@v7.0.1',
|
|
343
345
|
' with:',
|
|
344
346
|
` name: trace-results-${githubExpression('github.run_id')}`,
|
|
@@ -362,7 +364,8 @@ function yamlLinesForStep(step, options) {
|
|
|
362
364
|
case PublishWorkflowStepKind.SaveNixDevenv:
|
|
363
365
|
return [
|
|
364
366
|
` - name: ${step.name}`,
|
|
365
|
-
|
|
367
|
+
' # success() is default; always() still saves GH Nix cache after a red job.',
|
|
368
|
+
' if: always()',
|
|
366
369
|
' uses: ./.github/actions/save-nix-devenv',
|
|
367
370
|
' with:',
|
|
368
371
|
` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`,
|
|
@@ -392,7 +395,7 @@ function deployEnvLines(options) {
|
|
|
392
395
|
}
|
|
393
396
|
function conditionalRunStep(step, run) {
|
|
394
397
|
const condition = "steps.version.outputs.mode != 'none'";
|
|
395
|
-
return [` - name: ${step.name}`, ` if: ${
|
|
398
|
+
return [` - name: ${step.name}`, ` if: ${condition}`, ` run: ${run}`];
|
|
396
399
|
}
|
|
397
400
|
function renderSingleJobPublishWorkflowSteps(steps, options) {
|
|
398
401
|
const lines = [];
|
|
@@ -402,7 +405,7 @@ function renderSingleJobPublishWorkflowSteps(steps, options) {
|
|
|
402
405
|
lines.push(...yamlLinesForStep(step, options));
|
|
403
406
|
lines.push('');
|
|
404
407
|
if (step.kind === PublishWorkflowStepKind.Build) {
|
|
405
|
-
lines.push(' - name: ๐ง Build supplemental Linux targets',
|
|
408
|
+
lines.push(' - name: ๐ง Build supplemental Linux targets', " if: steps.version.outputs.mode != 'none'", ` run: smoo github-ci nx-run-many --targets "${LINUX_PLATFORM_TARGET_GLOBS.join(',')}" --projects "${githubExpression('steps.version.outputs.projects')}"`, '');
|
|
406
409
|
}
|
|
407
410
|
}
|
|
408
411
|
return `${lines.join('\n').trimEnd()}\n`;
|
|
@@ -447,7 +450,7 @@ defaults:
|
|
|
447
450
|
|
|
448
451
|
jobs:
|
|
449
452
|
linux-release-candidate:
|
|
450
|
-
|
|
453
|
+
${renderRunsOnLine(options.runsOn)}
|
|
451
454
|
permissions:
|
|
452
455
|
contents: write
|
|
453
456
|
id-token: none
|
|
@@ -508,7 +511,7 @@ function renderLinuxReleaseCandidateSteps(steps, options) {
|
|
|
508
511
|
lines.push(` - name: ${step.name}`, ' uses: actions/checkout@v6.0.2', ' with:', ` ref: ${githubExpression('github.sha')}`, ' filter: blob:none', ' fetch-depth: 0');
|
|
509
512
|
}
|
|
510
513
|
else if (step.kind === PublishWorkflowStepKind.Build) {
|
|
511
|
-
lines.push(` - name: ${step.name}`,
|
|
514
|
+
lines.push(` - name: ${step.name}`, " if: steps.version.outputs.mode != 'none'", ' run:', ` smoo github-ci nx-run-many --targets build --projects "${githubExpression('steps.version.outputs.projects')}" --collect-outputs "${githubExpression('runner.temp')}/release-build-outputs"`);
|
|
512
515
|
}
|
|
513
516
|
else {
|
|
514
517
|
lines.push(...yamlLinesForStep(step, options));
|
|
@@ -519,16 +522,16 @@ function renderLinuxReleaseCandidateSteps(steps, options) {
|
|
|
519
522
|
stepNumber += 1;
|
|
520
523
|
}
|
|
521
524
|
if (step.kind === PublishWorkflowStepKind.Build && hasLinuxPlatformTargets(options)) {
|
|
522
|
-
lines.push('', ` # Step ${stepNumber}`, ' - name: ๐ง Build supplemental Linux targets',
|
|
525
|
+
lines.push('', ` # Step ${stepNumber}`, ' - name: ๐ง Build supplemental Linux targets', " if: steps.version.outputs.mode != 'none'", ' run:', ` smoo github-ci nx-run-many --targets "${LINUX_PLATFORM_TARGET_GLOBS.join(',')}" --projects "${githubExpression('steps.version.outputs.projects')}" --collect-outputs "${githubExpression('runner.temp')}/linux-platform-outputs"`);
|
|
523
526
|
stepNumber += 1;
|
|
524
527
|
}
|
|
525
528
|
lines.push('');
|
|
526
529
|
}
|
|
527
|
-
lines.push(' # --- Candidate transfer --------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐ฆ Bundle validated release state', ' run:', ` mkdir -p "${githubExpression('runner.temp')}/publish-release-state" && git bundle create`, ` "${githubExpression('runner.temp')}/publish-release-state/release-state.bundle" HEAD --tags && git rev-parse HEAD >`, ` "${githubExpression('runner.temp')}/publish-release-state/release-head"`, '', ` # Step ${stepNumber++}`, ' - name: ๐ค Upload validated release state', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-state-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/publish-release-state`, ' if-no-files-found: error', ' retention-days: 1', '', ` # Step ${stepNumber++}`, ' - name: ๐ค Upload validated build outputs',
|
|
530
|
+
lines.push(' # --- Candidate transfer --------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐ฆ Bundle validated release state', ' run:', ` mkdir -p "${githubExpression('runner.temp')}/publish-release-state" && git bundle create`, ` "${githubExpression('runner.temp')}/publish-release-state/release-state.bundle" HEAD --tags && git rev-parse HEAD >`, ` "${githubExpression('runner.temp')}/publish-release-state/release-head"`, '', ` # Step ${stepNumber++}`, ' - name: ๐ค Upload validated release state', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-state-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/publish-release-state`, ' if-no-files-found: error', ' retention-days: 1', '', ` # Step ${stepNumber++}`, ' - name: ๐ค Upload validated build outputs', " if: steps.version.outputs.mode != 'none'", ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/release-build-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true');
|
|
528
531
|
if (hasLinuxPlatformTargets(options)) {
|
|
529
|
-
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ค Upload supplemental Linux outputs',
|
|
532
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ค Upload supplemental Linux outputs', " if: steps.version.outputs.mode != 'none'", ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-linux-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/linux-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true');
|
|
530
533
|
}
|
|
531
|
-
lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐งน Cleanup and cache Nix/devenv',
|
|
534
|
+
lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐งน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
|
|
532
535
|
return lines.join('\n').trimEnd();
|
|
533
536
|
}
|
|
534
537
|
function renderMacosPlatformSteps(options) {
|
|
@@ -554,7 +557,7 @@ function renderMacosPlatformSteps(options) {
|
|
|
554
557
|
if (isSmoothBricksCodebasePackageName(options.repoName)) {
|
|
555
558
|
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐๏ธ Build self-hosted smoo', ' # SmoothBricks self-hosts smoo from source for release commands.', ' run: nx build cli');
|
|
556
559
|
}
|
|
557
|
-
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ Build selected macOS and iOS release outputs', ' run:', ` smoo release build-platform-outputs --bump "${githubExpression('inputs.bump')}" --ref "${githubExpression('github.sha')}" --targets "${MACOS_PLATFORM_TARGET_GLOBS.join(',')}" --output`, ` "${githubExpression('runner.temp')}/macos-platform-outputs"`, '', ` # Step ${stepNumber++}`, ' - name: ๐ค Upload macOS platform outputs', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-macos-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/macos-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true', '', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐งน Cleanup and cache Nix/devenv',
|
|
560
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ Build selected macOS and iOS release outputs', ' run:', ` smoo release build-platform-outputs --bump "${githubExpression('inputs.bump')}" --ref "${githubExpression('github.sha')}" --targets "${MACOS_PLATFORM_TARGET_GLOBS.join(',')}" --output`, ` "${githubExpression('runner.temp')}/macos-platform-outputs"`, '', ` # Step ${stepNumber++}`, ' - name: ๐ค Upload macOS platform outputs', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-macos-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/macos-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true', '', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐งน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
|
|
558
561
|
return lines.join('\n').trimEnd();
|
|
559
562
|
}
|
|
560
563
|
function renderFinalLinuxPublishSteps(options) {
|
|
@@ -597,15 +600,15 @@ function renderFinalLinuxPublishSteps(options) {
|
|
|
597
600
|
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐๏ธ Build self-hosted smoo', ' # SmoothBricks self-hosts smoo from source for release commands.', ' run: nx build cli');
|
|
598
601
|
}
|
|
599
602
|
lines.push('', ' # --- Repair -------------------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐งฏ Repair pending releases', ' run:', ` smoo release repair-pending --ref "${githubExpression('github.sha')}" --platform-outputs "${githubExpression('runner.temp')}/publish-artifacts/publish-macos-outputs-${githubExpression('github.run_id')}/repairs" --dry-run`, ` "${githubExpression('inputs.dry_run')}"`, '', ` # Step ${stepNumber++}`, ' - name: โป๏ธ Restore validated release state', ' run:', ` git fetch "${githubExpression('runner.temp')}/publish-artifacts/publish-release-state-${githubExpression('github.run_id')}/release-state.bundle" HEAD --tags && git reset`, ` --hard "$(cat "${githubExpression('runner.temp')}/publish-artifacts/publish-release-state-${githubExpression('github.run_id')}/release-head")"`);
|
|
600
|
-
lines.push('', ' # --- Validation ---------------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐ฆ Apply verified Linux outputs', ` if: ${
|
|
603
|
+
lines.push('', ' # --- Validation ---------------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐ฆ Apply verified Linux outputs', ` if: ${mode} != 'none'`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('needs.linux-release-candidate.outputs.release-sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-release-outputs-${githubExpression('github.run_id')}"`);
|
|
601
604
|
if (hasLinuxPlatformTargets(options)) {
|
|
602
605
|
lines.push(` "${githubExpression('runner.temp')}/publish-artifacts/publish-linux-outputs-${githubExpression('github.run_id')}"`);
|
|
603
606
|
}
|
|
604
|
-
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ Apply verified macOS outputs', ` if: ${
|
|
607
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ Apply verified macOS outputs', ` if: ${mode} != 'none'`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('github.sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-macos-outputs-${githubExpression('github.run_id')}/current"`, '', ` # Step ${stepNumber++}`, ` - name: โ
Validate restored release (${githubExpression(mode)})`, ` if: ${mode} != 'none'`, ' run: smoo monorepo validate', '', ' # --- Release ------------------------------------------------------------', '', ` # Step ${stepNumber++}`, ` - name: ๐ฆ Publish release (${githubExpression(mode)})`, ' # smoo packs with Bun, then publishes tarballs with npm. Existing', ' # packages must already exist on npm and use trusted publishing/OIDC.', ' # Missing package names are bootstrapped locally before trust setup.', ` run: smoo release publish --bump "${githubExpression('inputs.bump')}" --dry-run "${githubExpression('inputs.dry_run')}"`);
|
|
605
608
|
if (options.deploy === true) {
|
|
606
609
|
lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ Deploy production', ' if:', " ${{ needs.linux-release-candidate.outputs.mode != 'none' && inputs.deploy_environment == 'production' &&", " inputs.dry_run != 'true' }}", ...deployEnvLines(options), ' run: smoo github-ci nx-deploy --configuration production --mode run-many --verify --name "Deploy Production"');
|
|
607
610
|
}
|
|
608
|
-
lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐งน Cleanup and cache Nix/devenv',
|
|
611
|
+
lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐งน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
|
|
609
612
|
return lines.join('\n').trimEnd();
|
|
610
613
|
}
|
|
611
614
|
function hasMacosPlatformTargets(options) {
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
NIX_STORE_NAR="${NIX_STORE_NAR:-/tmp/nix-store.nar}"
|
|
5
5
|
nix_store_cmd="/nix/var/nix/profiles/default/bin/nix-store"
|
|
6
|
+
DEVENV_FLAKE="${DEVENV_FLAKE:-github:cachix/devenv}"
|
|
7
|
+
# Host CI cache (GARM bind-mount). Prefer env from runner profile.
|
|
8
|
+
# Path comes from the runner (GARM profile). Ephemeral runners leave unset;
|
|
9
|
+
# devenv enterShell defaults to $PWD/.cache/ttsc.
|
|
10
|
+
TTSC_CACHE_DIR="${TTSC_CACHE_DIR:-}"
|
|
6
11
|
# Resolve from this script's location, not the caller's cwd. GitHub Actions
|
|
7
12
|
# runs this from tooling/direnv today, but direct cwd-changing helpers are easy
|
|
8
13
|
# to misuse and break on repeated calls.
|
|
@@ -36,12 +41,21 @@ restore_nix_store() {
|
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
install_devenv() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
# Shared host /nix/store is the package cache. Image may already provide
|
|
45
|
+
# devenv from github:cachix/devenv; otherwise profile-add the same flake
|
|
46
|
+
# (links store paths; re-fetch only when missing).
|
|
47
|
+
if command -v devenv >/dev/null 2>&1; then
|
|
48
|
+
echo "using existing devenv: $(command -v devenv) ($(devenv version 2>/dev/null || true))"
|
|
49
|
+
else
|
|
50
|
+
echo "nix profile add ${DEVENV_FLAKE}"
|
|
51
|
+
nix profile add --accept-flake-config "$DEVENV_FLAKE"
|
|
52
|
+
fi
|
|
53
|
+
if [ -d "$HOME/.nix-profile/bin" ]; then
|
|
54
|
+
echo "$HOME/.nix-profile/bin" >> "${GITHUB_PATH:-/dev/null}"
|
|
55
|
+
fi
|
|
56
|
+
if [ -n "$TTSC_CACHE_DIR" ]; then
|
|
57
|
+
mkdir -p "$TTSC_CACHE_DIR"
|
|
42
58
|
fi
|
|
43
|
-
echo "$HOME/.nix-profile/bin" >> "$GITHUB_PATH"
|
|
44
|
-
sudo ln -sf "$HOME/.nix-profile" /nix/var/nix/gcroots/ci/profile
|
|
45
59
|
}
|
|
46
60
|
|
|
47
61
|
build_devenv_shell() {
|
|
@@ -50,7 +64,10 @@ build_devenv_shell() {
|
|
|
50
64
|
# independent workflow step shells that run after this composite action.
|
|
51
65
|
if [ -n "${GITHUB_ENV:-}" ]; then
|
|
52
66
|
echo "TTSC_TSGO_BINARY=$repo_root/node_modules/@typescript/native/bin/tsc" >> "$GITHUB_ENV"
|
|
53
|
-
|
|
67
|
+
# Only re-export when the runner (or a prior step) already set the path.
|
|
68
|
+
if [ -n "$TTSC_CACHE_DIR" ]; then
|
|
69
|
+
echo "TTSC_CACHE_DIR=$TTSC_CACHE_DIR" >> "$GITHUB_ENV"
|
|
70
|
+
fi
|
|
54
71
|
fi
|
|
55
72
|
# Add repo-local tools only after the shell exists; cleanup steps use an
|
|
56
73
|
# explicit PATH because failures before this point must still refresh caches.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
name: Cache Nix profiles, devenv and direnv
|
|
2
|
-
description:
|
|
2
|
+
description: >
|
|
3
|
+
Two independent segments: large nix (NAR/profiles, ephemeral runners only) and small devenv (.devenv/.direnv โ eval
|
|
4
|
+
SQLite, shell scripts, profile; all runners).
|
|
3
5
|
|
|
4
6
|
inputs:
|
|
5
7
|
segment:
|
|
@@ -19,12 +21,11 @@ outputs:
|
|
|
19
21
|
runs:
|
|
20
22
|
using: composite
|
|
21
23
|
steps:
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
- name: Restore Nix profiles, devenv and direnv
|
|
24
|
+
# Large segment: Nix profile + exported store NAR. Ephemeral runners only.
|
|
25
|
+
# Key = shell closure inputs; direnv/setup script edits must not bust a multi-GB NAR.
|
|
26
|
+
- name: Restore Nix profiles and store NAR
|
|
26
27
|
id: restore-nix
|
|
27
|
-
if:
|
|
28
|
+
if: inputs.segment == 'nix' && inputs.mode == 'restore'
|
|
28
29
|
uses: actions/cache/restore@v5.0.5
|
|
29
30
|
with:
|
|
30
31
|
path: |
|
|
@@ -39,7 +40,7 @@ runs:
|
|
|
39
40
|
${{ runner.os }}-${{ runner.arch }}-nix-v3-
|
|
40
41
|
|
|
41
42
|
- name: Save Nix profiles and store NAR
|
|
42
|
-
if:
|
|
43
|
+
if: inputs.segment == 'nix' && inputs.mode == 'save'
|
|
43
44
|
uses: actions/cache/save@v5.0.5
|
|
44
45
|
with:
|
|
45
46
|
path: |
|
|
@@ -51,11 +52,12 @@ runs:
|
|
|
51
52
|
${{ runner.os }}-${{ runner.arch }}-nix-v3-${{ hashFiles('tooling/direnv/devenv.yaml',
|
|
52
53
|
'tooling/direnv/devenv.nix', 'tooling/direnv/devenv.lock') }}
|
|
53
54
|
|
|
54
|
-
#
|
|
55
|
-
#
|
|
55
|
+
# Small segment: devenv eval cache (nix-eval-cache.db), shell-*.sh, profile, .direnv.
|
|
56
|
+
# Own key. Setup restores on every runner; not gated on nix NAR hit. Devenv drops a
|
|
57
|
+
# shell cache row when drv/out are missing (GC) and re-evals/realizes.
|
|
56
58
|
- name: Restore devenv and direnv state
|
|
57
59
|
id: restore-devenv
|
|
58
|
-
if:
|
|
60
|
+
if: inputs.segment == 'devenv' && inputs.mode == 'restore'
|
|
59
61
|
uses: actions/cache/restore@v5.0.5
|
|
60
62
|
with:
|
|
61
63
|
path: |
|
|
@@ -69,7 +71,7 @@ runs:
|
|
|
69
71
|
${{ runner.os }}-${{ runner.arch }}-devenv-v3-
|
|
70
72
|
|
|
71
73
|
- name: Save devenv and direnv state
|
|
72
|
-
if:
|
|
74
|
+
if: inputs.segment == 'devenv' && inputs.mode == 'save'
|
|
73
75
|
uses: actions/cache/save@v5.0.5
|
|
74
76
|
with:
|
|
75
77
|
path: |
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
name: Save Nix/devenv caches
|
|
2
|
-
description:
|
|
2
|
+
description: >
|
|
3
|
+
Save cache segments after the job. Nix store NAR stays ephemeral-only (host uses shared /nix/store). Devenv/direnv
|
|
4
|
+
eval-cache segment saves on every runner when setup missed and build-shell produced nix-eval-cache.db.
|
|
3
5
|
|
|
4
6
|
inputs:
|
|
5
7
|
nix-cache-hit:
|
|
@@ -14,8 +16,19 @@ inputs:
|
|
|
14
16
|
runs:
|
|
15
17
|
using: composite
|
|
16
18
|
steps:
|
|
19
|
+
- name: ๐ Runner kind
|
|
20
|
+
id: runner-kind
|
|
21
|
+
shell: bash
|
|
22
|
+
run: |
|
|
23
|
+
if [ "${NIX_REMOTE:-}" = daemon ] && [ -d /var/cache/ci ]; then
|
|
24
|
+
echo "host=true" >> "$GITHUB_OUTPUT"
|
|
25
|
+
else
|
|
26
|
+
echo "host=false" >> "$GITHUB_OUTPUT"
|
|
27
|
+
fi
|
|
28
|
+
|
|
17
29
|
- name: ๐งน Prepare Nix/devenv cache save
|
|
18
30
|
id: cleanup-cache
|
|
31
|
+
if: steps.runner-kind.outputs.host != 'true'
|
|
19
32
|
shell: bash
|
|
20
33
|
working-directory: tooling/direnv
|
|
21
34
|
env:
|
|
@@ -33,14 +46,32 @@ runs:
|
|
|
33
46
|
smoo github-ci cleanup-cache
|
|
34
47
|
|
|
35
48
|
- name: ๐ง Save Nix profiles and store NAR
|
|
36
|
-
if:
|
|
49
|
+
if:
|
|
50
|
+
${{ steps.runner-kind.outputs.host != 'true' && steps.cleanup-cache.outputs.cache-ready == 'true' &&
|
|
51
|
+
inputs.nix-cache-hit != 'true' }}
|
|
37
52
|
uses: ./.github/actions/cache-nix-devenv
|
|
38
53
|
with:
|
|
39
54
|
segment: nix
|
|
40
55
|
mode: save
|
|
41
56
|
|
|
57
|
+
# Devenv segment is independent of nix NAR readiness and host vs ephemeral.
|
|
58
|
+
# Skip when setup never finished (no eval DB) so if: always() cannot poison
|
|
59
|
+
# the next restore with an empty/partial key.
|
|
60
|
+
- name: ๐ Devenv save ready
|
|
61
|
+
id: devenv-save
|
|
62
|
+
if: inputs.devenv-cache-hit != 'true'
|
|
63
|
+
shell: bash
|
|
64
|
+
run: |
|
|
65
|
+
db="${GITHUB_WORKSPACE}/tooling/direnv/.devenv/nix-eval-cache.db"
|
|
66
|
+
if [[ -f "$db" ]]; then
|
|
67
|
+
echo "ready=true" >> "$GITHUB_OUTPUT"
|
|
68
|
+
else
|
|
69
|
+
echo "ready=false" >> "$GITHUB_OUTPUT"
|
|
70
|
+
echo "skip devenv save: no nix-eval-cache.db"
|
|
71
|
+
fi
|
|
72
|
+
|
|
42
73
|
- name: ๐ง Save devenv and direnv
|
|
43
|
-
if: ${{
|
|
74
|
+
if: ${{ inputs.devenv-cache-hit != 'true' && steps.devenv-save.outputs.ready == 'true' }}
|
|
44
75
|
uses: ./.github/actions/cache-nix-devenv
|
|
45
76
|
with:
|
|
46
77
|
segment: devenv
|
|
@@ -1,44 +1,71 @@
|
|
|
1
1
|
name: Setup Nix/devenv
|
|
2
|
-
description:
|
|
2
|
+
description: >
|
|
3
|
+
Build the SmoothBricks devenv shell after checkout. Restores the small devenv/direnv actions/cache segment on every
|
|
4
|
+
runner (eval SQLite + shell scripts). On GARM/NixOS (NIX_REMOTE=daemon + /var/cache/ci) skips Nix install and the
|
|
5
|
+
large store NAR (host store). On ubuntu/macOS installs Nix and restores the NAR/profile cache.
|
|
3
6
|
|
|
4
7
|
outputs:
|
|
5
8
|
nix-cache-hit:
|
|
6
9
|
description: Whether the Nix profile/store cache restored from the exact primary key.
|
|
7
|
-
value: ${{ steps.nix-cache.outputs.cache-hit }}
|
|
10
|
+
value: ${{ steps.nix-cache.outputs.cache-hit || 'false' }}
|
|
8
11
|
devenv-cache-hit:
|
|
9
12
|
description: Whether the devenv/direnv cache restored from the exact primary key.
|
|
10
|
-
value: ${{ steps.devenv-cache.outputs.cache-hit }}
|
|
13
|
+
value: ${{ steps.devenv-cache.outputs.cache-hit || 'false' }}
|
|
14
|
+
host-runner:
|
|
15
|
+
description: Whether this job is on a host-nix runner (GARM) with shared store/caches.
|
|
16
|
+
value: ${{ steps.runner-kind.outputs.host }}
|
|
11
17
|
|
|
12
18
|
runs:
|
|
13
19
|
using: composite
|
|
14
20
|
steps:
|
|
15
21
|
# This action is intentionally post-checkout only. Repo-local actions do not
|
|
16
22
|
# exist before actions/checkout has populated the working tree.
|
|
23
|
+
|
|
24
|
+
# Runner image/profile owns paths (NIX_REMOTE, /var/cache/ci/*). Detect here
|
|
25
|
+
# so every workflow can `uses: setup-devenv` without forking step graphs.
|
|
26
|
+
- name: ๐ Runner kind
|
|
27
|
+
id: runner-kind
|
|
28
|
+
shell: bash
|
|
29
|
+
run: |
|
|
30
|
+
if [ "${NIX_REMOTE:-}" = daemon ] && [ -d /var/cache/ci ]; then
|
|
31
|
+
echo "host=true" >> "$GITHUB_OUTPUT"
|
|
32
|
+
echo "host-nix runner (shared store + /var/cache/ci)"
|
|
33
|
+
else
|
|
34
|
+
echo "host=false" >> "$GITHUB_OUTPUT"
|
|
35
|
+
echo "ephemeral runner (install Nix + GH caches)"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Devenv segment (own key): tooling/direnv/.devenv + .direnv โ includes
|
|
39
|
+
# nix-eval-cache.db. Independent of the nix NAR; restore on host and ephemeral
|
|
40
|
+
# whether or not the store cache hit. Missing store paths are fine: devenv
|
|
41
|
+
# verifies shell drv/out exist on eval-cache hit and invalidates + re-evals
|
|
42
|
+
# / realizes when GC removed them. Packages still come from host store, NAR,
|
|
43
|
+
# or Cachix โ this blob only skips evaluation.
|
|
44
|
+
- name: ๐ง Cache devenv and direnv
|
|
45
|
+
id: devenv-cache
|
|
46
|
+
uses: ./.github/actions/cache-nix-devenv
|
|
47
|
+
with:
|
|
48
|
+
segment: devenv
|
|
49
|
+
|
|
17
50
|
- name: โ๏ธ Install Nix
|
|
51
|
+
if: steps.runner-kind.outputs.host != 'true'
|
|
18
52
|
uses: DeterminateSystems/determinate-nix-action@v3
|
|
19
53
|
|
|
20
54
|
- name: ๐ง Cache Nix profiles and store NAR
|
|
21
55
|
id: nix-cache
|
|
56
|
+
if: steps.runner-kind.outputs.host != 'true'
|
|
22
57
|
uses: ./.github/actions/cache-nix-devenv
|
|
23
58
|
with:
|
|
24
59
|
segment: nix
|
|
25
60
|
|
|
26
61
|
- name: โป๏ธ Restore Nix store from NAR
|
|
62
|
+
if: steps.runner-kind.outputs.host != 'true'
|
|
27
63
|
shell: bash
|
|
28
64
|
working-directory: tooling/direnv
|
|
29
65
|
run: ./github-actions-bootstrap.sh restore-store
|
|
30
66
|
|
|
31
|
-
# Restore direnv state only when the Nix cache key is exact. Partial Nix
|
|
32
|
-
# restores can contain a NAR for a different shell closure, and .direnv
|
|
33
|
-
# points directly at derivations inside that closure.
|
|
34
|
-
- name: ๐ง Cache devenv and direnv
|
|
35
|
-
id: devenv-cache
|
|
36
|
-
if: ${{ steps.nix-cache.outputs.cache-hit == 'true' }}
|
|
37
|
-
uses: ./.github/actions/cache-nix-devenv
|
|
38
|
-
with:
|
|
39
|
-
segment: devenv
|
|
40
|
-
|
|
41
67
|
- name: โก Enable Cachix
|
|
68
|
+
if: steps.runner-kind.outputs.host != 'true'
|
|
42
69
|
uses: cachix/cachix-action@v17
|
|
43
70
|
with:
|
|
44
71
|
name: devenv
|
|
@@ -48,12 +75,14 @@ runs:
|
|
|
48
75
|
working-directory: tooling/direnv
|
|
49
76
|
run: ./github-actions-bootstrap.sh install-devenv
|
|
50
77
|
|
|
78
|
+
# node_modules + ttsc plugin binaries: GH Actions cache on ephemeral runners.
|
|
79
|
+
# Host runners keep those under the /var/cache/ci bind (bun / ttsc env).
|
|
51
80
|
- name: ๐ฆ Cache node_modules
|
|
81
|
+
if: steps.runner-kind.outputs.host != 'true'
|
|
52
82
|
uses: ./.github/actions/cache-node-modules
|
|
53
83
|
|
|
54
|
-
# Restores compiled ttsc native plugins into .cache/ttsc/plugins. TTSC_CACHE_DIR
|
|
55
|
-
# is set by devenv enterShell (+ bootstrap GITHUB_ENV for later steps).
|
|
56
84
|
- name: ๐ง Cache ttsc plugins
|
|
85
|
+
if: steps.runner-kind.outputs.host != 'true'
|
|
57
86
|
uses: ./.github/actions/cache-ttsc-plugins
|
|
58
87
|
|
|
59
88
|
- name: ๐ Build devenv shell
|
|
@@ -9,10 +9,17 @@
|
|
|
9
9
|
# change is upstream code that deserves a human look before it lands. Re-runs
|
|
10
10
|
# refresh the same branch in place.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
12
|
+
# REQUIRED SECRET: MANAGED_FILES_TOKEN
|
|
13
|
+
# Managed files include .github/workflows/*. The default GITHUB_TOKEN is
|
|
14
|
+
# server-side forbidden to create/update workflow files, even with
|
|
15
|
+
# contents:write. Configure a GitHub App installation token or classic/fine-
|
|
16
|
+
# grained PAT with:
|
|
17
|
+
# - contents: write
|
|
18
|
+
# - pull-requests: write
|
|
19
|
+
# - workflows: write
|
|
20
|
+
# as repository secret MANAGED_FILES_TOKEN. Without it, any update that
|
|
21
|
+
# touches workflow YAML fails at push (this is the usual "managed files
|
|
22
|
+
# workflow isn't doing anything" failure mode).
|
|
16
23
|
name: Managed files
|
|
17
24
|
|
|
18
25
|
on:
|
|
@@ -41,6 +48,7 @@ jobs:
|
|
|
41
48
|
filter: blob:none
|
|
42
49
|
fetch-depth: 0
|
|
43
50
|
persist-credentials: true
|
|
51
|
+
# Prefer MANAGED_FILES_TOKEN so push can update workflow files.
|
|
44
52
|
token: ${{ secrets.MANAGED_FILES_TOKEN || github.token }}
|
|
45
53
|
|
|
46
54
|
- name: ๐งฑ Setup Nix/devenv
|
|
@@ -53,27 +61,71 @@ jobs:
|
|
|
53
61
|
- name: ๐ค Push review branch and open PR
|
|
54
62
|
env:
|
|
55
63
|
GH_TOKEN: ${{ secrets.MANAGED_FILES_TOKEN || github.token }}
|
|
64
|
+
# secrets.* is empty when unset โ used to fail before a useless push.
|
|
65
|
+
MANAGED_FILES_TOKEN_CONFIGURED: ${{ secrets.MANAGED_FILES_TOKEN != '' }}
|
|
56
66
|
run: |
|
|
67
|
+
set -euo pipefail
|
|
57
68
|
cd "$(git rev-parse --show-toplevel)"
|
|
69
|
+
|
|
58
70
|
if [ -z "$(git status --porcelain)" ]; then
|
|
59
71
|
echo "Managed files are in sync; nothing to do."
|
|
60
72
|
exit 0
|
|
61
73
|
fi
|
|
74
|
+
|
|
75
|
+
echo "Pending managed-file changes:"
|
|
76
|
+
git status --porcelain
|
|
77
|
+
|
|
78
|
+
workflow_changes="$(git status --porcelain -- .github/workflows || true)"
|
|
79
|
+
if [ -n "$workflow_changes" ] && [ "${MANAGED_FILES_TOKEN_CONFIGURED}" != "true" ]; then
|
|
80
|
+
{
|
|
81
|
+
echo "::error title=MANAGED_FILES_TOKEN required::Managed update touches .github/workflows/* but repository secret MANAGED_FILES_TOKEN is not set."
|
|
82
|
+
echo ""
|
|
83
|
+
echo "GitHub refuses pushes that create/update workflow files when the credentials are the default GITHUB_TOKEN / a GitHub App without the workflows permission:"
|
|
84
|
+
echo " refusing to allow a GitHub App to create or update workflow ... without \`workflows\` permission"
|
|
85
|
+
echo ""
|
|
86
|
+
echo "Fix:"
|
|
87
|
+
echo " 1. Create a GitHub App (or PAT) with contents:write, pull-requests:write, workflows:write"
|
|
88
|
+
echo " 2. Install it on this repo"
|
|
89
|
+
echo " 3. Store an installation token or PAT as repository secret MANAGED_FILES_TOKEN"
|
|
90
|
+
echo " 4. Re-run this workflow"
|
|
91
|
+
echo ""
|
|
92
|
+
echo "Workflow files that would be updated:"
|
|
93
|
+
echo "$workflow_changes"
|
|
94
|
+
} >&2
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
|
|
62
98
|
git config user.name "github-actions[bot]"
|
|
63
99
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
64
100
|
git switch -C chore/managed-files
|
|
65
101
|
git add -A
|
|
66
102
|
git commit -m "chore: regenerate smoo-managed files"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
103
|
+
|
|
104
|
+
if ! git push --force origin chore/managed-files 2> /tmp/managed-files-push.err; then
|
|
105
|
+
cat /tmp/managed-files-push.err >&2
|
|
106
|
+
if grep -q 'workflows' /tmp/managed-files-push.err; then
|
|
107
|
+
{
|
|
108
|
+
echo ""
|
|
109
|
+
echo "::error title=workflows permission missing::Push rejected because the token cannot update GitHub Actions workflow files."
|
|
110
|
+
echo "Set repository secret MANAGED_FILES_TOKEN to a GitHub App/PAT with contents:write + pull-requests:write + workflows:write, then re-run."
|
|
111
|
+
} >&2
|
|
112
|
+
fi
|
|
113
|
+
exit 1
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
if ! gh pr view chore/managed-files --json number --jq .number >/dev/null 2>&1; then
|
|
117
|
+
gh pr create \
|
|
118
|
+
--head chore/managed-files \
|
|
119
|
+
--base "${GITHUB_REF_NAME}" \
|
|
120
|
+
--title "chore: regenerate smoo-managed files" \
|
|
121
|
+
--body "Automated refresh of smoo-managed files after drift (usually a \`@smoothbricks/cli\` pin bump). One persistent PR; re-runs force-push this branch in place. Review the template changes โ do NOT enable auto-merge."
|
|
122
|
+
else
|
|
123
|
+
echo "PR already open for chore/managed-files; branch refreshed in place."
|
|
124
|
+
fi
|
|
74
125
|
|
|
75
126
|
- name: ๐งน Cleanup and cache Nix/devenv
|
|
76
|
-
|
|
127
|
+
# success() is default; always() still saves GH Nix cache after a red job.
|
|
128
|
+
if: always()
|
|
77
129
|
uses: ./.github/actions/save-nix-devenv
|
|
78
130
|
with:
|
|
79
131
|
nix-cache-hit: ${{ steps.setup.outputs.nix-cache-hit }}
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -66,11 +66,11 @@ function buildProgram(): Command {
|
|
|
66
66
|
.option('--warn', 'report drift as warnings (GitHub annotations) instead of failing')
|
|
67
67
|
.action(async (options: { warn?: boolean }) => {
|
|
68
68
|
const { checkManagedFiles } = await import('./monorepo/index.js');
|
|
69
|
-
checkManagedFiles(await findRepoRoot(), { warn: options.warn });
|
|
69
|
+
await checkManagedFiles(await findRepoRoot(), { warn: options.warn });
|
|
70
70
|
});
|
|
71
71
|
monorepo.command('diff').action(async () => {
|
|
72
72
|
const { diffManagedFiles } = await import('./monorepo/index.js');
|
|
73
|
-
diffManagedFiles(await findRepoRoot());
|
|
73
|
+
await diffManagedFiles(await findRepoRoot());
|
|
74
74
|
});
|
|
75
75
|
monorepo
|
|
76
76
|
.command('validate-commit-msg <commitMsgFile>')
|
|
@@ -38,7 +38,7 @@ describe('GitHub CI Nx target expansion', () => {
|
|
|
38
38
|
['test', ['api', 'desktop']],
|
|
39
39
|
]);
|
|
40
40
|
expect(expanded.runs.map((run) => nxRunManyArgs(run))).toEqual([
|
|
41
|
-
['run-many', '-t', 'test', '--projects=api,desktop', '--parallel=
|
|
41
|
+
['run-many', '-t', 'test', '--projects=api,desktop', '--parallel=100%'],
|
|
42
42
|
]);
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -65,7 +65,7 @@ describe('GitHub CI Nx target expansion', () => {
|
|
|
65
65
|
|
|
66
66
|
expect(expanded.unmatchedGlobs).toEqual([]);
|
|
67
67
|
expect(expanded.runs.map((run) => nxRunManyArgs(run))).toEqual([
|
|
68
|
-
['run-many', '-t', 'missing', '--projects=api', '--parallel=
|
|
68
|
+
['run-many', '-t', 'missing', '--projects=api', '--parallel=100%'],
|
|
69
69
|
]);
|
|
70
70
|
});
|
|
71
71
|
|
|
@@ -114,7 +114,7 @@ describe('GitHub CI Nx target expansion', () => {
|
|
|
114
114
|
'-t',
|
|
115
115
|
'test',
|
|
116
116
|
'--exclude=tag:ci:skip:test',
|
|
117
|
-
'--parallel=
|
|
117
|
+
'--parallel=100%',
|
|
118
118
|
]);
|
|
119
119
|
expect(nxRunManyArgs({ target: 'test', projects: projects.slice(0, 1) })).not.toContain(
|
|
120
120
|
'--exclude=tag:ci:skip:test',
|
package/src/github-ci/index.ts
CHANGED
|
@@ -27,6 +27,9 @@ const parseNxProjectDeployConfigurations = typia.json.createIsParse<NxProjectDep
|
|
|
27
27
|
|
|
28
28
|
type NxSmartMode = 'auto' | 'affected' | 'run-many';
|
|
29
29
|
|
|
30
|
+
/** Nx workers = host cores (CI runners sized for full machine use). */
|
|
31
|
+
const NX_PARALLEL = '100%';
|
|
32
|
+
|
|
30
33
|
export async function cleanupGithubCiCache(root: string): Promise<void> {
|
|
31
34
|
const githubOutput = process.env.GITHUB_OUTPUT;
|
|
32
35
|
const markCacheReady = async (ready: boolean): Promise<void> => {
|
|
@@ -139,7 +142,7 @@ export function nxSmartArgs(target: string, mode: 'affected' | 'run-many', confi
|
|
|
139
142
|
if (configuration) {
|
|
140
143
|
args.push(`--configuration=${configuration}`);
|
|
141
144
|
}
|
|
142
|
-
args.push(`--exclude=tag:ci:skip:${target}`,
|
|
145
|
+
args.push(`--exclude=tag:ci:skip:${target}`, `--parallel=${NX_PARALLEL}`);
|
|
143
146
|
return args;
|
|
144
147
|
}
|
|
145
148
|
|
|
@@ -262,7 +265,7 @@ export function nxRunManyArgs(run: NxTargetRun, configuration?: string): string[
|
|
|
262
265
|
if (configuration) {
|
|
263
266
|
nxArgs.push(`--configuration=${configuration}`);
|
|
264
267
|
}
|
|
265
|
-
nxArgs.push(
|
|
268
|
+
nxArgs.push(`--parallel=${NX_PARALLEL}`);
|
|
266
269
|
return nxArgs;
|
|
267
270
|
}
|
|
268
271
|
|
|
@@ -343,7 +346,7 @@ export async function githubCiNxDeploy(
|
|
|
343
346
|
const projectList = projects.join(',');
|
|
344
347
|
const targets = options.verify === true ? ['build', 'lint', 'test', 'deploy'] : ['deploy'];
|
|
345
348
|
for (const target of targets) {
|
|
346
|
-
const nxArgs = ['run-many', '-t', target, `--projects=${projectList}`,
|
|
349
|
+
const nxArgs = ['run-many', '-t', target, `--projects=${projectList}`, `--parallel=${NX_PARALLEL}`];
|
|
347
350
|
if (target === 'deploy') {
|
|
348
351
|
nxArgs.push(`--configuration=${options.configuration}`);
|
|
349
352
|
}
|