@smoothbricks/cli 0.3.4 → 0.4.0

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 CHANGED
@@ -252,6 +252,8 @@ function buildProgram() {
252
252
  .requiredOption('--target <target>')
253
253
  .option('--name <name>')
254
254
  .option('--step <step>')
255
+ .option('--mode <mode>', 'auto, affected, or run-many', 'auto')
256
+ .option('--configuration <configuration>')
255
257
  .action(async (options) => {
256
258
  const { githubCiNxSmart } = await import('./github-ci/index.js');
257
259
  await githubCiNxSmart(await findRepoRoot(), options);
@@ -260,10 +262,22 @@ function buildProgram() {
260
262
  .command('nx-run-many')
261
263
  .requiredOption('--targets <targets>')
262
264
  .option('--projects <projects>')
265
+ .option('--configuration <configuration>')
263
266
  .action(async (options) => {
264
267
  const { githubCiNxRunMany } = await import('./github-ci/index.js');
265
268
  await githubCiNxRunMany(await findRepoRoot(), options);
266
269
  });
270
+ githubCi
271
+ .command('nx-deploy')
272
+ .requiredOption('--configuration <configuration>')
273
+ .option('--mode <mode>', 'auto, affected, or run-many', 'run-many')
274
+ .option('--name <name>')
275
+ .option('--step <step>')
276
+ .option('--verify', 'run build, lint, and test before deploy')
277
+ .action(async (options) => {
278
+ const { githubCiNxDeploy } = await import('./github-ci/index.js');
279
+ await githubCiNxDeploy(await findRepoRoot(), options);
280
+ });
267
281
  return program;
268
282
  }
269
283
  function booleanOption(value) {
@@ -1,11 +1,23 @@
1
+ type NxSmartMode = 'auto' | 'affected' | 'run-many';
1
2
  export declare function cleanupGithubCiCache(root: string): Promise<void>;
2
3
  export declare function githubCiNxSmart(root: string, options: {
3
4
  target: string;
4
5
  name?: string;
5
6
  step?: string;
7
+ mode?: NxSmartMode;
8
+ configuration?: string;
6
9
  }): Promise<void>;
7
10
  export declare function githubCiNxRunMany(root: string, options: {
8
11
  targets: string;
9
12
  projects?: string;
13
+ configuration?: string;
10
14
  }): Promise<void>;
15
+ export declare function githubCiNxDeploy(root: string, options: {
16
+ configuration: string;
17
+ mode?: NxSmartMode;
18
+ name?: string;
19
+ step?: string;
20
+ verify?: boolean;
21
+ }): Promise<void>;
22
+ export {};
11
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github-ci/index.ts"],"names":[],"mappings":"AAMA,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBtE;AAmFD,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github-ci/index.ts"],"names":[],"mappings":"AAMA,KAAK,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AAEpD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBtE;AAmFD,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACpG,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACtE,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GACrG,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
@@ -104,10 +104,12 @@ export async function githubCiNxSmart(root, options) {
104
104
  const name = options.name ?? options.target;
105
105
  const step = options.step ?? '';
106
106
  await createGithubStatus(name, step);
107
- const mode = process.env.GITHUB_EVENT_NAME === 'push' && process.env.GITHUB_REF_NAME === 'main' ? 'run-many' : 'affected';
108
- const nxArgs = mode === 'run-many'
109
- ? ['run-many', '-t', options.target, '--parallel=5']
110
- : ['affected', '-t', options.target, '--parallel=5'];
107
+ const mode = resolveNxSmartMode(options.mode ?? 'auto');
108
+ const nxArgs = mode === 'run-many' ? ['run-many', '-t', options.target] : ['affected', '-t', options.target];
109
+ if (options.configuration) {
110
+ nxArgs.push(`--configuration=${options.configuration}`);
111
+ }
112
+ nxArgs.push('--parallel=5');
111
113
  const status = await runStatus('nx', nxArgs, root);
112
114
  await updateGithubStatus(name, status === 0 ? 'success' : 'failure', step);
113
115
  if (status !== 0) {
@@ -119,8 +121,74 @@ export async function githubCiNxRunMany(root, options) {
119
121
  if (options.projects) {
120
122
  nxArgs.push(`--projects=${options.projects}`);
121
123
  }
124
+ if (options.configuration) {
125
+ nxArgs.push(`--configuration=${options.configuration}`);
126
+ }
122
127
  await run('nx', nxArgs, root);
123
128
  }
129
+ export async function githubCiNxDeploy(root, options) {
130
+ const name = options.name ?? `Deploy ${options.configuration}`;
131
+ const step = options.step ?? '';
132
+ await createGithubStatus(name, step);
133
+ const mode = resolveNxSmartMode(options.mode ?? 'run-many');
134
+ const projects = await deployProjectsWithConfiguration(root, options.configuration, mode);
135
+ if (projects.length === 0) {
136
+ console.log(`No ${mode} deploy projects with configuration ${options.configuration}; skipping.`);
137
+ await updateGithubStatus(name, 'success', step);
138
+ return;
139
+ }
140
+ const projectList = projects.join(',');
141
+ const targets = options.verify === true ? ['build', 'lint', 'test', 'deploy'] : ['deploy'];
142
+ for (const target of targets) {
143
+ const nxArgs = ['run-many', '-t', target, `--projects=${projectList}`, '--parallel=5'];
144
+ if (target === 'deploy') {
145
+ nxArgs.push(`--configuration=${options.configuration}`);
146
+ }
147
+ const status = await runStatus('nx', nxArgs, root);
148
+ if (status !== 0) {
149
+ await updateGithubStatus(name, 'failure', step);
150
+ throw new Error(`nx ${nxArgs.join(' ')} failed with exit code ${status}`);
151
+ }
152
+ }
153
+ await updateGithubStatus(name, 'success', step);
154
+ }
155
+ function resolveNxSmartMode(mode) {
156
+ if (mode === 'affected' || mode === 'run-many') {
157
+ return mode;
158
+ }
159
+ return process.env.GITHUB_EVENT_NAME === 'push' && process.env.GITHUB_REF_NAME === 'main' ? 'run-many' : 'affected';
160
+ }
161
+ async function deployProjectsWithConfiguration(root, configuration, mode) {
162
+ const listArgs = mode === 'affected'
163
+ ? ['show', 'projects', '--affected', '--withTarget', 'deploy', '--json']
164
+ : ['show', 'projects', '--withTarget', 'deploy', '--json'];
165
+ const result = await $ `nx ${listArgs}`.cwd(root).quiet();
166
+ const candidates = nxProjectList(decode(result.stdout));
167
+ const projects = [];
168
+ for (const project of candidates) {
169
+ if (await deployTargetHasConfiguration(root, project, configuration)) {
170
+ projects.push(project);
171
+ }
172
+ }
173
+ return projects.sort((a, b) => a.localeCompare(b));
174
+ }
175
+ async function deployTargetHasConfiguration(root, project, configuration) {
176
+ const result = await $ `nx show project ${project} --json`.cwd(root).quiet();
177
+ const parsed = JSON.parse(decode(result.stdout));
178
+ const targets = recordValue(parsed)?.targets;
179
+ const deploy = recordValue(targets)?.deploy;
180
+ const configurations = recordValue(deploy)?.configurations;
181
+ return recordValue(configurations)?.[configuration] !== undefined;
182
+ }
183
+ function nxProjectList(output) {
184
+ const parsed = JSON.parse(output);
185
+ return Array.isArray(parsed) ? parsed.filter((project) => typeof project === 'string') : [];
186
+ }
187
+ function recordValue(value) {
188
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
189
+ ? value
190
+ : undefined;
191
+ }
124
192
  async function createGithubStatus(name, step) {
125
193
  await postGithubStatus(name, 'pending', `Running ${name}...`, step);
126
194
  }
@@ -0,0 +1,26 @@
1
+ export declare enum CiWorkflowStepKind {
2
+ Checkout = "checkout",
3
+ SetupDevenv = "setup-devenv",
4
+ SetNxShas = "set-nx-shas",
5
+ RestoreNxCache = "restore-nx-cache",
6
+ Build = "build",
7
+ Lint = "lint",
8
+ UnitTests = "unit-tests",
9
+ Deploy = "deploy",
10
+ SaveNxCache = "save-nx-cache",
11
+ UploadTraceDbs = "upload-trace-dbs",
12
+ SaveNixDevenv = "save-nix-devenv"
13
+ }
14
+ export interface CiWorkflowStep {
15
+ kind: CiWorkflowStepKind;
16
+ name: string;
17
+ number: number;
18
+ }
19
+ export interface CiWorkflowDefinitionOptions {
20
+ deploy: boolean;
21
+ deployProvider?: 'cloudflare';
22
+ pushBranches: string[];
23
+ }
24
+ export declare function defineCiWorkflow(options: CiWorkflowDefinitionOptions): CiWorkflowStep[];
25
+ export declare function renderCiWorkflowYaml(options: CiWorkflowDefinitionOptions): string;
26
+ //# sourceMappingURL=ci-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/ci-workflow.ts"],"names":[],"mappings":"AAAA,oBAAY,kBAAkB;IAC5B,QAAQ,aAAa;IACrB,WAAW,iBAAiB;IAC5B,SAAS,gBAAgB;IACzB,cAAc,qBAAqB;IACnC,KAAK,UAAU;IACf,IAAI,SAAS;IACb,SAAS,eAAe;IACxB,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,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,EAAE,CAmBvF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,MAAM,CAGjF"}
@@ -0,0 +1,201 @@
1
+ export var CiWorkflowStepKind;
2
+ (function (CiWorkflowStepKind) {
3
+ CiWorkflowStepKind["Checkout"] = "checkout";
4
+ CiWorkflowStepKind["SetupDevenv"] = "setup-devenv";
5
+ CiWorkflowStepKind["SetNxShas"] = "set-nx-shas";
6
+ CiWorkflowStepKind["RestoreNxCache"] = "restore-nx-cache";
7
+ CiWorkflowStepKind["Build"] = "build";
8
+ CiWorkflowStepKind["Lint"] = "lint";
9
+ CiWorkflowStepKind["UnitTests"] = "unit-tests";
10
+ CiWorkflowStepKind["Deploy"] = "deploy";
11
+ CiWorkflowStepKind["SaveNxCache"] = "save-nx-cache";
12
+ CiWorkflowStepKind["UploadTraceDbs"] = "upload-trace-dbs";
13
+ CiWorkflowStepKind["SaveNixDevenv"] = "save-nix-devenv";
14
+ })(CiWorkflowStepKind || (CiWorkflowStepKind = {}));
15
+ export function defineCiWorkflow(options) {
16
+ const steps = [
17
+ { kind: CiWorkflowStepKind.Checkout, name: '📥 Checkout' },
18
+ { kind: CiWorkflowStepKind.SetupDevenv, name: '🧱 Setup Nix/devenv' },
19
+ { kind: CiWorkflowStepKind.SetNxShas, name: '🧭 Set Nx SHAs' },
20
+ { kind: CiWorkflowStepKind.RestoreNxCache, name: '🧠 Restore Nx cache' },
21
+ { kind: CiWorkflowStepKind.Build, name: '🔨 Build' },
22
+ { kind: CiWorkflowStepKind.Lint, name: '🔍 Lint' },
23
+ { kind: CiWorkflowStepKind.UnitTests, name: '🧪 Unit Tests' },
24
+ ];
25
+ if (options.deploy) {
26
+ steps.push({ kind: CiWorkflowStepKind.Deploy, name: '🚀 Deploy Staging' });
27
+ }
28
+ steps.push({ kind: CiWorkflowStepKind.SaveNxCache, name: '💾 Save Nx cache' }, { kind: CiWorkflowStepKind.UploadTraceDbs, name: '📎 Upload trace DBs' }, { kind: CiWorkflowStepKind.SaveNixDevenv, name: '🧹 Cleanup and cache Nix/devenv' });
29
+ return steps.map((step, index) => ({ ...step, number: index + 2 }));
30
+ }
31
+ export function renderCiWorkflowYaml(options) {
32
+ const steps = defineCiWorkflow(options);
33
+ return `${renderCiWorkflowHeader(options)}${renderCiWorkflowSteps(steps, options)}`;
34
+ }
35
+ function renderCiWorkflowHeader(options) {
36
+ return `name: CI
37
+
38
+ on:
39
+ push:
40
+ branches:
41
+ ${renderYamlList(options.pushBranches, 6)}
42
+ pull_request:
43
+
44
+ permissions:
45
+ actions: read
46
+ contents: read
47
+ statuses: write
48
+
49
+ defaults:
50
+ run:
51
+ working-directory: tooling/direnv
52
+
53
+ jobs:
54
+ main:
55
+ name: Validate
56
+ runs-on: ubuntu-latest
57
+ timeout-minutes: 45
58
+ env:
59
+ NIX_STORE_NAR: ${githubExpression('github.workspace')}/nix-store.nar
60
+ GH_TOKEN: ${githubExpression('github.token')}
61
+ steps:
62
+ `;
63
+ }
64
+ function githubExpression(expression) {
65
+ return `$${`{{ ${expression} }}`}`;
66
+ }
67
+ function renderCiWorkflowSteps(steps, options) {
68
+ const lines = [];
69
+ for (const step of steps) {
70
+ lines.push(...sectionLinesBefore(step));
71
+ lines.push(...commentLinesForStep(step));
72
+ lines.push(...yamlLinesForStep(step, options));
73
+ lines.push('');
74
+ }
75
+ return `${lines.join('\n').trimEnd()}\n`;
76
+ }
77
+ function sectionLinesBefore(step) {
78
+ if (step.kind === CiWorkflowStepKind.SetNxShas) {
79
+ return [' # --- Nx -----------------------------------------------------------------', ''];
80
+ }
81
+ if (step.kind === CiWorkflowStepKind.SaveNixDevenv) {
82
+ return [' # --- Cleanup ------------------------------------------------------------', ''];
83
+ }
84
+ return [];
85
+ }
86
+ function commentLinesForStep(step) {
87
+ if (step.kind === CiWorkflowStepKind.Checkout) {
88
+ return [' # Step 1: GitHub adds "Set up job" automatically', ' # Step 2'];
89
+ }
90
+ if (step.kind === CiWorkflowStepKind.SetupDevenv) {
91
+ return [
92
+ ' # Step 3. Composite action internals do not affect top-level job step',
93
+ ' # anchors; update the nx-smart --step values below if top-level steps move.',
94
+ ];
95
+ }
96
+ if (step.kind === CiWorkflowStepKind.SetNxShas) {
97
+ return [` # Step ${step.number}`, ' # Sets the base and head SHAs required for the nx affected commands'];
98
+ }
99
+ if (step.kind === CiWorkflowStepKind.SaveNxCache) {
100
+ return [
101
+ ` # Step ${step.number}`,
102
+ " # Nx's database cache needs artifact files and .nx/workspace-data DB",
103
+ ' # metadata restored together; GitHub Actions cache is only the archive',
104
+ ' # transport. Save runs only after prior required steps succeed on the default',
105
+ ' # branch, so PRs may restore shared cache but cannot publish it.',
106
+ ];
107
+ }
108
+ return [` # Step ${step.number}`];
109
+ }
110
+ function yamlLinesForStep(step, options) {
111
+ switch (step.kind) {
112
+ case CiWorkflowStepKind.Checkout:
113
+ return [
114
+ ` - name: ${step.name}`,
115
+ ' uses: actions/checkout@v6.0.2',
116
+ ' with:',
117
+ ' filter: blob:none',
118
+ ' fetch-depth: 0',
119
+ ];
120
+ case CiWorkflowStepKind.SetupDevenv:
121
+ return [` - name: ${step.name}`, ' id: setup', ' uses: ./.github/actions/setup-devenv'];
122
+ case CiWorkflowStepKind.SetNxShas:
123
+ return [
124
+ ` - name: ${step.name}`,
125
+ ' uses: nrwl/nx-set-shas@v5.0.1',
126
+ ' with:',
127
+ ' workflow-id: ci.yml',
128
+ ];
129
+ case CiWorkflowStepKind.RestoreNxCache:
130
+ return [` - name: ${step.name}`, ' id: nx-cache', ' uses: ./.github/actions/cache-nx'];
131
+ case CiWorkflowStepKind.Build:
132
+ return nxSmartStep(step, 'build', 'Build');
133
+ case CiWorkflowStepKind.Lint:
134
+ return nxSmartStep(step, 'lint', 'Lint');
135
+ case CiWorkflowStepKind.UnitTests:
136
+ return nxSmartStep(step, 'test', 'Unit Tests');
137
+ case CiWorkflowStepKind.Deploy:
138
+ return [
139
+ ` - name: ${step.name}`,
140
+ ' if:',
141
+ " ${{ github.event_name == 'push' && github.ref == format('refs/heads/{0}',",
142
+ ' github.event.repository.default_branch) }}',
143
+ ...deployEnvLines(options),
144
+ ` run: smoo github-ci nx-deploy --configuration staging --mode affected --name "Deploy Staging" --step ${step.number}`,
145
+ ];
146
+ case CiWorkflowStepKind.SaveNxCache:
147
+ return [
148
+ ` - name: ${step.name}`,
149
+ ' if:',
150
+ " ${{ github.event_name == 'push' && github.ref == format('refs/heads/{0}',",
151
+ " github.event.repository.default_branch) && steps.nx-cache.outputs.cache-hit != 'true' }}",
152
+ ' uses: actions/cache/save@v5.0.5',
153
+ ' with:',
154
+ ' path: |',
155
+ ' .nx/cache',
156
+ ' .nx/workspace-data/*.db*',
157
+ ' key: ${{ runner.os }}-nx-db-v1-${{ github.sha }}',
158
+ ];
159
+ case CiWorkflowStepKind.UploadTraceDbs:
160
+ return [
161
+ ` - name: ${step.name}`,
162
+ ' if: ${{ always() }}',
163
+ ' uses: actions/upload-artifact@v7.0.1',
164
+ ' with:',
165
+ ' name: trace-results-${{ github.run_id }}',
166
+ ' path: packages/*/.trace-results.db',
167
+ ' if-no-files-found: ignore',
168
+ ' retention-days: 14',
169
+ ' include-hidden-files: true',
170
+ ];
171
+ case CiWorkflowStepKind.SaveNixDevenv:
172
+ return [
173
+ ` - name: ${step.name}`,
174
+ ' if: ${{ always() }}',
175
+ ' uses: ./.github/actions/save-nix-devenv',
176
+ ' with:',
177
+ ' nix-cache-hit: ${{ steps.setup.outputs.nix-cache-hit }}',
178
+ ' devenv-cache-hit: ${{ steps.setup.outputs.devenv-cache-hit }}',
179
+ ];
180
+ }
181
+ }
182
+ function deployEnvLines(options) {
183
+ if (options.deployProvider !== 'cloudflare') {
184
+ return [];
185
+ }
186
+ return [
187
+ ' env:',
188
+ ' CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}',
189
+ ' CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}',
190
+ ];
191
+ }
192
+ function nxSmartStep(step, target, name) {
193
+ return [
194
+ ` - name: ${step.name}`,
195
+ ` run: smoo github-ci nx-smart --target ${target} --name "${name}" --step ${step.number}`,
196
+ ];
197
+ }
198
+ function renderYamlList(values, spaces) {
199
+ const indent = ' '.repeat(spaces);
200
+ return values.map((value) => `${indent}- ${value}`).join('\n');
201
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"AAgBA,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;AA8ED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,EAAE,CAG/F;AA0ED,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAIxD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQzD"}
1
+ {"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"AAkBA,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;AAwFD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,EAAE,CAG/F;AA4KD,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAIxD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQzD"}
@@ -1,7 +1,9 @@
1
+ import { execFileSync } from 'node:child_process';
1
2
  import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
3
  import { dirname, join, resolve } from 'node:path';
3
4
  import { fileURLToPath } from 'node:url';
4
5
  import { listReleasePackages, readPackageJson } from '../lib/workspace.js';
6
+ import { renderCiWorkflowYaml } from './ci-workflow.js';
5
7
  import { renderPublishWorkflowYaml } from './publish-workflow.js';
6
8
  const managedFiles = [
7
9
  {
@@ -34,8 +36,8 @@ const managedFiles = [
34
36
  target: '.git-format-staged.yml',
35
37
  },
36
38
  {
37
- kind: 'template',
38
- source: 'github/workflows/ci.yml',
39
+ kind: 'generated',
40
+ source: 'ci-workflow',
39
41
  target: '.github/workflows/ci.yml',
40
42
  },
41
43
  {
@@ -76,7 +78,7 @@ export function applyManagedFiles(root, mode) {
76
78
  return managedFiles.map((file) => applyManagedFile(root, file, mode, context));
77
79
  }
78
80
  function applyManagedFile(root, file, mode, context) {
79
- if (file.releasePackagesOnly === true && !context.hasReleasePackages) {
81
+ if (file.releasePackagesOnly === true && !context.hasReleasePackages && !context.hasProductionDeployTargets) {
80
82
  return { target: file.target, action: 'skipped' };
81
83
  }
82
84
  const target = resolve(root, file.target);
@@ -107,8 +109,19 @@ function applyManagedFile(root, file, mode, context) {
107
109
  }
108
110
  function getManagedContent(file, context) {
109
111
  if (file.kind === 'generated') {
112
+ if (file.source === 'ci-workflow') {
113
+ return renderCiWorkflowYaml({
114
+ deploy: context.hasStagingDeployTargets,
115
+ deployProvider: context.stagingDeployProvider,
116
+ pushBranches: context.ciPushBranches,
117
+ });
118
+ }
110
119
  if (file.source === 'publish-workflow') {
111
- return renderPublishWorkflowYaml({ repoName: context.repoName });
120
+ return renderPublishWorkflowYaml({
121
+ deploy: context.hasProductionDeployTargets,
122
+ deployProvider: context.productionDeployProvider,
123
+ repoName: context.repoName,
124
+ });
112
125
  }
113
126
  throw new Error(`Unknown generated managed file source ${file.source}`);
114
127
  }
@@ -123,16 +136,95 @@ function getManagedContent(file, context) {
123
136
  function getManagedFileContext(root) {
124
137
  const packageJson = readPackageJson(join(root, 'package.json'));
125
138
  const repoName = packageJson?.name ?? 'monorepo';
139
+ const ciPushBranches = getCiPushBranches(packageJson?.json);
140
+ const stagingDeploy = getDeployTargetInfo(root, 'staging');
141
+ const productionDeploy = getDeployTargetInfo(root, 'production');
126
142
  const nodeModulesCacheKey = existsSync(join(root, 'bun.lock'))
127
143
  ? `$${"{{ hashFiles('bun.lock', 'package.json', 'packages/*/package.json') }}"}`
128
144
  : `$${"{{ hashFiles('bun.lockb', 'package.json', 'packages/*/package.json') }}"}`;
129
- return { hasReleasePackages: listReleasePackages(root, packageJson).length > 0, nodeModulesCacheKey, repoName };
145
+ return {
146
+ hasReleasePackages: listReleasePackages(root, packageJson).length > 0,
147
+ hasStagingDeployTargets: stagingDeploy.exists,
148
+ hasProductionDeployTargets: productionDeploy.exists,
149
+ stagingDeployProvider: stagingDeploy.provider,
150
+ productionDeployProvider: productionDeploy.provider,
151
+ ciPushBranches,
152
+ nodeModulesCacheKey,
153
+ repoName,
154
+ };
130
155
  }
131
156
  function renderTemplate(context, template) {
132
157
  return template
133
158
  .replaceAll('{{REPO_NAME}}', context.repoName)
159
+ .replaceAll('__SMOO_CI_PUSH_BRANCHES__', renderYamlFlowList(context.ciPushBranches))
134
160
  .replaceAll('{{NODE_MODULES_CACHE_KEY}}', context.nodeModulesCacheKey);
135
161
  }
162
+ function getDeployTargetInfo(root, configuration) {
163
+ const output = execFileSync('nx', ['show', 'projects', '--withTarget', 'deploy', '--json'], {
164
+ cwd: root,
165
+ encoding: 'utf8',
166
+ stdio: ['ignore', 'pipe', 'inherit'],
167
+ });
168
+ const projects = JSON.parse(output);
169
+ if (!Array.isArray(projects) || !projects.every((project) => typeof project === 'string')) {
170
+ return { exists: false };
171
+ }
172
+ let exists = false;
173
+ let provider;
174
+ for (const project of projects) {
175
+ const target = nxDeployTarget(root, project, configuration);
176
+ if (!target.exists) {
177
+ continue;
178
+ }
179
+ exists = true;
180
+ provider ??= target.provider;
181
+ }
182
+ return { exists, provider };
183
+ }
184
+ function nxDeployTarget(root, project, configuration) {
185
+ const output = execFileSync('nx', ['show', 'project', project, '--json'], {
186
+ cwd: root,
187
+ encoding: 'utf8',
188
+ stdio: ['ignore', 'pipe', 'inherit'],
189
+ });
190
+ const parsed = JSON.parse(output);
191
+ const projectJson = recordValue(parsed);
192
+ const targets = recordValue(projectJson?.targets);
193
+ const deploy = recordValue(targets?.deploy);
194
+ const configurations = recordValue(deploy?.configurations);
195
+ const config = recordValue(configurations?.[configuration]);
196
+ if (!config) {
197
+ return { exists: false };
198
+ }
199
+ const command = deployCommand(deploy, config);
200
+ return { exists: true, provider: command.includes('wrangler ') ? 'cloudflare' : undefined };
201
+ }
202
+ function deployCommand(deploy, config) {
203
+ const command = stringValue(config.command) ?? stringValue(recordValue(config.options)?.command);
204
+ return command ?? stringValue(recordValue(deploy?.options)?.command) ?? '';
205
+ }
206
+ function stringValue(value) {
207
+ return typeof value === 'string' ? value : undefined;
208
+ }
209
+ function getCiPushBranches(packageJson) {
210
+ const configured = readCiPushBranches(packageJson);
211
+ return configured.length > 0 ? configured : ['main'];
212
+ }
213
+ function readCiPushBranches(packageJson) {
214
+ const rootPackage = recordValue(packageJson);
215
+ const smoo = recordValue(rootPackage?.smoo);
216
+ const github = recordValue(smoo?.github);
217
+ const branches = Array.isArray(github?.pushBranches) ? github.pushBranches : [];
218
+ return branches.filter((branch) => typeof branch === 'string' && branch.length > 0);
219
+ }
220
+ function recordValue(value) {
221
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
222
+ ? value
223
+ : undefined;
224
+ }
225
+ function renderYamlFlowList(values) {
226
+ return JSON.stringify(values);
227
+ }
136
228
  function writeManagedFile(path, content, executable) {
137
229
  mkdirSync(dirname(path), { recursive: true });
138
230
  writeFileSync(path, content, { mode: executable ? 0o755 : 0o644 });
@@ -1 +1 @@
1
- {"version":3,"file":"package-policy.d.ts","sourceRoot":"","sources":["../../src/monorepo/package-policy.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAGL,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,+CAA+C,CAAC;AA6BvD,YAAY,EAAE,0BAA0B,IAAI,iCAAiC,EAAE,sBAAsB,EAAE,CAAC;AACxG,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,CAAC;AAUhE,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuB1D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMxD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuC7D;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,IAAI,CAwB7G;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoB7D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAezD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsC9D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyB3D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcvD;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0DlE;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,MAAM,CAiC5G"}
1
+ {"version":3,"file":"package-policy.d.ts","sourceRoot":"","sources":["../../src/monorepo/package-policy.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAGL,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,+CAA+C,CAAC;AA6BvD,YAAY,EAAE,0BAA0B,IAAI,iCAAiC,EAAE,sBAAsB,EAAE,CAAC;AACxG,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,CAAC;AAYhE,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuB1D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMxD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuC7D;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,IAAI,CAwB7G;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoB7D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAezD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsC9D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyB3D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcvD;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0DlE;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,MAAM,CAiC5G"}
@@ -9,10 +9,12 @@ import { getWorkspacePackageManifests, getWorkspacePackages, listPackageJsonReco
9
9
  export { SMOO_NX_RELEASE_TAG_PATTERN, SMOO_NX_VERSION_ACTIONS };
10
10
  const extraCommitScopes = ['release'];
11
11
  const rootScriptPolicy = {
12
+ clean: 'nx run-many -t clean; nx reset',
13
+ 'clean:node_modules': 'rm -rf node_modules && find e* t* p* -type d -name node_modules -print0 | xargs -0 rm -rvf',
14
+ 'format:changed': 'git-format-staged --config tooling/git-hooks/git-format-staged.yml --also-unstaged',
15
+ 'format:staged': 'git-format-staged --config tooling/git-hooks/git-format-staged.yml',
12
16
  lint: 'nx run-many -t lint',
13
17
  'lint:fix': 'git-format-staged --config tooling/git-hooks/git-format-staged.yml --unstaged',
14
- 'format:staged': 'git-format-staged --config tooling/git-hooks/git-format-staged.yml',
15
- 'format:changed': 'git-format-staged --config tooling/git-hooks/git-format-staged.yml --also-unstaged',
16
18
  };
17
19
  export function applyFixableMonorepoDefaults(root) {
18
20
  applyRootScriptDefaults(root);
@@ -1,6 +1,7 @@
1
1
  export type PublishWorkflowBump = 'auto' | 'patch' | 'minor' | 'major' | 'prerelease';
2
- export type PublishWorkflowCondition = 'version-mode-not-none' | 'failure' | 'always';
2
+ export type PublishWorkflowCondition = 'version-mode-not-none' | 'deploy-production' | 'failure' | 'always';
3
3
  export type PublishWorkflowNxTarget = 'build' | 'lint' | 'test';
4
+ export type PublishWorkflowDeployEnvironment = 'none' | 'production';
4
5
  export declare enum PublishWorkflowStepKind {
5
6
  Checkout = "checkout",
6
7
  SetupDevenv = "setup-devenv",
@@ -15,6 +16,7 @@ export declare enum PublishWorkflowStepKind {
15
16
  UploadTraceDbs = "upload-trace-dbs",
16
17
  ValidateMonorepoConfig = "validate-monorepo-config",
17
18
  PublishRelease = "publish-release",
19
+ DeployProduction = "deploy-production",
18
20
  SaveNixDevenv = "save-nix-devenv"
19
21
  }
20
22
  export interface PublishWorkflowStep {
@@ -29,10 +31,13 @@ export interface PublishWorkflowDefinition {
29
31
  steps: PublishWorkflowStep[];
30
32
  }
31
33
  export interface PublishWorkflowDefinitionOptions {
34
+ deploy?: boolean;
35
+ deployProvider?: 'cloudflare';
32
36
  repoName?: string;
33
37
  }
34
38
  export interface PublishWorkflowInputs {
35
39
  bump: PublishWorkflowBump;
40
+ deployEnvironment: PublishWorkflowDeployEnvironment;
36
41
  dryRun: boolean;
37
42
  }
38
43
  export interface PublishWorkflowVersionOutputs {
@@ -66,6 +71,7 @@ export interface PublishWorkflowCallbacks {
66
71
  bump: PublishWorkflowBump;
67
72
  dryRun: boolean;
68
73
  }): Promise<void>;
74
+ deployProduction(): Promise<void>;
69
75
  saveNixDevenv(input: PublishWorkflowSetupOutputs): Promise<void>;
70
76
  }
71
77
  export interface PublishWorkflowRunContext {
@@ -1 +1 @@
1
- {"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,CAAC;AACtF,MAAM,MAAM,wBAAwB,GAAG,uBAAuB,GAAG,SAAS,GAAG,QAAQ,CAAC;AACtF,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhE,oBAAY,uBAAuB;IACjC,QAAQ,aAAa;IACrB,WAAW,iBAAiB;IAC5B,sBAAsB,6BAA6B;IACnD,kBAAkB,0BAA0B;IAC5C,qBAAqB,4BAA4B;IACjD,cAAc,oBAAoB;IAClC,yBAAyB,iCAAiC;IAC1D,KAAK,UAAU;IACf,IAAI,SAAS;IACb,SAAS,eAAe;IACxB,cAAc,qBAAqB;IACnC,sBAAsB,6BAA6B;IACnD,cAAc,oBAAoB;IAClC,aAAa,oBAAoB;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,wBAAwB,CAAC;IACrC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;CACpC;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,WAAW,IAAI,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACpD,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,qBAAqB,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,cAAc,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,mBAAmB,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;IAC9G,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,SAAS,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,uBAAuB,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzF,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,cAAc,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,mBAAmB,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF,aAAa,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,SAAS,EAAE,wBAAwB,CAAC;CACrC;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,6BAA6B,CAAC;IACvC,MAAM,EAAE,OAAO,CAAC;CACjB;AAID,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,gCAAqC,GAAG,yBAAyB,CA0D/G;AAMD,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,yBAAyB,EACnC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CAmEnC;AAYD,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,gCAAqC,GAAG,MAAM,CAGhG"}
1
+ {"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"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"}