Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/linters/actionlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# FIXME: Temporary ignores to bypass actionlint limitations. See https://github.com/rhysd/actionlint/issues/590.
paths:
.github/workflows/continuous-integration.yml:
ignore:
- 'both "username" and "password" must be specified in "credentials" section'
- '"credentials" section is scalar node but mapping node is expected'
- '"container" section is alias node but mapping node is expected'
- '"env" section must be mapping node but got scalar node'
- '"ports" section must be sequence node but got scalar node'
- '"volumes" section must be sequence node but got scalar node'
47 changes: 47 additions & 0 deletions .github/workflows/__test-workflow-continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,50 @@ jobs:

- name: Check the build artifacts
run: test -f ${{ runner.temp }}/usr/src/app/dist/test.txt

act-with-container-advanced:
name: Act - Run the continuous integration workflow (with container and advanced options)
uses: ./.github/workflows/continuous-integration.yml
needs: arrange-with-container
permissions:
contents: read
pull-requests: write
security-events: write
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
id-token: write
with:
container: |
{
"image": "${{ fromJSON(needs.arrange-with-container.outputs.built-images).ci-npm.images[0] }}",
"env": {
"NODE_ENV": "test",
"CI": "true"
},
"options": "--cpus 1",
"credentials": {
"username": "${{ github.actor }}"
}
}
working-directory: /usr/src/app/
build: |
{
"artifact": "dist"
}
test: |
{"coverage": "codecov"}
secrets:
container-password: ${{ secrets.GITHUB_TOKEN }}

assert-with-container-advanced:
name: Assert - Ensure build artifact has been uploaded (with container advanced)
runs-on: ubuntu-latest
needs: act-with-container-advanced
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
artifact-ids: ${{ needs.act-with-container-advanced.outputs.build-artifact-id }}
path: ${{ runner.temp }}

- name: Check the build artifacts
run: test -f ${{ runner.temp }}/usr/src/app/dist/test.txt
145 changes: 137 additions & 8 deletions .github/workflows/continuous-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,29 @@ jobs:
# Default: `.`
working-directory: .

# 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.
# Container configuration to run CI steps in.
# Accepts either a string (container image name) or a JSON object with container options.
#
# String format (simple):
# container: "node:18"
#
# JSON object format (advanced):
# container: |
# {
# "image": "node:18",
# "env": {
# "NODE_ENV": "production"
# },
# "ports": [8080],
# "volumes": ["/tmp:/tmp"],
# "options": "--cpus 2"
# }
#
# All properties from GitHub's container specification are supported except credentials (use secrets instead).
# See https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container
#
# When specified, steps will execute inside this container instead of checking out code.
# The container should have the project code and dependencies pre-installed.
container: ""
````

Expand Down Expand Up @@ -162,20 +184,83 @@ jobs:
| | Set to `null` or empty to disable. | | | |
| | Accepts a JSON object for test options. See [test action](../actions/test/README.md). | | | |
| **`working-directory`** | Working directory where the dependencies are installed. | **false** | **string** | `.` |
| **`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** | - |
| **`container`** | Container configuration to run CI steps in. Accepts string or JSON object. See Container Configuration below | **false** | **string** | - |

<!-- inputs:end -->

### Container Configuration

The `container` input accepts either:

**Simple string format** (image name only):

```yaml
container: "node:18"
```

**Advanced JSON format** (with container options):

```yaml
container: |
{
"image": "node:18",
"env": {
"NODE_ENV": "production"
},
"options": "--cpus 2",
"ports": [8080, 3000],
"volumes": ["/tmp:/tmp", "/cache:/cache"],
"credentials": {
"username": "myusername"
}
}
```

**Supported properties:**

- `image` (string, required) - Container image name
- `env` (object) - Environment variables
- `options` (string) - Additional Docker options
- `ports` (array) - Port mappings
- `volumes` (array) - Volume mounts
- `credentials` (object) - Registry credentials with `username` property

#### Container Registry Credentials

For private container images, specify the username in the container input's `credentials.username` property and pass the password via the `container-password` secret:

```yaml
jobs:
continuous-integration:
uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@main
secrets:
container-password: ${{ secrets.REGISTRY_PASSWORD }}
with:
container: |
{
"image": "ghcr.io/myorg/my-private-image:latest",
"credentials": {
"username": "myusername"
}
}
```

See [GitHub's container specification](https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container) for more details.

When specified, steps will execute inside this container instead of checking out code. The container should have the project code and dependencies pre-installed.

<!-- secrets:start -->

## Secrets

| **Secret** | **Description** | **Required** |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------ |
| **`build-secrets`** | Secrets to be used during the build step. | **false** |
| | Must be a multi-line env formatted string. | |
| | Example: | |
| | <!-- textlint-disable --><pre lang="txt">SECRET_EXAMPLE=$\{{ secrets.SECRET_EXAMPLE }}</pre><!-- textlint-enable --> | |
| **Secret** | **Description** | **Required** |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| **`build-secrets`** | Secrets to be used during the build step. | **false** |
| | Must be a multi-line env formatted string. | |
| | Example: | |
| | <!-- textlint-disable --><pre lang="txt">SECRET_EXAMPLE=$\{{ secrets.SECRET_EXAMPLE }}</pre><!-- textlint-enable --> | |
| **`container-password`** | Password or token for authenticating to the container registry. | **false** |
| | Required when using private container images. The username should be specified in the container input's `credentials.username` property. | |

<!-- secrets:end -->

Expand Down Expand Up @@ -289,6 +374,50 @@ jobs:
test: true
```

### Continuous Integration with Advanced Container Options

This example shows how to use advanced container options like environment variables, ports, volumes, credentials, and additional Docker options.

```yaml
name: Continuous Integration - Advanced Container Options

on:
push:
branches: [main]

jobs:
continuous-integration:
uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@32a69b7b8fd5f7ab7bf656e7e88aa90ad235cf8d # 0.18.0
permissions:
id-token: write
security-events: write
contents: read
secrets:
container-password: ${{ secrets.REGISTRY_PASSWORD }}
with:
container: |
{
"image": "ghcr.io/myorg/node-image:18-alpine",
"env": {
"NODE_ENV": "production",
"CI": "true"
},
"options": "--cpus 2 --memory 4g",
"ports": [3000, 8080],
"volumes": ["/tmp:/tmp", "/cache:/workspace/cache"],
"credentials": {
"username": "myusername"
}
}
# When using container mode, code-ql and dependency-review are typically disabled
# as they require repository checkout
code-ql: ""
dependency-review: false
build: "build"
lint: true
test: true
```

<!-- examples:end -->

<!-- contributing:start -->
Expand Down
Loading
Loading