Skip to content

Commit 0880d72

Browse files
Copilotneilime
andcommitted
feat(continuous-integration)!: add configurable lint/test commands and container better support
Co-authored-by: neilime <314088+neilime@users.noreply.github.com> Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
1 parent ce2bb82 commit 0880d72

File tree

12 files changed

+577
-272
lines changed

12 files changed

+577
-272
lines changed

.github/linters/actionlint.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ paths:
88
- '"env" section must be mapping node but got scalar node'
99
- '"ports" section must be sequence node but got scalar node'
1010
- '"volumes" section must be sequence node but got scalar node'
11+
- '"runs-on" section is alias node but mapping node is expected'

.github/workflows/__test-workflow-continuous-integration.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ jobs:
1111
uses: ./.github/workflows/continuous-integration.yml
1212
permissions:
1313
contents: read
14+
packages: read
1415
pull-requests: write
1516
security-events: write
1617
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
@@ -41,6 +42,7 @@ jobs:
4142
uses: ./.github/workflows/continuous-integration.yml
4243
permissions:
4344
contents: read
45+
packages: read
4446
pull-requests: write
4547
security-events: write
4648
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
@@ -82,6 +84,7 @@ jobs:
8284
needs: arrange-with-container
8385
permissions:
8486
contents: read
87+
packages: read
8588
pull-requests: write
8689
security-events: write
8790
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
@@ -116,6 +119,7 @@ jobs:
116119
needs: arrange-with-container
117120
permissions:
118121
contents: read
122+
packages: read
119123
pull-requests: write
120124
security-events: write
121125
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659

.github/workflows/continuous-integration.md

Lines changed: 96 additions & 51 deletions
Large diffs are not rendered by default.

