Skip to content

Commit 811a849

Browse files
Copilotneilime
andcommitted
Add container input to continuous-integration workflow
Co-authored-by: neilime <314088+neilime@users.noreply.github.com>
1 parent 74e2f14 commit 811a849

2 files changed

Lines changed: 101 additions & 18 deletions

File tree

.github/workflows/continuous-integration.md

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ jobs:
8787
# Working directory where the dependencies are installed.
8888
# Default: `.`
8989
working-directory: .
90+
91+
# Docker container image to run CI steps in. When specified, steps will execute inside this container instead of checking out code.
92+
# The container should have the project code and dependencies pre-installed.
93+
# Default: `` (empty, uses local checkout)
94+
container: ""
9095
```
9196
9297
<!-- usage:end -->
@@ -97,16 +102,17 @@ jobs:
97102
98103
### Workflow Call Inputs
99104
100-
| **Input** | **Description** | **Required** | **Type** | **Default** |
101-
| ----------------------- | ----------------------------------------------------------------------------------------- | ------------ | ----------- | ------------ |
102-
| **`build`** | Build parameters. Must be a string or a JSON object. | **false** | **string** | `build` |
103-
| **`checks`** | Optional flag to enable check steps. | **false** | **boolean** | `true` |
104-
| **`lint`** | Optional flag to enable linting. | **false** | **boolean** | `true` |
105-
| **`code-ql`** | Code QL analysis language. See <https://github.com/github/codeql-action>. | **false** | **string** | `typescript` |
106-
| **`dependency-review`** | Enable dependency review scan. See <https://github.com/actions/dependency-review-action>. | **false** | **boolean** | `true` |
107-
| **`test`** | Optional flag to enable test. | **false** | **boolean** | `true` |
108-
| **`coverage`** | Specifify code coverage reporter. Supported values: `codecov`. | **false** | **string** | `codecov` |
109-
| **`working-directory`** | Working directory where the dependencies are installed. | **false** | **string** | `.` |
105+
| **Input** | **Description** | **Required** | **Type** | **Default** |
106+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | ----------- | ------------ |
107+
| **`build`** | Build parameters. Must be a string or a JSON object. | **false** | **string** | `build` |
108+
| **`checks`** | Optional flag to enable check steps. | **false** | **boolean** | `true` |
109+
| **`lint`** | Optional flag to enable linting. | **false** | **boolean** | `true` |
110+
| **`code-ql`** | Code QL analysis language. See <https://github.com/github/codeql-action>. | **false** | **string** | `typescript` |
111+
| **`dependency-review`** | Enable dependency review scan. See <https://github.com/actions/dependency-review-action>. | **false** | **boolean** | `true` |
112+
| **`test`** | Optional flag to enable test. | **false** | **boolean** | `true` |
113+
| **`coverage`** | Specifify code coverage reporter. Supported values: `codecov`. | **false** | **string** | `codecov` |
114+
| **`working-directory`** | Working directory where the dependencies are installed. | **false** | **string** | `.` |
115+
| **`container`** | Docker container image to run CI steps in. When specified, steps will execute inside this container instead of checking out code. The container should have the project code and dependencies pre-installed. | **false** | **string** | `` |
110116

111117
<!-- inputs:end -->
112118

@@ -168,6 +174,54 @@ jobs:
168174
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
169175
```
170176

177+
### Continuous Integration in a Docker container
178+
179+
This example runs CI checks inside a pre-built Docker container that contains the project code and dependencies. This ensures the same environment that will be deployed to production is tested.
180+
181+
```yaml
182+
name: Continuous Integration - Container Mode
183+
184+
on:
185+
push:
186+
branches: [main]
187+
188+
jobs:
189+
# Build the Docker image with project code and dependencies
190+
build-image:
191+
runs-on: ubuntu-latest
192+
steps:
193+
- name: Checkout
194+
uses: actions/checkout@v4.2.2
195+
196+
- name: Build Docker image
197+
run: |
198+
docker build -t my-app:${{ github.sha }} .
199+
200+
- name: Push to registry
201+
run: |
202+
docker tag my-app:${{ github.sha }} ghcr.io/${{ github.repository }}:${{ github.sha }}
203+
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
204+
205+
# Run CI checks inside the Docker container
206+
continuous-integration:
207+
needs: build-image
208+
uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@6809332ced7647b3d52300a47d65657283f3395e # 0.16.0
209+
permissions:
210+
id-token: write
211+
security-events: write
212+
contents: read
213+
with:
214+
container: ghcr.io/${{ github.repository }}:${{ github.sha }}
215+
# When using container mode, code-ql and dependency-review are typically disabled
216+
# as they require repository checkout
217+
code-ql: ""
218+
dependency-review: false
219+
# Specify which build/test commands to run (they should exist in package.json)
220+
build: "" # Skip build as it was done in the Docker image
221+
lint: true
222+
test: true
223+
```
224+
171225
<!-- examples:end -->
172226

