cistack 3.0.0 → 3.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/bin/ciflow.js CHANGED
@@ -6,10 +6,12 @@ const { program } = require('commander');
6
6
  const path = require('path');
7
7
  const CIFlow = require('../src/index');
8
8
 
9
+ const { version } = require('../package.json');
10
+
9
11
  program
10
12
  .name('cistack')
11
13
  .description('Generate GitHub Actions CI/CD pipelines by analysing your codebase')
12
- .version('2.0.0');
14
+ .version(version);
13
15
 
14
16
  program
15
17
  .command('generate', { isDefault: true })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cistack",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Automatically generate GitHub Actions CI/CD pipelines by analysing your codebase",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const yaml = require('js-yaml');
4
+ const { version } = require('../../package.json');
5
+
4
6
 
5
7
  /**
6
8
  * Takes all detected signals and produces one or more complete GitHub Actions workflow YAML files.
@@ -190,7 +192,7 @@ class WorkflowGenerator {
190
192
 
191
193
  const envComment = this._envComment();
192
194
  const header =
193
- `# Generated by cistack v2.0.0 — https://github.com/cistack\n` +
195
+ `# Generated by cistack v${version} — https://github.com/cistack\n` +
194
196
  `# CI Pipeline: lint → test → build${this.e2eTests.length > 0 ? ' → e2e' : ''}\n` +
195
197
  envComment +
196
198
  `\n`;
@@ -266,7 +268,7 @@ class WorkflowGenerator {
266
268
 
267
269
  return this._toYaml(
268
270
  workflow,
269
- '# Generated by cistack v2.0.0 — https://github.com/cistack\n# Monorepo CI — matrix over all workspaces\n\n'
271
+ `# Generated by cistack v${version} — https://github.com/cistack\n# Monorepo CI — matrix over all workspaces\n\n`
270
272
  );
271
273
  }
272
274
 
@@ -333,7 +335,7 @@ class WorkflowGenerator {
333
335
 
334
336
  return this._toYaml(
335
337
  workflow,
336
- `# Generated by cistack v2.0.0\n# Deploy Pipeline → ${h.name}\n${secretsDoc}${envComment}\n`
338
+ `# Generated by cistack v${version}\n# Deploy Pipeline → ${h.name}\n${secretsDoc}${envComment}\n`
337
339
  );
338
340
  }
339
341
 
@@ -411,7 +413,7 @@ class WorkflowGenerator {
411
413
  },
412
414
  };
413
415
 
414
- return this._toYaml(workflow, '# Generated by cistack v2.0.0\n# Docker image build and push to GHCR\n\n');
416
+ return this._toYaml(workflow, `# Generated by cistack v${version}\n# Docker image build and push to GHCR\n\n`);
415
417
  }
416
418
 
417
419
  // ══════════════════════════════════════════════════════════════════════════
@@ -483,7 +485,7 @@ class WorkflowGenerator {
483
485
  },
484
486
  };
485
487
 
486
- return this._toYaml(workflow, '# Generated by cistack v2.0.0\n# Security: dependency audit + CodeQL analysis (runs weekly)\n\n');
488
+ return this._toYaml(workflow, `# Generated by cistack v${version}\n# Security: dependency audit + CodeQL analysis (runs weekly)\n\n`);
487
489
  }
488
490
 
489
491
  // ══════════════════════════════════════════════════════════════════════════
@@ -740,8 +742,8 @@ class WorkflowGenerator {
740
742
  steps.push(
741
743
  { name: 'Install Vercel CLI', run: 'npm install -g vercel' },
742
744
  { name: 'Pull Vercel environment', run: `vercel pull --yes --environment=${isPreview ? 'preview' : 'production'} --token=\${{ secrets.VERCEL_TOKEN }}` },
743
- { name: 'Build project', run: `vercel build ${prodFlag} --token=\${{ secrets.VERCEL_TOKEN }}` },
744
- { name: 'Deploy to Vercel', run: `vercel deploy --prebuilt ${prodFlag} --token=\${{ secrets.VERCEL_TOKEN }}` },
745
+ { name: 'Build project', run: `vercel build${prodFlag ? ' ' + prodFlag : ''} --token=\${{ secrets.VERCEL_TOKEN }}` },
746
+ { name: 'Deploy to Vercel', run: `vercel deploy --prebuilt${prodFlag ? ' ' + prodFlag : ''} --token=\${{ secrets.VERCEL_TOKEN }}` },
745
747
  );
746
748
  break;
747
749
  }
package/src/index.js CHANGED
@@ -257,20 +257,60 @@ class CIFlow {
257
257
  if (!confirmed) {
258
258
  console.log(chalk.yellow('\nCustomisation mode – answer the prompts below:\n'));
259
259
 
260
- const hostingChoices = ['firebase', 'vercel', 'netlify', 'aws', 'gcp', 'azure', 'heroku', 'render', 'railway', 'none'];
260
+ // Map lowercase choice values exact names used in _hostingDeploySteps() switch cases
261
+ const HOSTING_NAME_MAP = {
262
+ firebase: 'Firebase',
263
+ vercel: 'Vercel',
264
+ netlify: 'Netlify',
265
+ aws: 'AWS',
266
+ gcp: 'GCP App Engine',
267
+ azure: 'Azure',
268
+ heroku: 'Heroku',
269
+ render: 'Render',
270
+ railway: 'Railway',
271
+ 'github-pages':'GitHub Pages',
272
+ };
273
+
274
+ const hostingChoices = [
275
+ { name: 'Firebase', value: 'firebase' },
276
+ { name: 'Vercel', value: 'vercel' },
277
+ { name: 'Netlify', value: 'netlify' },
278
+ { name: 'AWS (S3 + CloudFront)', value: 'aws' },
279
+ { name: 'GCP App Engine',value: 'gcp' },
280
+ { name: 'Azure Web App', value: 'azure' },
281
+ { name: 'Heroku', value: 'heroku' },
282
+ { name: 'Render', value: 'render' },
283
+ { name: 'Railway', value: 'railway' },
284
+ { name: 'GitHub Pages', value: 'github-pages' },
285
+ { name: 'None', value: 'none' },
286
+ ];
287
+
288
+ // Pre-select whatever was already detected (match by canonical name)
289
+ const reverseMap = Object.fromEntries(
290
+ Object.entries(HOSTING_NAME_MAP).map(([k, v]) => [v.toLowerCase(), k])
291
+ );
292
+ const currentDefaults = config.hosting
293
+ .map((h) => reverseMap[h.name.toLowerCase()])
294
+ .filter(Boolean);
295
+
261
296
  const { customHosting } = await inquirer.prompt([
262
297
  {
263
298
  type: 'checkbox',
264
299
  name: 'customHosting',
265
300
  message: 'Select hosting platform(s):',
266
301
  choices: hostingChoices,
267
- default: config.hosting.map((h) => h.name.toLowerCase()),
302
+ default: currentDefaults,
268
303
  },
269
304
  ]);
270
305
 
271
306
  config.hosting = customHosting
272
307
  .filter((h) => h !== 'none')
273
- .map((h) => ({ name: h, confidence: 1.0, manual: true, secrets: [] }));
308
+ .map((h) => ({
309
+ name: HOSTING_NAME_MAP[h] || h, // always the correct PascalCase name
310
+ confidence: 1.0,
311
+ manual: true,
312
+ secrets: [],
313
+ }));
274
314
  }
275
315
 
276
316
  return config;
@@ -5,6 +5,8 @@ const path = require('path');
5
5
  const chalk = require('chalk');
6
6
  const yaml = require('js-yaml');
7
7
 
8
+ const { version } = require('../../package.json');
9
+
8
10
  function ensureDir(dirPath) {
9
11
  if (!fs.existsSync(dirPath)) {
10
12
  fs.mkdirSync(dirPath, { recursive: true });
@@ -17,16 +19,8 @@ function writeFile(filePath, content) {
17
19
  }
18
20
 
19
21
  function banner() {
20
- console.log('\n' + chalk.bold.cyan(' ██████╗██╗███████╗████████╗ █████╗ ██████╗██╗ ██╗'));
21
- console.log(chalk.bold.cyan(' ██╔════╝██║██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝'));
22
- console.log(chalk.bold.cyan(' ██║ ██║███████╗ ██║ ███████║██║ █████╔╝ '));
23
- console.log(chalk.bold.cyan(' ██║ ██║╚════██║ ██║ ██╔══██║██║ ██╔═██╗ '));
24
- console.log(chalk.bold.cyan(' ╚██████╗██║███████║ ██║ ██║ ██║╚██████╗██║ ██╗'));
25
- console.log(chalk.bold.cyan(' ╚═════╝╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝'));
26
- console.log('');
27
- console.log(' ' + chalk.dim('GitHub Actions pipeline generator ') + chalk.bold.cyan('v2.0.0'));
28
- console.log(' ' + chalk.dim('─'.repeat(52)));
29
- console.log('');
22
+ console.log('\n' + chalk.bold.cyan(' cistack ') + chalk.dim('v' + version));
23
+ console.log(chalk.dim(' ' + '─'.repeat(24)) + '\n');
30
24
  }
31
25
 
32
26
  /**