@sonarsource/marketing-cli 1.0.0 → 1.1.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/README.md CHANGED
@@ -171,6 +171,10 @@ Clone a Kontent.ai environment for the current branch.
171
171
 
172
172
  Migrate the source environment, delete the clone, and clean up Netlify vars and status.
173
173
 
174
+ ### `marketing environment verify`
175
+
176
+ Check whether the current branch's Kontent environment has been properly finished before merging. Local-only — no credentials required. In CI, use `npx marketing environment verify --ci`.
177
+
174
178
  ### `marketing migration create <name>`
175
179
 
176
180
  Scaffold a new timestamp-ordered TypeScript migration in `Migrations/`.
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Command } from 'commander';
2
2
  import { readFileSync } from 'node:fs';
3
- import { environmentCreate, environmentFinish } from './commands/environment.js';
3
+ import { environmentCreate, environmentFinish, environmentVerify } from './commands/environment.js';
4
4
  import { init } from './commands/init.js';
5
5
  import { migrationCreate, migrationRun } from './commands/migration.js';
6
6
  import { setup } from './commands/setup.js';
@@ -98,5 +98,13 @@ export function buildProgram() {
98
98
  const globalOpts = program.opts();
99
99
  await environmentFinish(globalOpts);
100
100
  }));
101
+ environment
102
+ .command('verify')
103
+ .description('Check that the current branch is safe to merge (no unfinished environments).')
104
+ .option('--ci', 'Force CI mode (accepted for symmetry; verify never prompts)')
105
+ .action(wrapAction(async () => {
106
+ const globalOpts = program.opts();
107
+ await environmentVerify(globalOpts);
108
+ }));
101
109
  return program;
102
110
  }
@@ -11,6 +11,9 @@ export interface EnvironmentFinishOptions {
11
11
  ci?: boolean;
12
12
  yes?: boolean;
13
13
  }
14
+ export interface EnvironmentVerifyOptions {
15
+ branch?: string;
16
+ }
14
17
  interface ResolvedSource {
15
18
  environmentId: string;
16
19
  isProduction: boolean;
@@ -33,4 +36,5 @@ export declare function slugifyBranch(branch: string): string;
33
36
  export declare function resolveSourceEnvironment(branch: string, config: MarketingConfig): ResolvedSource;
34
37
  export declare function environmentCreate(opts: EnvironmentCreateOptions): Promise<void>;
35
38
  export declare function environmentFinish(opts: EnvironmentFinishOptions): Promise<void>;
39
+ export declare function environmentVerify(opts: EnvironmentVerifyOptions): Promise<void>;
36
40
  export {};
@@ -395,6 +395,40 @@ export async function environmentFinish(opts) {
395
395
  console.log(`\nEnvironment finished for branch "${branch}".`);
396
396
  }
397
397
  // ---------------------------------------------------------------------------
398
+ // environment verify
399
+ // ---------------------------------------------------------------------------
400
+ export async function environmentVerify(opts) {
401
+ const cwd = process.cwd();
402
+ const config = loadConfig(cwd);
403
+ const branch = requireBranch(opts);
404
+ const llb = config.kontent.longLivedBranches;
405
+ // --- Active-children check ---
406
+ const llbEntry = llb[branch];
407
+ if (llbEntry && llbEntry.children.length > 0) {
408
+ throw new CliError(`Long-lived branch "${branch}" still has children registered in config:\n` +
409
+ llbEntry.children.map((c) => ` \u2022 ${c}`).join('\n') +
410
+ `\nFinish and merge those branches (or remove them from config) before merging "${branch}".`);
411
+ }
412
+ // --- Build expected environment set ---
413
+ const status = loadStatusJson(cwd);
414
+ const statusKeys = Object.keys(status);
415
+ const expectedSet = new Set();
416
+ expectedSet.add(config.kontent.productionEnvironmentId);
417
+ for (const [llbBranch, entry] of Object.entries(llb)) {
418
+ if (llbBranch !== branch && entry.environmentId) {
419
+ expectedSet.add(entry.environmentId);
420
+ }
421
+ }
422
+ // --- Check for unexpected environments ---
423
+ const unexpected = statusKeys.filter((key) => !expectedSet.has(key));
424
+ if (unexpected.length > 0) {
425
+ throw new CliError(`Branch "${branch}" has an unfinished environment.\n` +
426
+ `Unexpected environments in Migrations/status.json:\n` +
427
+ unexpected.map((id) => ` \u2022 ${id}`).join('\n') +
428
+ `\nRun \`marketing environment finish\` before merging.`);
429
+ }
430
+ }
431
+ // ---------------------------------------------------------------------------
398
432
  // Utilities
399
433
  // ---------------------------------------------------------------------------
400
434
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonarsource/marketing-cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "bin": {