Skip to content

Commit d53eede

Browse files
Copilotneilime
andcommitted
docs: add yml syntax highlighting to code block
Co-authored-by: neilime <[email protected]> Signed-off-by: Emilien Escalle <[email protected]>
1 parent 893f457 commit d53eede

File tree

3 files changed

+84
-49
lines changed

3 files changed

+84
-49
lines changed

.github/linters/actionlint.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# FIXME: Temporary ignores to bypass actionlint limitations. See https://github.com/rhysd/actionlint/issues/590.
2+
paths:
3+
.github/workflows/continuous-integration.yml:
4+
ignore:
5+
- 'both "username" and "password" must be specified in "credentials" section'
6+
- '"credentials" section is scalar node but mapping node is expected'
7+
- '"container" section is alias node but mapping node is expected'

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@ jobs:
128128
"NODE_ENV": "test",
129129
"CI": "true"
130130
},
131-
"options": "--cpus 1"
131+
"options": "--cpus 1",
132+
"credentials": {
133+
"username": "${{ github.actor }}"
134+
}
132135
}
133136
working-directory: /usr/src/app/
134137
build: |
@@ -137,6 +140,8 @@ jobs:
137140
}
138141
test: |
139142
{"coverage": "codecov"}
143+
secrets:
144+
container-password: ${{ secrets.GITHUB_TOKEN }}
140145

141146
assert-with-container-advanced:
142147
name: Assert - Ensure build artifact has been uploaded (with container advanced)

.github/workflows/continuous-integration.yml

Lines changed: 71 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ on:
8888
Accepts either a string (container image name) or a JSON object with container options.
8989
9090
String format (simple):
91-
```
91+
```yml
9292
container: "node:18"
9393
```
9494
@@ -123,6 +123,12 @@ on:
123123
SECRET_EXAMPLE=$\{{ secrets.SECRET_EXAMPLE }}
124124
```
125125
required: false
126+
container-password:
127+
description: |
128+
Password for container registry authentication, if required.
129+
Used when the container image is hosted in a private registry.
130+
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.
131+
required: false
126132
outputs:
127133
build-artifact-id:
128134
description: "ID of the build artifact) uploaded during the build step."
@@ -131,56 +137,72 @@ on:
131137
permissions: {}
132138

133139
jobs:
134-
parse-container:
135-
name: 📦 Parse Container Configuration
136-
if: inputs.container != ''
140+
prepare:
141+
name: 📦 Prepare configuration
137142
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
138143
permissions: {}
139144
outputs:
140-
config: ${{ steps.parse.outputs.config }}
145+
container-image: ${{ steps.parse.outputs.container-image }}
146+
container-options: ${{ steps.parse.outputs.container-options }}
147+
container-username: ${{ steps.parse.outputs.container-username }}
141148
steps:
142149
- id: parse
143150
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
144151
env:
145152
CONTAINER_INPUT: ${{ inputs.container }}
153+
CONTAINER_PASSWORD: ${{ secrets.container-password }}
146154
with:
147155
script: |
148156
const containerInput = process.env.CONTAINER_INPUT.trim();
157+
if (!containerInput) {
158+
return;
159+
}
160+
core.debug(`Container input: ${containerInput}`);
149161
150162
// Check if input is a JSON object or a simple string
151163
const isJson = containerInput.startsWith('{');
152164
153-
let config = {
154-
image: '',
165+
let container = {
155166
options: '--user root:root'
156167
};
157168
158169
if (isJson) {
159170
try {
160-
const container = JSON.parse(containerInput);
161-
162-
// Set image
163-
config.image = container.image || '';
164-
165-
// Add env if provided
166-
if (container.env && Object.keys(container.env).length > 0) {
167-
config.env = container.env;
168-
}
169-
170-
// Merge user options with default --user root:root
171-
if (container.options) {
172-
config.options = `${config.options} ${container.options}`;
173-
}
171+
const parsedContainer = JSON.parse(containerInput);
172+
core.debug(`Parsed container input as JSON: ${JSON.stringify(parsedContainer)}`);
173+
container = {
174+
...container,
175+
...parsedContainer,
176+
options: `${container.options} ${parsedContainer.options || ''}`.trim()
177+
};
178+
174179
} catch (error) {
175-
core.setFailed(`Failed to parse container input as JSON: ${error.message}`);
176-
return;
180+
return core.setFailed(`Failed to parse container input as JSON: ${error.message}`,{ cause: error });
177181
}
178182
} else {
179183
// Simple string format - just the image name
180-
config.image = containerInput;
184+
container.image = containerInput;
181185
}
182186
183-
core.setOutput('config', JSON.stringify(config));
187+
core.debug(`Parsed container configuration: ${JSON.stringify(container)}`);
188+
189+
if (!container.image) {
190+
return core.setFailed('Container image must be specified in the container input.');
191+
}
192+
core.setOutput('container-image', container.image);
193+
194+
if (container.options) {
195+
core.setOutput('container-options', container.options);
196+
}
197+
198+
if (container.credentials?.username) {
199+
core.setOutput('container-username', container.credentials.username);
200+
if (!process.env.CONTAINER_PASSWORD) {
201+
return core.setFailed('Container password must be provided when container credentials username is specified.');
202+
}
203+
} else if (process.env.CONTAINER_PASSWORD) {
204+
return core.setFailed('Container credentials username must be provided when container password is specified.');
205+
}
184206
185207
code-ql:
186208
name: 🛡️ CodeQL Analysis
@@ -208,9 +230,11 @@ jobs:
208230
setup:
209231
name: ⚙️ Setup
210232
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
211-
container: ${{ inputs.container != '' && fromJSON(needs.parse-container.outputs.config) || null }}
212-
needs: parse-container
213-
if: ${{ always() && !cancelled() && !failure() }}
233+
needs: prepare
234+
container: &container-setup
235+
image: ${{ needs.prepare.outputs.container-image || '' }}
236+
options: ${{ needs.prepare.outputs.container-options || ' ' }}
237+
credentials: ${{ fromJSON(needs.prepare.outputs.container-username && format('{{"username":{0},"password":{1}}}',toJSON(needs.prepare.outputs.container-username),toJSON(secrets.container-password)) || '{}') }}
214238
permissions:
215239
contents: read
216240
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
@@ -220,7 +244,7 @@ jobs:
220244
build-commands: ${{ steps.build-variables.outputs.commands }}
221245
build-artifact: ${{ steps.build-variables.outputs.artifact }}
222246
steps:
223-
- if: inputs.container == ''
247+
- if: needs.prepare.outputs.container-image == null
224248
uses: hoverkraft-tech/ci-github-common/actions/checkout@753288393de1f3d92f687a6761d236ca800f5306 # 0.28.1
225249

226250
- id: build-variables
@@ -324,22 +348,21 @@ jobs:
324348
325349
lint:
326350
name: 👕 Lint
327-
if: inputs.checks == true && inputs.lint && always() && !cancelled() && !failure()
328-
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
329-
container: ${{ inputs.container != '' && fromJSON(needs.parse-container.outputs.config) || null }}
351+
if: inputs.checks == true && inputs.lint
330352
needs:
331-
- parse-container
353+
- prepare
332354
- setup
355+
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
356+
container: *container-setup
333357
# jscpd:ignore-start
334358
permissions:
335359
contents: read
336360
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
337361
id-token: write
338362
steps:
339363
- uses: hoverkraft-tech/ci-github-common/actions/checkout@753288393de1f3d92f687a6761d236ca800f5306 # 0.28.1
340-
if: inputs.container == ''
364+
if: needs.prepare.outputs.container-image == null
341365

342-
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
343366
- id: oidc
344367
uses: ChristopherHX/oidc@73eee1ff03fdfce10eda179f617131532209edbd # v3
345368
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@@ -375,16 +398,16 @@ jobs:
375398
- uses: ./self-workflow/actions/lint
376399
with:
377400
working-directory: ${{ inputs.working-directory }}
378-
container: ${{ inputs.container != '' }}
401+
container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }}
379402

