cistack 5.3.0 → 5.5.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 +2 -0
- package/package.json +1 -1
- package/src/generators/workflow.js +10 -6
- package/tests/run.js +62 -2
package/README.md
CHANGED
|
@@ -89,6 +89,8 @@ By default, `cistack` now generates a single GitHub Actions workflow that combin
|
|
|
89
89
|
|
|
90
90
|
Dependabot remains a separate file in `.github/dependabot.yml`, because it is not a GitHub Actions workflow.
|
|
91
91
|
|
|
92
|
+
If you want preview deployments on Dependabot pull requests, add deployment credentials as Dependabot secrets too, not only Actions secrets. For Vercel, that means `VERCEL_TOKEN`, `VERCEL_ORG_ID`, and `VERCEL_PROJECT_ID`.
|
|
93
|
+
|
|
92
94
|
### Split mode
|
|
93
95
|
|
|
94
96
|
If you prefer the old multi-file layout, set:
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
3
5
|
const yaml = require('js-yaml');
|
|
4
6
|
const { version } = require('../../package.json');
|
|
5
7
|
|
|
@@ -45,9 +47,6 @@ class WorkflowGenerator {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
_detectRuntimeVersions() {
|
|
48
|
-
const fs = require('fs');
|
|
49
|
-
const path = require('path');
|
|
50
|
-
|
|
51
50
|
// 1. Node.js
|
|
52
51
|
if (!this.primaryLang.nodeVersion) {
|
|
53
52
|
const nvmrcPath = path.join(this.projectPath, '.nvmrc');
|
|
@@ -204,7 +203,7 @@ class WorkflowGenerator {
|
|
|
204
203
|
with: {
|
|
205
204
|
uploadArtifacts: true,
|
|
206
205
|
temporaryPublicStorage: true,
|
|
207
|
-
|
|
206
|
+
...this._lighthouseActionConfig(),
|
|
208
207
|
},
|
|
209
208
|
},
|
|
210
209
|
],
|
|
@@ -422,7 +421,7 @@ class WorkflowGenerator {
|
|
|
422
421
|
if (previewSteps.length > 0) {
|
|
423
422
|
jobs.preview = {
|
|
424
423
|
name: `✨ Deploy → ${h.name} (Preview)`,
|
|
425
|
-
if: "github.event_name == 'pull_request' && github.
|
|
424
|
+
if: "github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository",
|
|
426
425
|
'runs-on': 'ubuntu-latest',
|
|
427
426
|
environment: 'preview',
|
|
428
427
|
steps: [
|
|
@@ -430,7 +429,7 @@ class WorkflowGenerator {
|
|
|
430
429
|
...previewSteps,
|
|
431
430
|
{
|
|
432
431
|
name: 'Comment PR',
|
|
433
|
-
if:
|
|
432
|
+
if: "always() && github.actor != 'dependabot[bot]'",
|
|
434
433
|
uses: 'actions/github-script@v7',
|
|
435
434
|
with: {
|
|
436
435
|
script: `
|
|
@@ -699,6 +698,11 @@ class WorkflowGenerator {
|
|
|
699
698
|
return steps;
|
|
700
699
|
}
|
|
701
700
|
|
|
701
|
+
_lighthouseActionConfig() {
|
|
702
|
+
const configPath = path.join(this.projectPath, '.lighthouserc.json');
|
|
703
|
+
return fs.existsSync(configPath) ? { configPath: './.lighthouserc.json' } : {};
|
|
704
|
+
}
|
|
705
|
+
|
|
702
706
|
_stepInstallDeps(lang) {
|
|
703
707
|
const pm = lang.packageManager;
|
|
704
708
|
if (pm === 'npm') return { name: 'Install dependencies', run: this.lockFiles.has('package-lock.json') ? 'npm ci' : 'npm install' };
|
package/tests/run.js
CHANGED
|
@@ -494,6 +494,64 @@ test('Frontend Lighthouse is omitted when no build job exists', () => {
|
|
|
494
494
|
assert(!parsed.jobs.lighthouse);
|
|
495
495
|
});
|
|
496
496
|
|
|
497
|
+
test('Lighthouse job does not require .lighthouserc.json when the file is absent', () => {
|
|
498
|
+
const projectDir = makeTempDir();
|
|
499
|
+
writeFiles(projectDir, {
|
|
500
|
+
'package.json': json({
|
|
501
|
+
name: 'lighthouse-default-app',
|
|
502
|
+
version: '1.0.0',
|
|
503
|
+
scripts: {
|
|
504
|
+
build: 'echo build',
|
|
505
|
+
},
|
|
506
|
+
}),
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
const generator = new WorkflowGenerator(
|
|
510
|
+
makeJsProject({
|
|
511
|
+
frameworks: [{ name: 'React', confidence: 1, buildDir: 'dist' }],
|
|
512
|
+
}),
|
|
513
|
+
projectDir
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
const parsed = parseWorkflow(generator._buildCIWorkflow());
|
|
517
|
+
const lighthouseStep = parsed.jobs.lighthouse.steps.find((step) => step.name === 'Run Lighthouse on build output');
|
|
518
|
+
|
|
519
|
+
assert(lighthouseStep);
|
|
520
|
+
assert(!('configPath' in lighthouseStep.with));
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
test('Lighthouse job uses .lighthouserc.json when the file exists', () => {
|
|
524
|
+
const projectDir = makeTempDir();
|
|
525
|
+
writeFiles(projectDir, {
|
|
526
|
+
'package.json': json({
|
|
527
|
+
name: 'lighthouse-config-app',
|
|
528
|
+
version: '1.0.0',
|
|
529
|
+
scripts: {
|
|
530
|
+
build: 'echo build',
|
|
531
|
+
},
|
|
532
|
+
}),
|
|
533
|
+
'.lighthouserc.json': json({
|
|
534
|
+
ci: {
|
|
535
|
+
collect: {
|
|
536
|
+
numberOfRuns: 1,
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
}),
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
const generator = new WorkflowGenerator(
|
|
543
|
+
makeJsProject({
|
|
544
|
+
frameworks: [{ name: 'React', confidence: 1, buildDir: 'dist' }],
|
|
545
|
+
}),
|
|
546
|
+
projectDir
|
|
547
|
+
);
|
|
548
|
+
|
|
549
|
+
const parsed = parseWorkflow(generator._buildCIWorkflow());
|
|
550
|
+
const lighthouseStep = parsed.jobs.lighthouse.steps.find((step) => step.name === 'Run Lighthouse on build output');
|
|
551
|
+
|
|
552
|
+
assert.equal(lighthouseStep.with.configPath, './.lighthouserc.json');
|
|
553
|
+
});
|
|
554
|
+
|
|
497
555
|
test('E2E jobs fall back to existing jobs instead of depending on a missing build job', () => {
|
|
498
556
|
const projectDir = makeTempDir();
|
|
499
557
|
const generator = new WorkflowGenerator(
|
|
@@ -560,7 +618,7 @@ test('Netlify preview configuration uses the detected production branch instead
|
|
|
560
618
|
assert.equal(previewStep.with['production-branch'], 'release');
|
|
561
619
|
});
|
|
562
620
|
|
|
563
|
-
test('Preview deploy jobs
|
|
621
|
+
test('Preview deploy jobs run for same-repo pull requests, including Dependabot PRs', () => {
|
|
564
622
|
const projectDir = makeTempDir();
|
|
565
623
|
writeFiles(projectDir, {
|
|
566
624
|
'package.json': json({
|
|
@@ -582,11 +640,13 @@ test('Preview deploy jobs only run for same-repo pull requests with secrets acce
|
|
|
582
640
|
|
|
583
641
|
const deploy = generator.generate().find((workflow) => workflow.filename === 'deploy.yml');
|
|
584
642
|
const parsed = parseWorkflow(deploy.content);
|
|
643
|
+
const commentStep = parsed.jobs.preview.steps.find((step) => step.name === 'Comment PR');
|
|
585
644
|
|
|
586
645
|
assert.equal(
|
|
587
646
|
parsed.jobs.preview.if,
|
|
588
|
-
"github.event_name == 'pull_request' && github.
|
|
647
|
+
"github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository"
|
|
589
648
|
);
|
|
649
|
+
assert.equal(commentStep.if, "always() && github.actor != 'dependabot[bot]'");
|
|
590
650
|
});
|
|
591
651
|
|
|
592
652
|
test('Generic JavaScript builds no longer upload a fake dist artifact when no build directory is known', () => {
|