173227
<!-- contributing:start -->

.github/workflows/continuous-integration.yml

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ on:
5050
type: string
5151
required: false
5252
default: "."
53+
container:
54+
description: "Docker container image to run CI steps in. When specified, steps will execute inside this container instead of checking out code. The container should have the project code and dependencies pre-installed."
55+
type: string
56+
required: false
57+
default: ""
5358

5459
permissions:
5560
contents: read
@@ -84,6 +89,7 @@ jobs:
8489
setup:
8590
name: ⚙️ Setup
8691
runs-on: "ubuntu-latest"
92+
container: ${{ inputs.container != '' && inputs.container || null }}
8793
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
8894
permissions:
8995
contents: read
@@ -93,12 +99,15 @@ jobs:
9399
build-artifact: ${{ steps.build-variables.outputs.artifact }}
94100
steps:
95101
- uses: hoverkraft-tech/ci-github-common/actions/checkout@b7dd413209df265bef8d7eb0efb117eaabc684c4 # 0.27.0
102+
if: inputs.container == ''
96103

97104
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
98105
# jscpd:ignore-start
99106
- id: oidc
107+
if: inputs.container == ''
100108
uses: ChristopherHX/oidc@73eee1ff03fdfce10eda179f617131532209edbd # v3
101109
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
110+
if: inputs.container == ''
102111
with:
103112
path: ./self-workflow
104113
repository: ${{ steps.oidc.outputs.job_workflow_repo_name_and_owner }}
@@ -108,8 +117,10 @@ jobs:
108117
- run: |
109118
if [ -f .gitignore ]; then grep -q "self-workflow" .gitignore || echo "self-workflow" >> .gitignore; else echo "self-workflow" >> .gitignore; fi
110119
if [ -f .dockerignore ]; then grep -q "self-workflow" .dockerignore || echo "self-workflow" >> .dockerignore; else echo "self-workflow" >> .dockerignore; fi
120+
if: inputs.container == ''
111121
# jscpd:ignore-end
112122
- id: setup-node
123+
if: inputs.container == ''
113124
uses: ./self-workflow/actions/setup-node
114125
with:
115126
working-directory: ${{ inputs.working-directory }}
@@ -164,6 +175,7 @@ jobs:
164175
name: 👕 Lint
165176
if: inputs.checks == true && inputs.lint != false
166177
runs-on: "ubuntu-latest"
178+
container: ${{ inputs.container != '' && inputs.container || null }}
167179
needs: setup
168180
# jscpd:ignore-start
169181
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
@@ -172,11 +184,14 @@ jobs:
172184
id-token: write
173185
steps:
174186
- uses: hoverkraft-tech/ci-github-common/actions/checkout@b7dd413209df265bef8d7eb0efb117eaabc684c4 # 0.27.0
187+
if: inputs.container == ''
175188

176189
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
177190
- id: oidc
191+
if: inputs.container == ''
178192
uses: ChristopherHX/oidc@73eee1ff03fdfce10eda179f617131532209edbd # v3
179193
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
194+
if: inputs.container == ''
180195
with:
181196
path: ./self-workflow
182197
repository: ${{ steps.oidc.outputs.job_workflow_repo_name_and_owner }}
@@ -186,22 +201,25 @@ jobs:
186201
- run: |
187202
if [ -f .gitignore ]; then grep -q "self-workflow" .gitignore || echo "self-workflow" >> .gitignore; else echo "self-workflow" >> .gitignore; fi
188203
if [ -f .dockerignore ]; then grep -q "self-workflow" .dockerignore || echo "self-workflow" >> .dockerignore; else echo "self-workflow" >> .dockerignore; fi
204+
if: inputs.container == ''
189205
# jscpd:ignore-end
190206
- id: setup-node
207+
if: inputs.container == ''
191208
uses: ./self-workflow/actions/setup-node
192209
with:
193210
working-directory: ${{ inputs.working-directory }}
194211
dependencies-cache: |
195212
nx
196213
prettier
197214
198-
- run: ${{ steps.setup-node.outputs.run-script-command }} lint
215+
- run: ${{ inputs.container != '' && 'npm run lint' || steps.setup-node.outputs.run-script-command }} lint
199216
working-directory: ${{ inputs.working-directory }}
200217

