@smoothbricks/cli 0.10.13 → 0.10.15

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
@@ -286,6 +286,7 @@ function buildProgram() {
286
286
  .option('--mode <mode>', 'auto, affected, or run-many', 'auto')
287
287
  .option('--configuration <configuration>')
288
288
  .option('--stage <stage>')
289
+ .option('--stream-output', 'stream Nx task output without prefixes')
289
290
  .action(async (options) => {
290
291
  const { githubCiNxSmart } = await import('./github-ci/index.js');
291
292
  await githubCiNxSmart(await findRepoRoot(), options);
@@ -18,7 +18,7 @@ export interface GithubActionsEventPayload {
18
18
  }
19
19
  type NxSmartMode = 'auto' | 'affected' | 'run-many';
20
20
  export declare function cleanupGithubCiCache(root: string): Promise<void>;
21
- export declare function nxSmartArgs(target: string, mode: 'affected' | 'run-many', configuration?: string, stage?: string): string[];
21
+ export declare function nxSmartArgs(target: string, mode: 'affected' | 'run-many', configuration?: string, stage?: string, streamOutput?: boolean): string[];
22
22
  export declare function githubCiNxSmart(root: string, options: {
23
23
  target: string;
24
24
  name?: string;
@@ -26,6 +26,7 @@ export declare function githubCiNxSmart(root: string, options: {
26
26
  mode?: NxSmartMode;
27
27
  configuration?: string;
28
28
  stage?: string;
29
+ streamOutput?: boolean;
29
30
  }): Promise<void>;
30
31
  export interface NxRunManyOptions {
31
32
  targets: string;
@@ -53,7 +54,7 @@ export interface GithubCiNxDeployOptions {
53
54
  verify?: boolean;
54
55
  }
55
56
  export interface GithubCiNxDeployDependencies {
56
- listProjects?: (root: string, target: string, mode: 'affected' | 'run-many') => Promise<string[]>;
57
+ listProjects?: (root: string, target: string, mode: 'affected' | 'run-many', stage: DeploymentStage) => Promise<string[]>;
57
58
  runNx?: (args: string[], root: string) => Promise<number>;
58
59
  appendSummary?: (summaryPath: string, content: string) => Promise<void>;
59
60
  appendOutput?: (outputPath: string, content: string) => Promise<void>;
@@ -64,7 +65,7 @@ export interface GithubCiNxDeployDependencies {
64
65
  }
65
66
  export declare function githubCiNxDeploy(root: string, options: GithubCiNxDeployOptions, dependencies?: GithubCiNxDeployDependencies): Promise<void>;
66
67
  export declare function resolveDeploymentStage(explicit: string | undefined, environment: NodeJS.ProcessEnv, event: GithubActionsEventPayload | undefined): DeploymentStage;
67
- export declare function selectStageDeployProjects(candidates: string[], loadProject: (project: string) => Promise<unknown>): Promise<string[]>;
68
+ export declare function selectStageDeployProjects(candidates: string[], stage: DeploymentStage, loadProject: (project: string) => Promise<unknown>): Promise<string[]>;
68
69
  export interface GithubApiProcessResult {
69
70
  exitCode: number;
70
71
  stdout: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github-ci/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github-ci/index.ts"],"names":[],"mappings":"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"}
@@ -24,7 +24,7 @@ const isGithubDeployment = (() => {
24
24
  })();
25
25
  const isNxProjectDeployTarget = (() => {
26
26
  const _ip0 = input => true;
27
- const _io0 = input => undefined === input.targets || "object" === typeof input.targets && null !== input.targets && false === Array.isArray(input.targets) && _io1(input.targets);
27
+ const _io0 = input => true && (undefined === input.targets || "object" === typeof input.targets && null !== input.targets && false === Array.isArray(input.targets) && _io1(input.targets));
28
28
  const _io1 = input => undefined === input.deploy || "object" === typeof input.deploy && null !== input.deploy && false === Array.isArray(input.deploy) && _io2(input.deploy);
29
29
  const _io2 = input => _ip0(input) && (undefined === input.options || "object" === typeof input.options && null !== input.options && false === Array.isArray(input.options) && _io3(input.options));
30
30
  const _io3 = input => _ip0(input);
@@ -32,7 +32,7 @@ const isNxProjectDeployTarget = (() => {
32
32
  })();
33
33
  const parseNxProjectDeployTarget = (() => {
34
34
  const _ip0 = input => true;
35
- const _io0 = input => undefined === input.targets || "object" === typeof input.targets && null !== input.targets && false === Array.isArray(input.targets) && _io1(input.targets);
35
+ const _io0 = input => true && (undefined === input.targets || "object" === typeof input.targets && null !== input.targets && false === Array.isArray(input.targets) && _io1(input.targets));
36
36
  const _io1 = input => undefined === input.deploy || "object" === typeof input.deploy && null !== input.deploy && false === Array.isArray(input.deploy) && _io2(input.deploy);
37
37
  const _io2 = input => _ip0(input) && (undefined === input.options || "object" === typeof input.options && null !== input.options && false === Array.isArray(input.options) && _io3(input.options));
38
38
  const _io3 = input => _ip0(input);
@@ -138,7 +138,7 @@ async function addReferencesFrom(roots, path, cwd) {
138
138
  }
139
139
  }
140
140
  }
141
- export function nxSmartArgs(target, mode, configuration, stage) {
141
+ export function nxSmartArgs(target, mode, configuration, stage, streamOutput = false) {
142
142
  const args = [mode, '-t', target];
143
143
  if (configuration) {
144
144
  args.push(`--configuration=${configuration}`);
@@ -146,6 +146,9 @@ export function nxSmartArgs(target, mode, configuration, stage) {
146
146
  if (stage) {
147
147
  args.push(`--stage=${stage}`);
148
148
  }
149
+ if (streamOutput) {
150
+ args.push('--outputStyle=stream-without-prefixes');
151
+ }
149
152
  args.push(`--exclude=tag:ci:skip:${target}`, `--parallel=${NX_PARALLEL}`);
150
153
  return args;
151
154
  }
@@ -154,7 +157,7 @@ export async function githubCiNxSmart(root, options) {
154
157
  const step = options.step ?? '';
155
158
  await createGithubStatus(name, step);
156
159
  const mode = resolveNxSmartMode(options.mode ?? 'auto');
157
- const nxArgs = nxSmartArgs(options.target, mode, options.configuration, options.stage);
160
+ const nxArgs = nxSmartArgs(options.target, mode, options.configuration, options.stage, options.streamOutput);
158
161
  const status = await runStatus('nx', nxArgs, root);
159
162
  await updateGithubStatus(name, status === 0 ? 'success' : 'failure', step);
160
163
  if (status !== 0) {
@@ -330,7 +333,7 @@ export async function githubCiNxDeploy(root, options, dependencies = {}) {
330
333
  const mode = resolveNxSmartMode(options.mode ?? 'run-many');
331
334
  const listProjects = dependencies.listProjects ?? listNxProjectsWithTarget;
332
335
  const runNx = dependencies.runNx ?? ((args, commandRoot) => runStatus('nx', args, commandRoot));
333
- const projects = await listProjects(root, 'deploy', mode);
336
+ const projects = await listProjects(root, 'deploy', mode, stage);
334
337
  if (projects.length === 0) {
335
338
  console.log(`No ${mode} deploy projects; skipping ${stage}.`);
336
339
  await setStatus('success');
@@ -344,7 +347,7 @@ export async function githubCiNxDeploy(root, options, dependencies = {}) {
344
347
  '-t',
345
348
  target,
346
349
  `--projects=${projectList}`,
347
- '--exclude=tag:permanent-deploy-target',
350
+ `--exclude=${deployExclusions(stage)}`,
348
351
  `--parallel=${NX_PARALLEL}`,
349
352
  ];
350
353
  if (target === 'deploy') {
@@ -451,19 +454,25 @@ function readGithubActionsEvent(environment) {
451
454
  return undefined;
452
455
  }
453
456
  }
454
- async function listNxProjectsWithTarget(root, target, mode) {
457
+ function deployExclusions(stage) {
458
+ const tags = ['tag:permanent-deploy-target'];
459
+ if (stage !== 'staging')
460
+ tags.push('tag:staging-deploy-target');
461
+ return tags.join(',');
462
+ }
463
+ async function listNxProjectsWithTarget(root, target, mode, stage) {
455
464
  const listArgs = ['show', 'projects'];
456
465
  if (mode === 'affected')
457
466
  listArgs.push('--affected');
458
467
  listArgs.push('--withTarget', target);
459
468
  if (target === 'deploy')
460
- listArgs.push('--exclude=tag:permanent-deploy-target');
469
+ listArgs.push(`--exclude=${deployExclusions(stage)}`);
461
470
  listArgs.push('--json');
462
471
  const result = await $ `nx ${listArgs}`.cwd(root).quiet();
463
472
  const candidates = nxProjectList(decode(result.stdout)).sort((left, right) => left.localeCompare(right));
464
473
  if (target !== 'deploy')
465
474
  return candidates;
466
- return selectStageDeployProjects(candidates, async (project) => {
475
+ return selectStageDeployProjects(candidates, stage, async (project) => {
467
476
  const projectResult = await $ `nx show project ${project} --json`.cwd(root).quiet();
468
477
  const parsed = parseNxProjectDeployTarget(decode(projectResult.stdout));
469
478
  if (!parsed)
@@ -471,7 +480,7 @@ async function listNxProjectsWithTarget(root, target, mode) {
471
480
  return parsed;
472
481
  });
473
482
  }
474
- export async function selectStageDeployProjects(candidates, loadProject) {
483
+ export async function selectStageDeployProjects(candidates, stage, loadProject) {
475
484
  const selected = [];
476
485
  for (const project of candidates) {
477
486
  const definition = await loadProject(project);
@@ -479,7 +488,12 @@ export async function selectStageDeployProjects(candidates, loadProject) {
479
488
  continue;
480
489
  const deploy = definition.targets?.deploy;
481
490
  const commandValue = deploy?.options?.command ?? deploy?.command;
482
- if (typeof commandValue === 'string' && commandValue.includes('smoo wrangler deploy-stage')) {
491
+ const tags = Array.isArray(definition.tags)
492
+ ? definition.tags.filter((tag) => typeof tag === 'string')
493
+ : [];
494
+ const isStageDerived = typeof commandValue === 'string' && commandValue.includes('smoo wrangler deploy-stage');
495
+ const isStagingOnly = tags.includes('staging-deploy-target');
496
+ if (isStageDerived || (stage === 'staging' && isStagingOnly)) {
483
497
  selected.push(project);
484
498
  }
485
499
  }
@@ -253,7 +253,7 @@ function renderE2eDeploymentJob(options) {
253
253
  return '';
254
254
  return `
255
255
  e2e-deployment:
256
- name: Deployment E2E
256
+ name: E2E Tests (Deployed Stage)
257
257
  needs: main
258
258
  ${renderRunsOnLine(options.runsOn)}
259
259
  timeout-minutes: 15
@@ -275,9 +275,9 @@ ${renderRunsOnLine(options.runsOn)}
275
275
  uses: ./.github/actions/setup-devenv
276
276
 
277
277
  # Step 4
278
- - name: Deployment E2E
278
+ - name: E2E Tests (Deployed Stage)
279
279
  # prettier-ignore
280
- run: smoo github-ci nx-smart --target e2e-deployment --mode run-many --stage "\${{ needs.main.outputs.deployment-stage }}" --name "Deployment E2E" --step 4
280
+ run: smoo github-ci nx-smart --target e2e-deployment --mode run-many --stage "\${{ needs.main.outputs.deployment-stage }}" --stream-output --name "E2E Tests (Deployed Stage)" --step 4
281
281
 
282
282
  # Step 5
283
283
  - name: 🧹 Cleanup and cache Nix/devenv
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smoothbricks/cli",
3
- "version": "0.10.13",
3
+ "version": "0.10.15",
4
4
  "type": "module",
5
5
  "description": "SmoothBricks monorepo automation CLI",
6
6
  "bin": {
package/src/cli.ts CHANGED
@@ -336,6 +336,7 @@ function buildProgram(): Command {
336
336
  .option('--mode <mode>', 'auto, affected, or run-many', 'auto')
337
337
  .option('--configuration <configuration>')
338
338
  .option('--stage <stage>')
339
+ .option('--stream-output', 'stream Nx task output without prefixes')
339
340
  .action(
340
341
  async (options: {
341
342
  target: string;
@@ -344,6 +345,7 @@ function buildProgram(): Command {
344
345
  mode?: 'auto' | 'affected' | 'run-many';
345
346
  configuration?: string;
346
347
  stage?: string;
348
+ streamOutput?: boolean;
347
349
  }) => {
348
350
  const { githubCiNxSmart } = await import('./github-ci/index.js');
349
351
  await githubCiNxSmart(await findRepoRoot(), options);
@@ -134,12 +134,13 @@ describe('GitHub CI Nx target expansion', () => {
134
134
  ).toEqual(['native:package-linux', 'native:compile-linux', 'native:build']);
135
135
  });
136
136
 
137
- it('adds optional stage before the generic target skip tag only to nx-smart', () => {
138
- expect(nxSmartArgs('e2e-deployment', 'run-many', undefined, 'pr123')).toEqual([
137
+ it('adds optional stage and streaming before the generic target skip tag only to nx-smart', () => {
138
+ expect(nxSmartArgs('e2e-deployment', 'run-many', undefined, 'pr123', true)).toEqual([
139
139
  'run-many',
140
140
  '-t',
141
141
  'e2e-deployment',
142
142
  '--stage=pr123',
143
+ '--outputStyle=stream-without-prefixes',
143
144
  '--exclude=tag:ci:skip:e2e-deployment',
144
145
  '--parallel=100%',
145
146
  ]);
@@ -572,7 +573,7 @@ describe('event-aware stage deployment', () => {
572
573
  ).toThrow(/same-repository/);
573
574
  });
574
575
 
575
- it('selects only deploy targets owned by the stage convention', async () => {
576
+ it('selects stage-derived deploy targets plus staging-only infrastructure on staging', async () => {
576
577
  const definitions: Record<string, unknown> = {
577
578
  'conloca-app': {
578
579
  targets: {
@@ -582,17 +583,34 @@ describe('event-aware stage deployment', () => {
582
583
  'conloca-app-backend': {
583
584
  targets: { deploy: { command: 'smoo wrangler deploy-stage --stage {args.stage}' } },
584
585
  },
586
+ 'conloca-e2e-mail-capture': {
587
+ tags: ['staging-deploy-target'],
588
+ targets: { deploy: { options: { command: 'bun scripts/deploy.ts --stage={args.stage}' } } },
589
+ },
585
590
  'conloca-oauth-redirect': {
591
+ tags: ['permanent-deploy-target'],
586
592
  targets: { deploy: { options: { command: 'wrangler deploy --config wrangler.toml' } } },
587
593
  },
588
594
  'conloca-website': {
589
595
  targets: { deploy: { options: { command: 'bun scripts/deploy-website.ts' } } },
590
596
  },
591
597
  };
598
+ const candidates = Object.keys(definitions);
599
+ const loadProject = async (project: string) => definitions[project];
592
600
 
593
- await expect(
594
- selectStageDeployProjects(Object.keys(definitions), async (project) => definitions[project]),
595
- ).resolves.toEqual(['conloca-app', 'conloca-app-backend']);
601
+ await expect(selectStageDeployProjects(candidates, 'staging', loadProject)).resolves.toEqual([
602
+ 'conloca-app',
603
+ 'conloca-app-backend',
604
+ 'conloca-e2e-mail-capture',
605
+ ]);
606
+ await expect(selectStageDeployProjects(candidates, 'pr123', loadProject)).resolves.toEqual([
607
+ 'conloca-app',
608
+ 'conloca-app-backend',
609
+ ]);
610
+ await expect(selectStageDeployProjects(candidates, 'production', loadProject)).resolves.toEqual([
611
+ 'conloca-app',
612
+ 'conloca-app-backend',
613
+ ]);
596
614
  });
597
615
 
598
616
  it('publishes GitHub deployment JSON through a real stdin process seam', async () => {
@@ -657,7 +675,7 @@ describe('event-aware stage deployment', () => {
657
675
 
658
676
  it('deploys app/backend, publishes PR metadata, and emits the resolved stage', async () => {
659
677
  const nxCalls: string[][] = [];
660
- const listCalls: Array<[string, string]> = [];
678
+ const listCalls: Array<[string, string, string]> = [];
661
679
  const summaries: string[] = [];
662
680
  const deployments: Array<[string, string]> = [];
663
681
  const outputs: string[] = [];
@@ -677,8 +695,8 @@ describe('event-aware stage deployment', () => {
677
695
  repository: { full_name: 'owner/repo' },
678
696
  pull_request: { number: 123, head: { repo: { full_name: 'owner/repo' } } },
679
697
  },
680
- listProjects: async (_root, target, mode) => {
681
- listCalls.push([target, mode]);
698
+ listProjects: async (_root, target, mode, stage) => {
699
+ listCalls.push([target, mode, stage]);
682
700
  return ['conloca-app', 'conloca-app-backend'];
683
701
  },
684
702
  runNx: async (args) => {
@@ -697,10 +715,10 @@ describe('event-aware stage deployment', () => {
697
715
  },
698
716
  );
699
717
 
700
- expect(listCalls).toEqual([['deploy', 'run-many']]);
718
+ expect(listCalls).toEqual([['deploy', 'run-many', 'pr123']]);
701
719
  expect(nxCalls).toHaveLength(1);
702
720
  expect(nxCalls[0]).toContain('--projects=conloca-app,conloca-app-backend');
703
- expect(nxCalls[0]).toContain('--exclude=tag:permanent-deploy-target');
721
+ expect(nxCalls[0]).toContain('--exclude=tag:permanent-deploy-target,tag:staging-deploy-target');
704
722
  expect(nxCalls[0]).toContain('--stage=pr123');
705
723
  expect(nxCalls[0]).not.toContain('e2e-deployment');
706
724
  expect(summaries).toEqual(['## pr123 deployment\n\n[View deployment](https://app.pr123.conloca.com)\n']);
@@ -27,6 +27,7 @@ export interface GithubActionsEventPayload {
27
27
  }
28
28
 
29
29
  interface NxProjectDeployTarget {
30
+ tags?: unknown;
30
31
  targets?: {
31
32
  deploy?: {
32
33
  command?: unknown;
@@ -159,6 +160,7 @@ export function nxSmartArgs(
159
160
  mode: 'affected' | 'run-many',
160
161
  configuration?: string,
161
162
  stage?: string,
163
+ streamOutput = false,
162
164
  ): string[] {
163
165
  const args = [mode, '-t', target];
164
166
  if (configuration) {
@@ -167,19 +169,30 @@ export function nxSmartArgs(
167
169
  if (stage) {
168
170
  args.push(`--stage=${stage}`);
169
171
  }
172
+ if (streamOutput) {
173
+ args.push('--outputStyle=stream-without-prefixes');
174
+ }
170
175
  args.push(`--exclude=tag:ci:skip:${target}`, `--parallel=${NX_PARALLEL}`);
171
176
  return args;
172
177
  }
173
178
 
174
179
  export async function githubCiNxSmart(
175
180
  root: string,
176
- options: { target: string; name?: string; step?: string; mode?: NxSmartMode; configuration?: string; stage?: string },
181
+ options: {
182
+ target: string;
183
+ name?: string;
184
+ step?: string;
185
+ mode?: NxSmartMode;
186
+ configuration?: string;
187
+ stage?: string;
188
+ streamOutput?: boolean;
189
+ },
177
190
  ): Promise<void> {
178
191
  const name = options.name ?? options.target;
179
192
  const step = options.step ?? '';
180
193
  await createGithubStatus(name, step);
181
194
  const mode = resolveNxSmartMode(options.mode ?? 'auto');
182
- const nxArgs = nxSmartArgs(options.target, mode, options.configuration, options.stage);
195
+ const nxArgs = nxSmartArgs(options.target, mode, options.configuration, options.stage, options.streamOutput);
183
196
  const status = await runStatus('nx', nxArgs, root);
184
197
  await updateGithubStatus(name, status === 0 ? 'success' : 'failure', step);
185
198
  if (status !== 0) {
@@ -392,7 +405,12 @@ export interface GithubCiNxDeployOptions {
392
405
  }
393
406
 
394
407
  export interface GithubCiNxDeployDependencies {
395
- listProjects?: (root: string, target: string, mode: 'affected' | 'run-many') => Promise<string[]>;
408
+ listProjects?: (
409
+ root: string,
410
+ target: string,
411
+ mode: 'affected' | 'run-many',
412
+ stage: DeploymentStage,
413
+ ) => Promise<string[]>;
396
414
  runNx?: (args: string[], root: string) => Promise<number>;
397
415
  appendSummary?: (summaryPath: string, content: string) => Promise<void>;
398
416
  appendOutput?: (outputPath: string, content: string) => Promise<void>;
@@ -420,7 +438,7 @@ export async function githubCiNxDeploy(
420
438
  const mode = resolveNxSmartMode(options.mode ?? 'run-many');
421
439
  const listProjects = dependencies.listProjects ?? listNxProjectsWithTarget;
422
440
  const runNx = dependencies.runNx ?? ((args: string[], commandRoot: string) => runStatus('nx', args, commandRoot));
423
- const projects = await listProjects(root, 'deploy', mode);
441
+ const projects = await listProjects(root, 'deploy', mode, stage);
424
442
  if (projects.length === 0) {
425
443
  console.log(`No ${mode} deploy projects; skipping ${stage}.`);
426
444
  await setStatus('success');
@@ -435,7 +453,7 @@ export async function githubCiNxDeploy(
435
453
  '-t',
436
454
  target,
437
455
  `--projects=${projectList}`,
438
- '--exclude=tag:permanent-deploy-target',
456
+ `--exclude=${deployExclusions(stage)}`,
439
457
  `--parallel=${NX_PARALLEL}`,
440
458
  ];
441
459
  if (target === 'deploy') {
@@ -553,20 +571,27 @@ function readGithubActionsEvent(environment: NodeJS.ProcessEnv): GithubActionsEv
553
571
  }
554
572
  }
555
573
 
574
+ function deployExclusions(stage: DeploymentStage): string {
575
+ const tags = ['tag:permanent-deploy-target'];
576
+ if (stage !== 'staging') tags.push('tag:staging-deploy-target');
577
+ return tags.join(',');
578
+ }
579
+
556
580
  async function listNxProjectsWithTarget(
557
581
  root: string,
558
582
  target: string,
559
583
  mode: 'affected' | 'run-many',
584
+ stage: DeploymentStage,
560
585
  ): Promise<string[]> {
561
586
  const listArgs = ['show', 'projects'];
562
587
  if (mode === 'affected') listArgs.push('--affected');
563
588
  listArgs.push('--withTarget', target);
564
- if (target === 'deploy') listArgs.push('--exclude=tag:permanent-deploy-target');
589
+ if (target === 'deploy') listArgs.push(`--exclude=${deployExclusions(stage)}`);
565
590
  listArgs.push('--json');
566
591
  const result = await $`nx ${listArgs}`.cwd(root).quiet();
567
592
  const candidates = nxProjectList(decode(result.stdout)).sort((left, right) => left.localeCompare(right));
568
593
  if (target !== 'deploy') return candidates;
569
- return selectStageDeployProjects(candidates, async (project) => {
594
+ return selectStageDeployProjects(candidates, stage, async (project) => {
570
595
  const projectResult = await $`nx show project ${project} --json`.cwd(root).quiet();
571
596
  const parsed = parseNxProjectDeployTarget(decode(projectResult.stdout));
572
597
  if (!parsed) throw new Error(`nx show project ${project} returned invalid JSON.`);
@@ -576,6 +601,7 @@ async function listNxProjectsWithTarget(
576
601
 
577
602
  export async function selectStageDeployProjects(
578
603
  candidates: string[],
604
+ stage: DeploymentStage,
579
605
  loadProject: (project: string) => Promise<unknown>,
580
606
  ): Promise<string[]> {
581
607
  const selected: string[] = [];
@@ -584,7 +610,12 @@ export async function selectStageDeployProjects(
584
610
  if (!isNxProjectDeployTarget(definition)) continue;
585
611
  const deploy = definition.targets?.deploy;
586
612
  const commandValue = deploy?.options?.command ?? deploy?.command;
587
- if (typeof commandValue === 'string' && commandValue.includes('smoo wrangler deploy-stage')) {
613
+ const tags = Array.isArray(definition.tags)
614
+ ? definition.tags.filter((tag): tag is string => typeof tag === 'string')
615
+ : [];
616
+ const isStageDerived = typeof commandValue === 'string' && commandValue.includes('smoo wrangler deploy-stage');
617
+ const isStagingOnly = tags.includes('staging-deploy-target');
618
+ if (isStageDerived || (stage === 'staging' && isStagingOnly)) {
588
619
  selected.push(project);
589
620
  }
590
621
  }
@@ -77,7 +77,7 @@ describe('CI workflow definition', () => {
77
77
  const rendered = renderCiWorkflowYaml(options({ deploy: true, e2eDeployment: true, runsOn: [...nixosRunsOn] }));
78
78
 
79
79
  expect(rendered).toContain('deployment-stage: ${{ steps.deploy.outputs.stage }}');
80
- expect(rendered).toContain(' e2e-deployment:\n name: Deployment E2E\n needs: main');
80
+ expect(rendered).toContain(' e2e-deployment:\n name: E2E Tests (Deployed Stage)\n needs: main');
81
81
  expect(rendered).not.toContain('\n\n\n e2e-deployment:');
82
82
  expect(rendered).toContain(
83
83
  "if: ${{ needs.main.result == 'success' && needs.main.outputs.deployment-stage != '' }}",
@@ -88,9 +88,9 @@ describe('CI workflow definition', () => {
88
88
  );
89
89
  expect(rendered).toContain('# prettier-ignore\n run: smoo github-ci nx-smart --target e2e-deployment');
90
90
  expect(rendered).toContain(
91
- 'smoo github-ci nx-smart --target e2e-deployment --mode run-many --stage "${{ needs.main.outputs.deployment-stage }}" --name "Deployment E2E" --step 4',
91
+ 'smoo github-ci nx-smart --target e2e-deployment --mode run-many --stage "${{ needs.main.outputs.deployment-stage }}" --stream-output --name "E2E Tests (Deployed Stage)" --step 4',
92
92
  );
93
- expect(rendered.match(/name: Deployment E2E/g)).toHaveLength(2);
93
+ expect(rendered.match(/name: E2E Tests \(Deployed Stage\)/g)).toHaveLength(2);
94
94
  });
95
95
 
96
96
  it('omits optional browser and deployment-E2E lanes when disabled', () => {
@@ -295,7 +295,7 @@ function renderE2eDeploymentJob(options: CiWorkflowDefinitionOptions): string {
295
295
  if (!options.e2eDeployment) return '';
296
296
  return `
297
297
  e2e-deployment:
298
- name: Deployment E2E
298
+ name: E2E Tests (Deployed Stage)
299
299
  needs: main
300
300
  ${renderRunsOnLine(options.runsOn)}
301
301
  timeout-minutes: 15
@@ -317,9 +317,9 @@ ${renderRunsOnLine(options.runsOn)}
317
317
  uses: ./.github/actions/setup-devenv
318
318
 
319
319
  # Step 4
320
- - name: Deployment E2E
320
+ - name: E2E Tests (Deployed Stage)
321
321
  # prettier-ignore
322
- run: smoo github-ci nx-smart --target e2e-deployment --mode run-many --stage "\${{ needs.main.outputs.deployment-stage }}" --name "Deployment E2E" --step 4
322
+ run: smoo github-ci nx-smart --target e2e-deployment --mode run-many --stage "\${{ needs.main.outputs.deployment-stage }}" --stream-output --name "E2E Tests (Deployed Stage)" --step 4
323
323
 
324
324
  # Step 5
325
325
  - name: 🧹 Cleanup and cache Nix/devenv