Skip to content

Commit f546aa1

Browse files
authored
feat: build-push-docker allow-overwrites (#1526)
* feat: build-push-docker allow-overwrites * fixes? * test: use new ecr-image-exists * fix: update ref
1 parent a75cd1e commit f546aa1

3 files changed

Lines changed: 85 additions & 9 deletions

File tree

.changeset/mighty-ways-unite.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"build-push-docker": minor
3+
---
4+
5+
feat: add input "allow-overwrites" that allows you to fail the action early if
6+
you'd overwrite a tag in the target ECR

actions/build-push-docker/README.md

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,61 @@
11
# build-push-docker
22

3+
Builds and pushes a single-platform Docker image to ECR. Intended to be paired
4+
with [build-push-docker-manifest](../build-push-docker-manifest) to produce a
5+
multi-platform manifest from per-arch builds.
6+
7+
## Runner requirements
8+
9+
- OS: Linux only
10+
- Architecture: must match the `platform` input (`linux/amd64` → X64 runner,
11+
`linux/arm64` → ARM64 runner)
12+
13+
## Inputs
14+
15+
| Input | Required | Default | Description |
16+
| ------------------------- | ------------ | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
17+
| `platform` | **yes** || Target platform, e.g. `linux/amd64` or `linux/arm64`. Must match the runner architecture. |
18+
| `docker-registry-url` | when pushing || Registry hostname. Examples: `public.ecr.aws`, `<account-id>.dkr.ecr.<region>.amazonaws.com` |
19+
| `docker-repository-name` | when pushing || Repository name excluding the hostname and tags. Public ECR includes a registry alias, e.g. `chainlink/chainlink`. Private ECR is just the repo name, e.g. `my-repo`. |
20+
| `aws-account-number` | when pushing || AWS account number for the ECR registry. |
21+
| `aws-role-arn` | when pushing || AWS role ARN with ECR push permissions. |
22+
| `aws-region` | no | `us-east-1` | AWS region. Use `us-east-1` for public ECR. |
23+
| `dockerfile` | no | `./Dockerfile` | Path to the Dockerfile. |
24+
| `context` | no || Docker build context path or URL. Defaults to the Docker buildx default (repo root). |
25+
| `docker-target` | no || Target stage in a multi-stage Dockerfile. |
26+
| `docker-build-args` | no || Newline-delimited `KEY=VALUE` build arguments passed to `docker buildx build --build-arg`. See [Docker docs](https://docs.docker.com/reference/cli/docker/buildx/build/#build-arg). |
27+
| `docker-build-contexts` | no || Additional named build contexts, e.g. `name=path`. |
28+
| `docker-push` | no | `true` | Push the built image. Set to `false` for a build-only (no push) run. |
29+
| `tags` | no | `type=sha,prefix=pr=,event=pr` / `type=ref,event=tag` | Tag spec consumed by [docker/metadata-action](https://github.com/docker/metadata-action). |
30+
| `allow-overwrites` | no | `true` | When `false`, the action fails before building if any computed tag already exists in ECR. Useful for pseudo-immutability on public ECRs (which don't support native immutability) or as a fast-fail guard on private immutable ECRs. Ignored when `docker-push` is `false`. |
31+
| `docker-restore-cache` | no | `false` | Restore the Docker layer cache before building. |
32+
| `docker-save-cache` | no | `false` | Save the Docker layer cache after building. |
33+
| `docker-build-cache-from` | no | GHA cache scoped to OS/arch | Override the cache source. Effective only when `docker-restore-cache` is `true`. |
34+
| `docker-build-cache-to` | no | GHA cache scoped to OS/arch | Override the cache destination. Effective only when `docker-save-cache` is `true`. |
35+
| `docker-attestations` | no | `true` | Generate SBOM and provenance attestations. See [Docker docs](https://docs.docker.com/build/ci/github-actions/attestations/). |
36+
| `github-token` | no || GitHub token mounted as a Docker build secret (`GIT_AUTH_TOKEN`) for builds that fetch private dependencies. |
37+
38+
### Automatic `CL_AUTO_DOCKER_TAG` build arg
39+
40+
The action always injects a `CL_AUTO_DOCKER_TAG` build argument containing the
41+
first computed tag (with any `-amd64`/`-arm64` suffix stripped). Dockerfiles can
42+
consume it via `ARG CL_AUTO_DOCKER_TAG`. No configuration is needed; existing
43+
`docker-build-args` are preserved.
44+
45+
## Outputs
46+
47+
| Output | Description |
48+
| ------------------------------- | -------------------------------------------------- |
49+
| `docker-repository-name` | Echo of the `docker-repository-name` input. |
50+
| `docker-image-tags` | Newline-delimited list of all computed image tags. |
51+
| `docker-image-sha-digest-amd64` | Image digest when `platform` is `linux/amd64`. |
52+
| `docker-image-sha-digest-arm64` | Image digest when `platform` is `linux/arm64`. |
53+
354
## Example usage
455

5-
**NOTE**: _This composite workflow is intended to be used in conjunction with
6-
[build-push-docker-manifest](../build-push-docker-manifest) which will create a
7-
Docker manifest (or index) of the images created within this composite
8-
workflow._
56+
### This action is intended to be used with the [reusable-docker-build-publish](../../workflows/reusable-docker-build-publish/) workflow.
957

10-
### Set the following repo secrets
58+
#### Set the following repo secrets
1159

1260
**NOTE**: _Requires the [gh cli](https://cli.github.com/)._
1361

@@ -18,7 +66,7 @@ gh secret set AWS_REGION # example: us-east-1
1866
gh secret set AWS_OIDC_IAM_ROLE_ARN # example: arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ROLE NAME>
1967
```
2068

21-
### Create a workflow
69+
#### Create a workflow
2270

2371
This will build and push docker images for linux/amd64 AND linux/arm64.
2472

@@ -45,7 +93,7 @@ jobs:
4593
outputs:
4694
git-short-sha: ${{ steps.git-short-sha.outputs.short-sha }}
4795
steps:
48-
- uses: actions/checkout@v4
96+
- uses: actions/checkout@v6
4997
with:
5098
persist-credentials: false
5199
fetch-depth: 1
@@ -76,13 +124,13 @@ jobs:
76124
arch: arm64
77125
runs-on: ${{ matrix.runner }}
78126
steps:
79-
- uses: actions/checkout@v4
127+
- uses: actions/checkout@v6
80128
with:
81129
persist-credentials: false
82130
fetch-depth: 1
83131
- name: Build Docker image
84132
id: build-core
85-
uses: smartcontractkit/.github/actions/build-push-docker@<sha> # build-push-docker@x.y.z
133+
uses: smartcontractkit/.github/actions/build-push-docker@build-push-docker/v1
86134
with:
87135
# Change this to public.ecr.aws if you are using the public ECR.
88136
docker-registry-url:

actions/build-push-docker/action.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ inputs:
113113
114114
Required when inputs.docker-push is true.
115115
required: false
116+
# other inputs
117+
allow-overwrites:
118+
description: |
119+
Whether to allow overwriting existing image tags. If set to `false`, the action will fail if any of the tags already exist in ECR.
120+
Ideally the ECR is immutable and tags cannot be overwritten. Public ECRs don't support immutability so this allows a psuedo-immutability by failing if a tag already exists.
121+
This can be leveraged by immutable ECRs to fail-fast instead of building and subsequently failing to push.
122+
123+
Defaults to `true` for backwards compatibility. Ignored when inputs.docker-push is false.
124+
required: false
125+
default: "true"
116126

117127
outputs:
118128
docker-repository-name:
@@ -236,6 +246,18 @@ runs:
236246
flavor: |
237247
latest=false
238248
249+
- name: Check for existing tags
250+
if:
251+
${{ inputs.allow-overwrites == 'false' && inputs.docker-push == 'true'
252+
}}
253+
uses: smartcontractkit/.github/actions/ecr-image-exists@ecr-image-exists/v1
254+
with:
255+
docker-registry-url: ${{ inputs.docker-registry-url }}
256+
docker-repository-name: ${{ inputs.docker-repository-name }}
257+
tags: ${{ steps.docker-meta.outputs.tag-names }}
258+
assert-non-existence: true
259+
registry-auth: false
260+
239261
- name: Inject Standard Build Args
240262
id: inject-build-args
241263
shell: bash -euo pipefail {0}

0 commit comments

Comments
 (0)