.github/workflows/continuous-integration.yml

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,17 @@ on:
6060
required: false
6161
default: "true"
6262
code-ql:
63-
description: "Code QL analysis language. See <https://github.com/github/codeql-action>."
63+
description: |
64+
Code QL analysis language.
65+
See https://github.com/github/codeql-action.
6466
type: string
6567
required: false
6668
default: "typescript"
6769
dependency-review:
68-
description: "Enable dependency review scan. See <https://github.com/actions/dependency-review-action>."
70+
description: |
71+
Enable dependency review scan.
72+
Works with public repositories and private repositories with a GitHub Advanced Security license.
73+
See https://github.com/actions/dependency-review-action.
6974
type: boolean
7075
required: false
7176
default: true
@@ -88,11 +93,13 @@ on:
8893
Accepts either a string (container image name) or a JSON object with container options.
8994
9095
String format (simple):
96+
9197
```yml
9298
container: "node:18"
9399
```
94100
95101
JSON object format (advanced):
102+
96103
```json
97104
{
98105
"image": "node:18",
@@ -133,6 +140,11 @@ on:
133140
Used when the container image is hosted in a private registry.
134141
See https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container#defining-credentials-for-a-container-registry.
135142
required: false
143+
github-token:
144+
description: |
145+
GitHub token to use for authentication.
146+
Defaults to `GITHUB_TOKEN` if not provided.
147+
required: false
136148
outputs:
137149
build-artifact-id:
138150
description: "ID of the build artifact) uploaded during the build step."
@@ -143,7 +155,7 @@ permissions: {}
143155
jobs:
144156
prepare:
145157
name: 📦 Prepare configuration
146-
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
158+
runs-on: &ci-runner ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
147159
permissions: {}
148160
outputs:
149161
container-image: ${{ steps.parse.outputs.container-image }}
@@ -177,8 +189,8 @@ jobs:
177189
try {
178190
const parsedContainer = JSON.parse(containerInput);
179191
core.debug(`Parsed container input as JSON: ${JSON.stringify(parsedContainer)}`);
180-
container = {
181-
...container,
192+
container = {
193+
...container,
182194
...parsedContainer,
183195
options: `${container.options} ${parsedContainer.options || ''}`.trim()
184196
};
@@ -228,7 +240,7 @@ jobs:
228240
if: inputs.checks == true && inputs.code-ql != ''
229241
permissions:
230242
security-events: write
231-
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
243+
runs-on: *ci-runner
232244
steps:
233245
- uses: hoverkraft-tech/ci-github-common/actions/checkout@d95c78dc4b10250a07e227d3ddf33b0ea093e28d # 0.29.0
234246
- uses: github/codeql-action/init@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
@@ -241,32 +253,35 @@ jobs:
241253
if: github.event_name == 'pull_request' && inputs.checks == true && inputs.dependency-review
242254
permissions:
243255
contents: read
244-
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
256+
runs-on: *ci-runner
245257
steps:
246258
- uses: hoverkraft-tech/ci-github-common/actions/checkout@d95c78dc4b10250a07e227d3ddf33b0ea093e28d # 0.29.0
247259
- uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
248260

249261
setup:
250262
name: ⚙️ Setup
251-
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
252-
needs: prepare
253-
container: &container-setup
263+
runs-on: *ci-runner
264+
needs:
265+
- prepare
266+
permissions:
267+
contents: read
268+
packages: read
269+
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
270+
id-token: write
271+
container: &ci-container
254272
image: ${{ needs.prepare.outputs.container-image || '' }}
255273
env: ${{ fromJSON(needs.prepare.outputs.container-env || '{}') }}
256274
options: ${{ needs.prepare.outputs.container-options || ' ' }}
257275
ports: ${{ fromJSON(needs.prepare.outputs.container-ports || '[]') }}
258276
volumes: ${{ fromJSON(needs.prepare.outputs.container-volumes || '[]') }}
259277
credentials: ${{ fromJSON(needs.prepare.outputs.container-username && format('{{"username":{0},"password":{1}}}',toJSON(needs.prepare.outputs.container-username),toJSON(secrets.container-password)) || '{}') }}
260-
permissions:
261-
contents: read
262-
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
263-
id-token: write
264278
outputs:
265279
build-env: ${{ steps.build-variables.outputs.env }}
266280
build-commands: ${{ steps.build-variables.outputs.commands }}
267281
build-artifact: ${{ steps.build-variables.outputs.artifact }}
268282
steps:
269-
- if: needs.prepare.outputs.container-image == null
283+
- name: Checkout repository
284+
if: inputs.container == ''
270285
uses: hoverkraft-tech/ci-github-common/actions/checkout@d95c78dc4b10250a07e227d3ddf33b0ea093e28d # 0.29.0
271286

272287
- id: build-variables
@@ -369,21 +384,21 @@ jobs:
369384
core.setOutput('env', JSON.stringify(env));
370385
371386
lint:
387+
if: ${{ inputs.checks == true && inputs.lint }}
372388
name: 👕 Lint
373-
if: inputs.checks == true && inputs.lint
389+
runs-on: *ci-runner
390+
container: *ci-container
374391
needs:
375392
- prepare
376393
- setup
377-
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
378-
container: *container-setup
379-
# jscpd:ignore-start
380394
permissions:
381395
contents: read
396+
packages: read
382397
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
383398
id-token: write
384399
steps:
385400
- uses: hoverkraft-tech/ci-github-common/actions/checkout@d95c78dc4b10250a07e227d3ddf33b0ea093e28d # 0.29.0
386-
if: needs.prepare.outputs.container-image == null
401+
if: inputs.container == ''
387402

388403
- id: oidc
389404
uses: ChristopherHX/oidc@73eee1ff03fdfce10eda179f617131532209edbd # v3
@@ -397,7 +412,7 @@ jobs:
397412
- run: |
398413
if [ -f .gitignore ]; then grep -q "self-workflow" .gitignore || echo "self-workflow" >> .gitignore; else echo "self-workflow" >> .gitignore; fi
399414
if [ -f .dockerignore ]; then grep -q "self-workflow" .dockerignore || echo "self-workflow" >> .dockerignore; else echo "self-workflow" >> .dockerignore; fi
400-
# jscpd:ignore-end
415+
401416
- id: preparel-lint-options
402417
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
403418
env:
@@ -417,29 +432,35 @@ jobs:
417432
}
418433
}
419434
420-
- uses: ./self-workflow/actions/lint
435+
core.setOutput('command', lintOptions.command || 'lint:ci');
436+
core.setOutput('report-file', lintOptions['report-file'] || '');
437+
438+
- name: Run lint
439+
uses: ./self-workflow/actions/lint
421440
with:
422441
working-directory: ${{ inputs.working-directory }}
423-
container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }}
442+
container: ${{ inputs.container != '' && 'true' || 'false' }}
443+
command: ${{ steps.preparel-lint-options.outputs.command }}
444+
report-file: ${{ steps.preparel-lint-options.outputs.report-file }}
424445

425446
build:
447+
if: ${{ inputs.checks == true }}
426448
name: 🏗️ Build
427-
if: inputs.checks == true
428-
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
429-
container: *container-setup
430-
# jscpd:ignore-start
449+
runs-on: *ci-runner
450+
container: *ci-container
431451
needs:
432452
- prepare
433453
- setup
434454
permissions:
435455
contents: read
456+
packages: read
436457
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
437458
id-token: write
438459
outputs:
439460
artifact-id: ${{ steps.build.outputs.artifact-id }}
440461
steps:
441462
- uses: hoverkraft-tech/ci-github-common/actions/checkout@d95c78dc4b10250a07e227d3ddf33b0ea093e28d # 0.29.0
442-
if: needs.setup.outputs.build-commands && needs.prepare.outputs.container-image == null
463+
if: needs.setup.outputs.build-commands && inputs.container == ''
443464

444465
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
445466
- id: oidc
@@ -457,37 +478,38 @@ jobs:
457478
run: |
458479
if [ -f .gitignore ]; then grep -q "self-workflow" .gitignore || echo "self-workflow" >> .gitignore; else echo "self-workflow" >> .gitignore; fi
459480
if [ -f .dockerignore ]; then grep -q "self-workflow" .dockerignore || echo "self-workflow" >> .dockerignore; else echo "self-workflow" >> .dockerignore; fi
460-
# jscpd:ignore-end
481+
461482
- id: build
462483
if: needs.setup.outputs.build-commands
463484
uses: ./self-workflow/actions/build
464485
with:
486+
container: ${{ inputs.container != '' && 'true' || 'false' }}
465487
working-directory: ${{ inputs.working-directory }}
488+
build-secrets: ${{ secrets.build-secrets }}
466489
build-commands: ${{ needs.setup.outputs.build-commands }}
467490
build-env: ${{ needs.setup.outputs.build-env }}
468-
build-secrets: ${{ secrets.build-secrets }}
469491
build-artifact: ${{ needs.setup.outputs.build-artifact }}
470-
container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }}
471492

472493
test:
494+
if: ${{ inputs.checks == true && inputs.test }}
473495
name: 🧪 Test
474-
if: inputs.checks == true && inputs.test
475-
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
476-
container: *container-setup
496+
runs-on: *ci-runner
497+
container: *ci-container
477498
needs:
478499
- prepare
479500
- setup
480501
- build
481502
permissions:
482503
contents: read
483504
pull-requests: write
505+
packages: read
484506
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
485507
id-token: write
486508
steps:
487509
- uses: hoverkraft-tech/ci-github-common/actions/checkout@d95c78dc4b10250a07e227d3ddf33b0ea093e28d # 0.29.0
488-
if: needs.prepare.outputs.container-image == null
510+
if: inputs.container == ''
489511

490-
- if: needs.build.outputs.artifact-id && needs.prepare.outputs.container-image == null
512+
- if: needs.build.outputs.artifact-id && inputs.container == ''
491513
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
492514
with:
493515
artifact-ids: ${{ needs.build.outputs.artifact-id }}
@@ -530,13 +552,15 @@ jobs:
530552
testOptions.coverage = 'github';
531553
}
532554
core.setOutput('coverage', testOptions.coverage );
533-
534555
core.setOutput('coverage-files', testOptions['coverage-files'] || '');
556+
core.setOutput('command', testOptions.command || 'test:ci');
535557
536-
- uses: ./self-workflow/actions/test
558+
- name: Run tests
559+
uses: ./self-workflow/actions/test
537560
with:
538561
working-directory: ${{ inputs.working-directory }}
539-
container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }}
562+
container: ${{ inputs.container != '' && 'true' || 'false' }}
563+
command: ${{ steps.prepare-test-options.outputs.command }}
540564
coverage: ${{ steps.prepare-test-options.outputs.coverage }}
541565
coverage-files: ${{ steps.prepare-test-options.outputs.coverage-files }}
542-
github-token: ${{ github.token }}
566+
github-token: ${{ secrets.github-token || github.token }}

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ _Actions for continuous integration steps: build, lint, and test._
2828

2929
#### - [Test](actions/test/README.md)
3030

31+
#### - [Rewrite Report Paths](actions/rewrite-report-paths/README.md)
32+
3133
### Dependencies
3234

3335
_Actions dedicated to caching and validating Node.js dependencies._

actions/lint/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ Action to lint Node.js projects with support for pull request reporting and anno
4242
# Default: `false`
4343
container: "false"
4444

45+
# NPM/package manager script command to run for linting.
46+
# This should be a script defined in your package.json.
47+
# The command should generate lint report files in a standard format (ESLint JSON or Checkstyle XML).
48+
#
49+
# Default: `lint:ci`
50+
command: "lint:ci"
51+
4552
# Path to lint report file to process as GitHub annotations.
4653
# Supports ESLint JSON and Checkstyle XML formats.
4754
# If not specified, auto-detection will be attempted for common paths:
@@ -60,6 +67,9 @@ Action to lint Node.js projects with support for pull request reporting and anno
6067
| **`working-directory`** | Working directory where lint commands are executed. | **false** | `.` |
6168
| | Can be absolute or relative to the repository root. | | |
6269
| **`container`** | Whether running in container mode (skips checkout and node setup) | **false** | `false` |
70+
| **`command`** | NPM/package manager script command to run for linting. | **false** | `lint:ci` |
71+
| | This should be a script defined in your package.json. | | |
72+
| | The command should generate lint report files in a standard format. | | |
6373
| **`report-file`** | Path to lint report file to process as GitHub annotations. | **false** | - |
6474
| | Supports ESLint JSON and Checkstyle XML formats. | | |
6575
| | If not specified, auto-detection will be attempted for common paths: | | |

0 commit comments

Comments
 (0)