This action builds Docker/Podman containers conditionally using a set of directories. If any files were changed matching that, then build a container. If those files were not changed, retag an existing build.
This is useful in CI/CD pipelines where not every package/app needs to be rebuilt.
This tool is currently strongly opinionated and generates images with a rigid structure below. This is intended to become more flexible in future.
Package name: <organization>/<repository>/<package>:<tag>
Pull with: docker pull ghcr.io/<organization>/<repository>/<package>:<tag>
Only GitHub Container Registry (ghcr.io) is supported so far.
- uses: bcgov/[email protected]
with:
### Required
# Package name
package: frontend
### Typical / recommended
# Sets the build context/directory, which contains the build files
# Optional, defaults to package name
build_context: ./frontend
# Sets the Dockerfile with path
# Optional, defaults to {package}/Dockerfile or {build_context}/Dockerfile
build_file: ./frontend/Dockerfile
# Fallback tag, used if no build was generated
# Optional, defaults to nothing, which forces a build
# Non-matching or malformed tags are rejected, which also forced a build
tag_fallback: test
# Tags to apply to the image
# Optional, defaults to pull request number
# Note: All tags are normalized to lowercase and stripped of spaces before use.
tags: |
pr123
demo
# Bash array to diff for build triggering
# Optional, defaults to nothing, which forces a build
triggers: ('frontend/' 'backend/' 'database/')
### Usually a bad idea / not recommended
# Sets a list of [build-time variables](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-arg)
# Optional, defaults to sample content
build_args: |
ENV=build
# Overrides the default branch to diff against
# Defaults to the default branch, usually `main`
diff_branch: ${{ github.event.repository.default_branch }}
# Repository to clone and process
# Useful for consuming other repos, like in testing
# Defaults to the current one
repository: ${{ github.repository }}
# SBOM generation is enabled by default as a security best practice
# String value, not boolean
sbom: 'true'
# Specify token (GH or PAT), instead of inheriting one from the calling workflow
token: ${{ secrets.GITHUB_TOKEN }}
### Deprecated
# Single-value tag input has been deprecated and will be removed in a future release
# Please use inputs.tags, which can handle multiple values
tag: do not use!
Build a single subfolder with a Dockerfile in it. Runs on pull requests (PRs).
builds:
runs-on: ubuntu-24.04
steps:
- name: Builds
uses: bcgov/[email protected]
with:
package: frontend
tag_fallback: test
triggers: ('frontend/')
Same as previous, but specifying build folder and Dockerfile.
builds:
runs-on: ubuntu-24.04
steps:
- name: Builds
uses: bcgov/[email protected]
with:
package: frontend
build_context: ./
build_file: subdir/Dockerfile
tags: |
${{ github.event.number }}
${{ github.sha }}
latest
tag_fallback: test
token: ${{ secrets.GITHUB_TOKEN }}
triggers: ('frontend/')
Build from multiple subfolders with Dockerfile in them. This time an outside repository is used. Runs on pull requests (PRs).
builds:
runs-on: ubuntu-24.04
strategy:
matrix:
package: [backend, frontend]
include:
- package: backend
triggers: ('backend/')
- package: frontend
triggers: ('frontend/')
steps:
- uses: actions/checkout@v4
- name: Test Builds
uses: bcgov/[email protected]
with:
package: ${{ matrix.package }}
tags: ${{ github.event.number }}
tag_fallback: test
repository: bcgov/nr-quickstart-typescript
token: ${{ secrets.GITHUB_TOKEN }}
triggers: ${{ matrix.triggers }}
This action provides two key security features: Container Attestations and Software Bill of Materials (SBOM) generation.
Container attestations use GitHub's OIDC token to provide cryptographic proof of:
- Where the container was built (GitHub Actions)
- When it was built (timestamp)
- What repository and workflow built it
- What inputs and environment were used
Attestations require the following permissions:
permissions:
packages: write # Required for pushing images
id-token: write # Required for OIDC token generation
attestations: write # Required for creating attestations
If these permissions are not granted, the action will still build and push images but skip the attestation step.
This action automatically generates SBOMs for all container builds using Syft. SBOMs provide a detailed inventory that includes:
- All installed packages and their versions
- Dependencies and their relationships
- License information
- Known vulnerabilities
Two SBOM formats are generated and uploaded as workflow artifacts:
- CycloneDX JSON
- SPDX JSON
Output | Description |
---|---|
digest |
Digest of the built or retagged image |
triggered |
Whether a build was triggered (true/false ) |
New image digest (SHA). This applies to build and retags.
- id: digest
uses: bcgov/[email protected]
...
- name: Echo digest
run: |
echo "Digest: ${{ steps.digest.outputs.digest }}"
...
Has an image been built? [true|false]
- id: trigger
uses: bcgov/[email protected]
...
- name: Echo build trigger
run: |
echo "Trigger result: ${{ steps.trigger.outputs.triggered }}"
...
- Multi package repos:
ghcr.io/org/repo/package:tag
- Single package repos:
ghcr.io/org/repo:tag
Single package naming is only triggered when package=repository.
⚠️ Deprecated: Thetag
input has been deprecated in favor oftags
, a multiline string that can handle multiple values. Thetag
input will be removed in a future release.
- The
digest_old
output has been deprecated due to non-use. - The
digest_new
output has been renamed todigest
.