cistack 3.0.1 → 3.2.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/package.json +1 -1
- package/src/generators/workflow.js +40 -11
- package/src/index.js +55 -3
package/package.json
CHANGED
|
@@ -280,6 +280,7 @@ class WorkflowGenerator {
|
|
|
280
280
|
const h = this.primaryHosting;
|
|
281
281
|
const lang = this.primaryLang;
|
|
282
282
|
const branches = this.extraConfig.branches || ['main', 'master'];
|
|
283
|
+
const isGHPages = h.name === 'GitHub Pages';
|
|
283
284
|
|
|
284
285
|
const preDeploySteps = [
|
|
285
286
|
this._stepCheckout(),
|
|
@@ -288,14 +289,21 @@ class WorkflowGenerator {
|
|
|
288
289
|
].filter(Boolean);
|
|
289
290
|
|
|
290
291
|
const deploySteps = this._hostingDeploySteps(h, lang, false); // production
|
|
291
|
-
|
|
292
|
+
// GitHub Pages has no PR preview concept — skip preview job for it
|
|
293
|
+
const previewSteps = isGHPages ? [] : this._hostingDeploySteps(h, lang, true);
|
|
294
|
+
|
|
295
|
+
// GitHub Pages requires special permissions on the deploy job
|
|
296
|
+
const ghPagesPermissions = isGHPages
|
|
297
|
+
? { pages: 'write', 'id-token': 'write', contents: 'read' }
|
|
298
|
+
: undefined;
|
|
292
299
|
|
|
293
300
|
const jobs = {
|
|
294
301
|
deploy: {
|
|
295
302
|
name: `🚀 Deploy → ${h.name} (Production)`,
|
|
296
303
|
if: "github.event_name == 'push' || github.event_name == 'workflow_dispatch'",
|
|
297
304
|
'runs-on': 'ubuntu-latest',
|
|
298
|
-
environment: 'production',
|
|
305
|
+
environment: isGHPages ? 'github-pages' : 'production',
|
|
306
|
+
...(ghPagesPermissions ? { permissions: ghPagesPermissions } : {}),
|
|
299
307
|
steps: [...preDeploySteps, ...deploySteps].filter(Boolean),
|
|
300
308
|
},
|
|
301
309
|
};
|
|
@@ -323,13 +331,14 @@ class WorkflowGenerator {
|
|
|
323
331
|
|
|
324
332
|
const envComment = this._envComment();
|
|
325
333
|
|
|
334
|
+
// GitHub Pages doesn't need pull_request trigger (no preview)
|
|
335
|
+
const onTrigger = isGHPages
|
|
336
|
+
? { push: { branches: branches.filter((b) => b !== 'develop') }, workflow_dispatch: {} }
|
|
337
|
+
: { push: { branches: branches.filter((b) => b !== 'develop') }, pull_request: { branches }, workflow_dispatch: {} };
|
|
338
|
+
|
|
326
339
|
const workflow = {
|
|
327
340
|
name: `Deploy to ${h.name}`,
|
|
328
|
-
on:
|
|
329
|
-
push: { branches: branches.filter((b) => b !== 'develop') },
|
|
330
|
-
pull_request: { branches },
|
|
331
|
-
workflow_dispatch: {},
|
|
332
|
-
},
|
|
341
|
+
on: onTrigger,
|
|
333
342
|
jobs,
|
|
334
343
|
};
|
|
335
344
|
|
|
@@ -739,11 +748,28 @@ class WorkflowGenerator {
|
|
|
739
748
|
|
|
740
749
|
case 'Vercel': {
|
|
741
750
|
const prodFlag = isPreview ? '' : '--prod';
|
|
751
|
+
const vercelEnv = {
|
|
752
|
+
VERCEL_TOKEN: '${{ secrets.VERCEL_TOKEN }}',
|
|
753
|
+
VERCEL_ORG_ID: '${{ secrets.VERCEL_ORG_ID }}',
|
|
754
|
+
VERCEL_PROJECT_ID: '${{ secrets.VERCEL_PROJECT_ID }}',
|
|
755
|
+
};
|
|
742
756
|
steps.push(
|
|
743
757
|
{ name: 'Install Vercel CLI', run: 'npm install -g vercel' },
|
|
744
|
-
{
|
|
745
|
-
|
|
746
|
-
|
|
758
|
+
{
|
|
759
|
+
name: 'Pull Vercel environment',
|
|
760
|
+
run: `vercel pull --yes --environment=${isPreview ? 'preview' : 'production'} --token=\${{ secrets.VERCEL_TOKEN }}`,
|
|
761
|
+
env: vercelEnv,
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
name: 'Build project',
|
|
765
|
+
run: `vercel build${prodFlag ? ' ' + prodFlag : ''} --token=\${{ secrets.VERCEL_TOKEN }}`,
|
|
766
|
+
env: vercelEnv,
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
name: 'Deploy to Vercel',
|
|
770
|
+
run: `vercel deploy --prebuilt${prodFlag ? ' ' + prodFlag : ''} --token=\${{ secrets.VERCEL_TOKEN }}`,
|
|
771
|
+
env: vercelEnv,
|
|
772
|
+
},
|
|
747
773
|
);
|
|
748
774
|
break;
|
|
749
775
|
}
|
|
@@ -832,7 +858,10 @@ class WorkflowGenerator {
|
|
|
832
858
|
}
|
|
833
859
|
|
|
834
860
|
case 'Render': {
|
|
835
|
-
|
|
861
|
+
// Render doesn't support PR preview deploys via deploy hook
|
|
862
|
+
if (!isPreview) {
|
|
863
|
+
steps.push({ name: 'Trigger Render deploy', run: 'curl -X POST "${{ secrets.RENDER_DEPLOY_HOOK_URL }}"' });
|
|
864
|
+
}
|
|
836
865
|
break;
|
|
837
866
|
}
|
|
838
867
|
|
package/src/index.js
CHANGED
|
@@ -257,20 +257,72 @@ class CIFlow {
|
|
|
257
257
|
if (!confirmed) {
|
|
258
258
|
console.log(chalk.yellow('\nCustomisation mode – answer the prompts below:\n'));
|
|
259
259
|
|
|
260
|
-
|
|
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:
|
|
302
|
+
default: currentDefaults,
|
|
268
303
|
},
|
|
269
304
|
]);
|
|
270
305
|
|
|
271
306
|
config.hosting = customHosting
|
|
272
307
|
.filter((h) => h !== 'none')
|
|
273
|
-
.map((h) => ({
|
|
308
|
+
.map((h) => ({
|
|
309
|
+
name: HOSTING_NAME_MAP[h] || h, // always the correct PascalCase name
|
|
310
|
+
confidence: 1.0,
|
|
311
|
+
manual: true,
|
|
312
|
+
// Populate secrets so the generated deploy.yml header lists them correctly
|
|
313
|
+
secrets: {
|
|
314
|
+
firebase: ['FIREBASE_SERVICE_ACCOUNT'],
|
|
315
|
+
vercel: ['VERCEL_TOKEN', 'VERCEL_ORG_ID', 'VERCEL_PROJECT_ID'],
|
|
316
|
+
netlify: ['NETLIFY_AUTH_TOKEN', 'NETLIFY_SITE_ID'],
|
|
317
|
+
aws: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_REGION', 'AWS_S3_BUCKET', 'CLOUDFRONT_DISTRIBUTION_ID'],
|
|
318
|
+
gcp: ['GCP_SA_KEY'],
|
|
319
|
+
azure: ['AZURE_APP_NAME', 'AZURE_WEBAPP_PUBLISH_PROFILE'],
|
|
320
|
+
heroku: ['HEROKU_API_KEY', 'HEROKU_APP_NAME', 'HEROKU_EMAIL'],
|
|
321
|
+
render: ['RENDER_DEPLOY_HOOK_URL'],
|
|
322
|
+
railway: ['RAILWAY_TOKEN'],
|
|
323
|
+
'github-pages': [],
|
|
324
|
+
}[h] || [],
|
|
325
|
+
}));
|
|
274
326
|
}
|
|
275
327
|
|
|
276
328
|
return config;
|