380403
build:
381404
name: 🏗️ Build
382-
if: inputs.checks == true && always() && !cancelled() && !failure()
405+
if: inputs.checks == true
383406
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
407+
container: *container-setup
384408
# jscpd:ignore-start
385-
container: ${{ inputs.container != '' && fromJSON(needs.parse-container.outputs.config) || null }}
386409
needs:
387-
- parse-container
410+
- prepare
388411
- setup
389412
permissions:
390413
contents: read
@@ -394,7 +417,7 @@ jobs:
394417
artifact-id: ${{ steps.build.outputs.artifact-id }}
395418
steps:
396419
- uses: hoverkraft-tech/ci-github-common/actions/checkout@753288393de1f3d92f687a6761d236ca800f5306 # 0.28.1
397-
if: needs.setup.outputs.build-commands && inputs.container == ''
420+
if: needs.setup.outputs.build-commands && needs.prepare.outputs.container-image == null
398421

399422
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
400423
- id: oidc
@@ -422,15 +445,15 @@ jobs:
422445
build-env: ${{ needs.setup.outputs.build-env }}
423446
build-secrets: ${{ secrets.build-secrets }}
424447
build-artifact: ${{ needs.setup.outputs.build-artifact }}
425-
container: ${{ inputs.container != '' }}
448+
container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }}
426449

427450
test:
428451
name: 🧪 Test
429-
if: inputs.checks == true && inputs.test && always() && !cancelled() && !failure()
452+
if: inputs.checks == true && inputs.test
430453
runs-on: ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
431-
container: ${{ inputs.container != '' && fromJSON(needs.parse-container.outputs.config) || null }}
454+
container: *container-setup
432455
needs:
433-
- parse-container
456+
- prepare
434457
- setup
435458
- build
436459
permissions:
@@ -440,9 +463,9 @@ jobs:
440463
id-token: write
441464
steps:
442465
- uses: hoverkraft-tech/ci-github-common/actions/checkout@753288393de1f3d92f687a6761d236ca800f5306 # 0.28.1
443-
if: inputs.container == ''
466+
if: needs.prepare.outputs.container-image == null
444467

445-
- if: needs.build.outputs.artifact-id && inputs.container == ''
468+
- if: needs.build.outputs.artifact-id && needs.prepare.outputs.container-image == null
446469
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
447470
with:
448471
artifact-ids: ${{ needs.build.outputs.artifact-id }}
@@ -491,7 +514,7 @@ jobs:
491514
- uses: ./self-workflow/actions/test
492515
with:
493516
working-directory: ${{ inputs.working-directory }}
494-
container: ${{ inputs.container != '' }}
517+
container: ${{ needs.prepare.outputs.container-image && 'true' || 'false' }}
495518
coverage: ${{ steps.prepare-test-options.outputs.coverage }}
496-
coverage-files: ${{ steps.prepare-test-options.outputs['coverage-files'] }}
519+
coverage-files: ${{ steps.prepare-test-options.outputs.coverage-files }}
497520
github-token: ${{ github.token }}

0 commit comments

Comments
 (0)