201218
build:
202219
name: 🏗️ Build
203220
if: inputs.checks == true
204221
runs-on: "ubuntu-latest"
222+
container: ${{ inputs.container != '' && inputs.container || null }}
205223
needs: setup
206224
# jscpd:ignore-start
207225
permissions:
@@ -210,14 +228,14 @@ jobs:
210228
id-token: write
211229
steps:
212230
- uses: hoverkraft-tech/ci-github-common/actions/checkout@b7dd413209df265bef8d7eb0efb117eaabc684c4 # 0.27.0
213-
if: needs.setup.outputs.build-commands
231+
if: needs.setup.outputs.build-commands && inputs.container == ''
214232

215233
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
216234
- id: oidc
217-
if: needs.setup.outputs.build-commands
235+
if: needs.setup.outputs.build-commands && inputs.container == ''
218236
uses: ChristopherHX/oidc@73eee1ff03fdfce10eda179f617131532209edbd # v3
219237
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
220-
if: needs.setup.outputs.build-commands
238+
if: needs.setup.outputs.build-commands && inputs.container == ''
221239
with:
222240
path: ./self-workflow
223241
repository: ${{ steps.oidc.outputs.job_workflow_repo_name_and_owner }}
@@ -227,9 +245,10 @@ jobs:
227245
- run: |
228246
if [ -f .gitignore ]; then grep -q "self-workflow" .gitignore || echo "self-workflow" >> .gitignore; else echo "self-workflow" >> .gitignore; fi
229247
if [ -f .dockerignore ]; then grep -q "self-workflow" .dockerignore || echo "self-workflow" >> .dockerignore; else echo "self-workflow" >> .dockerignore; fi
248+
if: inputs.container == ''
230249
# jscpd:ignore-end
231250
- id: setup-node
232-
if: needs.setup.outputs.build-commands
251+
if: needs.setup.outputs.build-commands && inputs.container == ''
233252
uses: ./self-workflow/actions/setup-node
234253
with:
235254
working-directory: ${{ inputs.working-directory }}
@@ -253,7 +272,11 @@ jobs:
253272
fi
254273
255274
echo -e "\n - Running $COMMAND"
256-
${{ steps.setup-node.outputs.run-script-command }} "$COMMAND"
275+
if [ "${{ inputs.container }}" != "" ]; then
276+
npm run "$COMMAND"
277+
else
278+
${{ steps.setup-node.outputs.run-script-command }} "$COMMAND"
279+
fi
257280
done
258281
259282
- if: needs.setup.outputs.build-commands && needs.setup.outputs.build-artifact
@@ -266,6 +289,7 @@ jobs:
266289
name: 🧪 Test
267290
if: inputs.checks == true && inputs.test == true
268291
runs-on: "ubuntu-latest"
292+
container: ${{ inputs.container != '' && inputs.container || null }}
269293
needs:
270294
- setup
271295
- build
@@ -275,16 +299,19 @@ jobs:
275299
id-token: write
276300
steps:
277301
- uses: hoverkraft-tech/ci-github-common/actions/checkout@b7dd413209df265bef8d7eb0efb117eaabc684c4 # 0.27.0
302+
if: inputs.container == ''
278303

279-
- if: needs.setup.outputs.build-artifact
304+
- if: needs.setup.outputs.build-artifact && inputs.container == ''
280305
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
281306
with:
282307
name: build
283308
path: "/"
284309
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
285310
- id: oidc
311+
if: inputs.container == ''
286312
uses: ChristopherHX/oidc@73eee1ff03fdfce10eda179f617131532209edbd # v3
287313
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
314+
if: inputs.container == ''
288315
with:
289316
path: ./self-workflow
290317
repository: ${{ steps.oidc.outputs.job_workflow_repo_name_and_owner }}
@@ -294,16 +321,18 @@ jobs:
294321
- run: |
295322
if [ -f .gitignore ]; then grep -q "self-workflow" .gitignore || echo "self-workflow" >> .gitignore; else echo "self-workflow" >> .gitignore; fi
296323
if [ -f .dockerignore ]; then grep -q "self-workflow" .dockerignore || echo "self-workflow" >> .dockerignore; else echo "self-workflow" >> .dockerignore; fi
324+
if: inputs.container == ''
297325
298326
- id: setup-node
327+
if: inputs.container == ''
299328
uses: ./self-workflow/actions/setup-node
300329
with:
301330
working-directory: ${{ inputs.working-directory }}
302331
dependencies-cache: |
303332
nx
304333
jest
305334
306-
- run: ${{ steps.setup-node.outputs.run-script-command }} test:ci
335+
- run: ${{ inputs.container != '' && 'npm run test:ci' || steps.setup-node.outputs.run-script-command }} test:ci
307336
working-directory: ${{ inputs.working-directory }}
308337
env:
309338
CI: "true"

0 commit comments

Comments
 (0)