Action to create built images manifests. It uses the Docker Buildx plugin to create manifests for the built images. It requires the Docker Buildx plugin to be installed and configured. It supports creating manifests for multiple images and platforms at once.
If default GitHub token is used, the following permissions are required:
permissions:
contents: read
packages: write- uses: hoverkraft-tech/ci-github-container/actions/docker/create-images-manifests@c9088e8447c5a8be45157e17701023fc50ccb1c0 # 0.37.2
with:
# OCI registry configuration used to pull, push and cache images.
# Accepts either a registry hostname string (default format) or a JSON object.
# JSON example: `{"pull":"docker.io","pull:private":"ghcr.io","push":"ghcr.io"}`
# JSON object keys:
# - `pull`: registry used to pull public or default base images
# - `pull:<name>`: additional pull registry
# - `push`: registry used for published images
# - `cache`: registry used when `cache-type` is `registry`
#
# This input is required.
# Default: `ghcr.io`
oci-registry: ghcr.io
# Username configuration used to log against OCI registries.
# Accepts either a single username string (default format) or a JSON object using the same keys as `oci-registry`.
# JSON example: `{"pull:private":"$\{{ github.repository_owner }}","push":"$\{{ github.repository_owner }}"}`
# See https://github.com/docker/login-action#usage.
#
# This input is required.
# Default: `${{ github.repository_owner }}`
oci-registry-username: ${{ github.repository_owner }}
# Password or personal access token configuration used to log against OCI registries.
# Accepts either a single password/token string (default format) or a JSON object using the same keys as `oci-registry`.
# JSON example: `{"pull:private":"$\{{ github.token }}","push":"$\{{ github.token }}"}`
# Can be passed in using `secrets.GITHUB_TOKEN`.
# See https://github.com/docker/login-action#usage.
#
# This input is required.
# Default: `${{ github.token }}`
oci-registry-password: ${{ github.token }}
# Built images data.
# Example:
# ```json
# {
# "application": {
# "name": "application",
# "registry": "ghcr.io",
# "repository": "my-org/my-repo/application",
# "tags": ["pr-63-5222075","pr-63"],
# "images": [
# "ghcr.io/my-org/my-repo/application@sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d",
# "ghcr.io/my-org/my-repo/application@sha256:0f5aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f402",
# ],
# "annotations": {
# "org.opencontainers.image.created": "2021-09-30T14:00:00Z",
# "org.opencontainers.image.description": "Application image"
# },
# "platforms": ["linux/amd64", "linux/arm64"],
# "multi-platform": true
# }
# }
# ```
#
# This input is required.
built-images: ""| Input | Description | Required | Default |
|---|---|---|---|
oci-registry |
OCI registry configuration used to pull, push and cache images. | true | ghcr.io |
| Accepts either a registry hostname string (default format) or a JSON object. | |||
JSON example: {"pull":"docker.io","pull:private":"ghcr.io","push":"ghcr.io"} |
|||
| JSON object keys: | |||
- pull: registry used to pull public or default base images |
|||
- pull:<name>: additional pull registry |
|||
- push: registry used for published images |
|||
- cache: registry used when cache-type is registry |
|||
oci-registry-username |
Username configuration used to log against OCI registries. | true | ${{ github.repository_owner }} |
Accepts either a single username string (default format) or a JSON object using the same keys as oci-registry. |
|||
JSON example: {"pull:private":"$\{{ github.repository_owner }}","push":"$\{{ github.repository_owner }}"} |
|||
| See https://github.com/docker/login-action#usage. | |||
oci-registry-password |
Password or personal access token configuration used to log against OCI registries. | true | ${{ github.token }} |
Accepts either a single password/token string (default format) or a JSON object using the same keys as oci-registry. |
|||
JSON example: {"pull:private":"$\{{ github.token }}","push":"$\{{ github.token }}"} |
|||
Can be passed in using secrets.GITHUB_TOKEN. |
|||
| See https://github.com/docker/login-action#usage. | |||
built-images |
Built images data. | true | - |
| Example: | |||
{
"application": {
"name": "application",
"registry": "ghcr.io",
"repository": "my-org/my-repo/application",
"tags": ["pr-63-5222075","pr-63"],
"images": [
"ghcr.io/my-org/my-repo/application@sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d",
"ghcr.io/my-org/my-repo/application@sha256:0f5aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f402",
],
"annotations": {
"org.opencontainers.image.created": "2021-09-30T14:00:00Z",
"org.opencontainers.image.description": "Application image"
},
"platforms": ["linux/amd64", "linux/arm64"],
"multi-platform": true
}
} |
| Output | Description |
|---|---|
built-images |
Built images data. |
| Example: | |
{
"application": {
"name": "application",
"registry": "ghcr.io",
"repository": "my-org/my-repo/application",
"tags": ["pr-63-5222075","pr-63"],
"digest": "sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d",
"images": [
"ghcr.io/my-org/my-repo/application:pr-63-5222075@sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d",
"ghcr.io/my-org/my-repo/application:pr-63@sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d"
],
"annotations": {
"org.opencontainers.image.created": "2021-09-30T14:00:00Z",
"org.opencontainers.image.description": "Application image"
},
"platforms": ["linux/amd64", "linux/arm64"]
}
} |
The default single-registry format still works:
oci-registry: ghcr.io
oci-registry-username: ${{ github.repository_owner }}
oci-registry-password: ${{ github.token }}To configure distinct pull, push and cache registries, pass JSON objects:
oci-registry: |
{"pull":"docker.io","pull:private":"ghcr.io","push":"ghcr.io"}
oci-registry-username: |
{"pull:private":"${{ github.repository_owner }}","push":"${{ github.repository_owner }}"}
oci-registry-password: |
{"pull:private":"${{ github.token }}","push":"${{ github.token }}"}Registry credentials are resolved by role using the same keys as oci-registry.
This example first builds and publishes an original tag (1.0.0-rc.0) with the reusable workflow .github/workflows/docker-build-images.yml, then copies that tag to 1.0.0 using this action.
jobs:
build-original-tag:
uses: hoverkraft-tech/ci-github-container/.github/workflows/docker-build-images.yml@<sha> # x.y.z
permissions:
contents: read
id-token: write
packages: write
secrets:
oci-registry-password: ${{ secrets.GITHUB_TOKEN }}
with:
sign: false
images: |
[
{
"name": "application",
"context": ".",
"dockerfile": "./tests/application/Dockerfile",
"target": "prod",
"platforms": ["linux/amd64"],
"tag": "1.0.0-rc.0"
}
]
clone-image-tag:
needs: build-original-tag
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@<sha> # vx.y.z
with:
persist-credentials: false
- uses: hoverkraft-tech/ci-github-container/actions/docker/setup@<sha> # x.y.z
with:
oci-registry: ghcr.io
oci-registry-username: ${{ github.repository_owner }}
oci-registry-password: ${{ secrets.GITHUB_TOKEN }}
- id: create-images-manifests-input
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
BUILT_IMAGES_OUTPUT: ${{ needs.build-original-tag.outputs.built-images }}
with:
script: |
const builtImages = JSON.parse(process.env.BUILT_IMAGES_OUTPUT);
const imageName = "application";
const originalImage = builtImages[imageName];
if (!originalImage) {
throw new Error(`Missing "${imageName}" entry in "built-images" output`);
}
// Build manifest-clone input: source = existing 1.0.0-rc.0 tag, destination = 1.0.0 tag.
const cloneInput = {
[imageName]: {
...originalImage,
tags: ["1.0.0"],
images: [`${originalImage.registry}/${originalImage.repository}:1.0.0-rc.0`],
"multi-platform": true, // Force multi-platform to force create tag
},
};
core.setOutput("built-images", JSON.stringify(cloneInput));
- id: clone-tag
uses: hoverkraft-tech/ci-github-container/actions/docker/create-images-manifests@c9088e8447c5a8be45157e17701023fc50ccb1c0 # 0.37.2
with:
oci-registry: ghcr.io
oci-registry-username: ${{ github.repository_owner }}
oci-registry-password: ${{ secrets.GITHUB_TOKEN }}
built-images: ${{ steps.create-images-manifests-input.outputs.built-images }}Contributions are welcome! Please see the contributing guidelines for more details.
This project is licensed under the MIT License.
SPDX-License-Identifier: MIT
Copyright © 2026 hoverkraft
For more details, see the license.
This documentation was automatically generated by CI Dokumentor.