Compare commits

..

No commits in common. "master" and "v5.2.0" have entirely different histories.

43 changed files with 4567 additions and 10398 deletions

View File

@ -1,12 +1,2 @@
/coverage
# Dependency directories
node_modules/
jspm_packages/
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
/node_modules

View File

@ -13,7 +13,7 @@
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2023,
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [

2
.gitattributes vendored
View File

@ -1,4 +1,2 @@
/.yarn/releases/** binary
/.yarn/plugins/** binary
/dist/** linguist-generated=true
/lib/** linguist-generated=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

View File

@ -38,9 +38,6 @@ jobs:
fail-fast: false
matrix:
include:
-
buildx_version: edge
buildkit_image: moby/buildkit:latest
-
buildx_version: latest
buildkit_image: moby/buildkit:buildx-stable-1
@ -68,11 +65,10 @@ jobs:
if: inputs.type == 'local'
run: |
if [ ! -e /etc/docker/daemon.json ]; then
echo '{}' | sudo tee /etc/docker/daemon.json >/dev/null
echo '{}' | tee /etc/docker/daemon.json >/dev/null
fi
DOCKERD_CONFIG=$(jq '.+{"insecure-registries":["http://${{ env.REGISTRY_FQDN }}"]}' /etc/docker/daemon.json)
sudo tee /etc/docker/daemon.json <<<"$DOCKERD_CONFIG" >/dev/null
cat /etc/docker/daemon.json
sudo service docker restart
-
name: Install ${{ inputs.name }}
@ -98,7 +94,7 @@ jobs:
uses: docker/setup-buildx-action@v3
with:
version: ${{ matrix.buildx_version }}
buildkitd-config: /tmp/buildkitd.toml
config: /tmp/buildkitd.toml
buildkitd-flags: --debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
driver-opts: |
image=${{ matrix.buildkit_image }}

View File

@ -24,8 +24,8 @@ on:
pull_request:
env:
BUILDX_VERSION: edge
BUILDKIT_IMAGE: moby/buildkit:latest
BUILDX_VERSION: latest
BUILDKIT_IMAGE: moby/buildkit:buildx-stable-1
jobs:
minimal:
@ -288,6 +288,7 @@ jobs:
-
name: Check
run: |
echo "${{ toJson(steps.docker_build) }}"
if [ "${{ steps.docker_build.outcome }}" != "failure" ] || [ "${{ steps.docker_build.conclusion }}" != "success" ]; then
echo "::error::Should have failed"
exit 1
@ -323,6 +324,7 @@ jobs:
-
name: Check
run: |
echo "${{ toJson(steps.docker_build) }}"
if [ "${{ steps.docker_build.outcome }}" != "failure" ] || [ "${{ steps.docker_build.conclusion }}" != "success" ]; then
echo "::error::Should have failed"
exit 1
@ -565,8 +567,6 @@ jobs:
fail-fast: false
matrix:
include:
- buildx: edge
buildkit: moby/buildkit:latest
- buildx: latest
buildkit: moby/buildkit:buildx-stable-1
- buildx: latest
@ -1254,291 +1254,3 @@ jobs:
name: Check manifest
run: |
docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }} --format '{{json .}}'
multi-output:
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
buildkitd-flags: --debug
-
name: Build
uses: ./
with:
context: ./test
file: ./test/Dockerfile
outputs: |
type=image,name=localhost:5000/name/app:latest,push=true
type=docker,name=app:local
type=oci,dest=/tmp/oci.tar
-
name: Check registry
run: |
docker buildx imagetools inspect localhost:5000/name/app:latest --format '{{json .}}'
-
name: Check docker
run: |
docker image inspect app:local
-
name: Check oci
run: |
set -ex
mkdir -p /tmp/oci-out
tar xf /tmp/oci.tar -C /tmp/oci-out
tree -nh /tmp/oci-out
load-and-push:
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
buildkitd-flags: --debug
-
name: Build
uses: ./
with:
context: ./test
file: ./test/Dockerfile
load: true
push: true
tags: localhost:5000/name/app:latest
-
name: Check registry
run: |
docker buildx imagetools inspect localhost:5000/name/app:latest --format '{{json .}}'
-
name: Check docker
run: |
docker image inspect localhost:5000/name/app:latest
summary-disable:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
with:
path: action
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./action
with:
file: ./test/Dockerfile
env:
DOCKER_BUILD_SUMMARY: false
summary-disable-deprecated:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
with:
path: action
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./action
with:
file: ./test/Dockerfile
env:
DOCKER_BUILD_NO_SUMMARY: true
summary-not-supported:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
with:
path: action
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: v0.12.1
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./action
with:
file: ./test/Dockerfile
record-upload-disable:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
with:
path: action
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./action
with:
file: ./test/Dockerfile
env:
DOCKER_BUILD_RECORD_UPLOAD: false
record-retention-days:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
days:
- 2
- 0
steps:
-
name: Checkout
uses: actions/checkout@v4
with:
path: action
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./action
with:
file: ./test/Dockerfile
env:
DOCKER_BUILD_RECORD_RETENTION_DAYS: ${{ matrix.days }}
checks:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
buildx-version:
- edge
- latest
- v0.14.1
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ matrix.buildx-version }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./
with:
context: ./test
file: ./test/lint.Dockerfile
annotations-disabled:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./
with:
context: ./test
file: ./test/lint.Dockerfile
env:
DOCKER_BUILD_CHECKS_ANNOTATIONS: false
call-check:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
id: docker_build
continue-on-error: true
uses: ./
with:
context: ./test
file: ./test/lint.Dockerfile
call: check
-
name: Check
run: |
if [ "${{ steps.docker_build.outcome }}" != "failure" ] || [ "${{ steps.docker_build.conclusion }}" != "success" ]; then
echo "::error::Should have failed"
exit 1
fi

View File

@ -88,13 +88,13 @@ jobs:
username_secret: QUAY_USERNAME
password_secret: QUAY_TOKEN
type: remote
-
name: Artifactory
registry: infradock.jfrog.io
slug: infradock.jfrog.io/test-ghaction/build-push-action
username_secret: ARTIFACTORY_USERNAME
password_secret: ARTIFACTORY_TOKEN
type: remote
# -
# name: Artifactory
# registry: sforzando-build-team-local.jfrog.io
# slug: sforzando-build-team-local.jfrog.io/build-push-action-e2e
# username_secret: ARTIFACTORY_USERNAME
# password_secret: ARTIFACTORY_TOKEN
# type: remote
-
name: Harbor
id: harbor

View File

@ -1,21 +0,0 @@
name: publish
on:
release:
types:
- published
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
packages: write
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Publish
uses: actions/publish-immutable-action@v0.0.4

View File

@ -15,14 +15,17 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Test
uses: docker/bake-action@v6
uses: docker/bake-action@v4
with:
targets: test
-
name: Upload coverage
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v4
with:
files: ./coverage/clover.xml
file: ./coverage/clover.xml
token: ${{ secrets.CODECOV_TOKEN }}

View File

@ -15,17 +15,16 @@ jobs:
prepare:
runs-on: ubuntu-latest
outputs:
targets: ${{ steps.generate.outputs.targets }}
targets: ${{ steps.targets.outputs.matrix }}
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: List targets
id: generate
uses: docker/bake-action/subaction/list-targets@v6
with:
target: validate
name: Targets matrix
id: targets
run: |
echo "matrix=$(docker buildx bake validate --print | jq -cr '.group.validate.targets')" >> $GITHUB_OUTPUT
validate:
runs-on: ubuntu-latest
@ -36,8 +35,11 @@ jobs:
matrix:
target: ${{ fromJson(needs.prepare.outputs.targets) }}
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Validate
uses: docker/bake-action@v6
uses: docker/bake-action@v4
with:
targets: ${{ matrix.target }}

66
.gitignore vendored
View File

@ -1,5 +1,7 @@
# https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
node_modules
lib
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
# Logs
logs
*.log
@ -7,7 +9,6 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
@ -18,14 +19,34 @@ pids
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
@ -35,19 +56,36 @@ jspm_packages/
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
# dotenv environment variables file
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
.env.test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/

View File

@ -1,6 +0,0 @@
# Dependency directories
node_modules/
jspm_packages/
# yarn v2
.yarn/

File diff suppressed because one or more lines are too long

View File

@ -1,13 +0,0 @@
logFilters:
- code: YN0013
level: discard
- code: YN0019
level: discard
- code: YN0076
level: discard
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"

118
README.md
View File

@ -19,11 +19,21 @@ ___
* [Git context](#git-context)
* [Path context](#path-context)
* [Examples](#examples)
* [Summaries](#summaries)
* [Multi-platform image](https://docs.docker.com/build/ci/github-actions/multi-platform/)
* [Secrets](https://docs.docker.com/build/ci/github-actions/secrets/)
* [Push to multi-registries](https://docs.docker.com/build/ci/github-actions/push-multi-registries/)
* [Manage tags and labels](https://docs.docker.com/build/ci/github-actions/manage-tags-labels/)
* [Cache management](https://docs.docker.com/build/ci/github-actions/cache/)
* [Export to Docker](https://docs.docker.com/build/ci/github-actions/export-docker/)
* [Test before push](https://docs.docker.com/build/ci/github-actions/test-before-push/)
* [Local registry](https://docs.docker.com/build/ci/github-actions/local-registry/)
* [Share built image between jobs](https://docs.docker.com/build/ci/github-actions/share-image-jobs/)
* [Named contexts](https://docs.docker.com/build/ci/github-actions/named-contexts/)
* [Copy image between registries](https://docs.docker.com/build/ci/github-actions/copy-image-registries/)
* [Update Docker Hub repo description](https://docs.docker.com/build/ci/github-actions/update-dockerhub-desc/)
* [Customizing](#customizing)
* [inputs](#inputs)
* [outputs](#outputs)
* [environment variables](#environment-variables)
* [Troubleshooting](#troubleshooting)
* [Contributing](#contributing)
@ -55,26 +65,28 @@ name: ci
on:
push:
branches:
- 'main'
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v5
with:
push: true
tags: user/app:latest
@ -92,15 +104,28 @@ expression `{{defaultContext}}`. Here we can use it to provide a subdirectory
to the default Git context:
```yaml
-
# Setting up Docker Buildx with docker-container driver is required
# at the moment to be able to use a subdirectory with Git context
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v5
with:
context: "{{defaultContext}}:mysubdir"
push: true
tags: user/app:latest
```
> **Warning**
>
> Subdirectory for Git context is available from [BuildKit v0.9.0](https://github.com/moby/buildkit/releases/tag/v0.9.0).
> If you're using the `docker` builder (default if `setup-buildx-action` not used),
> then BuildKit in Docker Engine will be used. As Docker Engine < v22.x.x embeds
> Buildkit 0.8.2 at the moment, it does not support this feature. It's therefore
> required to use the `setup-buildx-action` at the moment.
Building from the current repository automatically uses the [GitHub Token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication),
so it does not need to be passed. If you want to authenticate against another
private repository, you have to use a [secret](https://docs.docker.com/build/ci/github-actions/secrets)
@ -109,7 +134,7 @@ named `GIT_AUTH_TOKEN` to be able to authenticate against it with Buildx:
```yaml
-
name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v5
with:
push: true
tags: user/app:latest
@ -124,6 +149,8 @@ name: ci
on:
push:
branches:
- 'main'
jobs:
docker:
@ -132,21 +159,21 @@ jobs:
-
name: Checkout
uses: actions/checkout@v4
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v5
with:
context: .
push: true
@ -162,54 +189,17 @@ jobs:
* [Cache management](https://docs.docker.com/build/ci/github-actions/cache/)
* [Export to Docker](https://docs.docker.com/build/ci/github-actions/export-docker/)
* [Test before push](https://docs.docker.com/build/ci/github-actions/test-before-push/)
* [Validating build configuration](https://docs.docker.com/build/ci/github-actions/checks/)
* [Local registry](https://docs.docker.com/build/ci/github-actions/local-registry/)
* [Share built image between jobs](https://docs.docker.com/build/ci/github-actions/share-image-jobs/)
* [Named contexts](https://docs.docker.com/build/ci/github-actions/named-contexts/)
* [Copy image between registries](https://docs.docker.com/build/ci/github-actions/copy-image-registries/)
* [Update Docker Hub repo description](https://docs.docker.com/build/ci/github-actions/update-dockerhub-desc/)
* [SBOM and provenance attestations](https://docs.docker.com/build/ci/github-actions/attestations/)
* [Annotations](https://docs.docker.com/build/ci/github-actions/annotations/)
* [Reproducible builds](https://docs.docker.com/build/ci/github-actions/reproducible-builds/)
## Summaries
This action generates a [job summary](https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/)
that provides a detailed overview of the build execution. The summary shows an
overview of all the steps executed during the build, including the build inputs
and eventual errors.
![build-push-action job summary](./.github/build-push-summary.png)
The summary also includes a link for downloading the build record with
additional details about the build, including build stats, logs, outputs, and
more. The build record can be imported to Docker Desktop for inspecting the
build in greater detail.
> [!WARNING]
>
> If you're using the [`actions/download-artifact`](https://github.com/actions/download-artifact)
> action in your workflow, you need to ignore the build record artifacts
> if `name` and `pattern` inputs are not specified ([defaults to download all artifacts](https://github.com/actions/download-artifact?tab=readme-ov-file#download-all-artifacts) of the workflow),
> otherwise the action will fail:
> ```yaml
> - uses: actions/download-artifact@v4
> with:
> pattern: "!*.dockerbuild"
> ```
> More info: https://github.com/actions/toolkit/pull/1874
Summaries are enabled by default, but can be disabled with the
`DOCKER_BUILD_SUMMARY` [environment variable](#environment-variables).
For more information about summaries, refer to the
[documentation](https://docs.docker.com/go/build-summary/).
## Customizing
### inputs
The following inputs can be used as `step.with` keys:
Following inputs can be used as `step.with` keys
> `List` type is a newline-delimited string
> ```yaml
@ -234,7 +224,6 @@ The following inputs can be used as `step.with` keys:
| `build-contexts` | List | List of additional [build contexts](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context) (e.g., `name=path`) |
| `cache-from` | List | List of [external cache sources](https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-from) (e.g., `type=local,src=path/to/dir`) |
| `cache-to` | List | List of [cache export destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-to) (e.g., `type=local,dest=path/to/dir`) |
| `call` | String | Set [method for evaluating build](https://docs.docker.com/reference/cli/docker/buildx/build/#call) (e.g., `check`) |
| `cgroup-parent` | String | Optional [parent cgroup](https://docs.docker.com/engine/reference/commandline/build/#use-a-custom-parent-cgroup---cgroup-parent) for the container used in the build |
| `context` | String | Build's context is the set of files located in the specified [`PATH` or `URL`](https://docs.docker.com/engine/reference/commandline/build/) (default [Git context](#git-context)) |
| `file` | String | Path to the Dockerfile. (default `{context}/Dockerfile`) |
@ -243,7 +232,7 @@ The following inputs can be used as `step.with` keys:
| `network` | String | Set the networking mode for the `RUN` instructions during build |
| `no-cache` | Bool | Do not use cache when building the image (default `false`) |
| `no-cache-filters` | List/CSV | Do not cache specified stages |
| `outputs` | List | List of [output destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#output) (format: `type=local,dest=path`) |
| `outputs`¹ | List | List of [output destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#output) (format: `type=local,dest=path`) |
| `platforms` | List/CSV | List of [target platforms](https://docs.docker.com/engine/reference/commandline/buildx_build/#platform) for build |
| `provenance` | Bool/String | Generate [provenance](https://docs.docker.com/build/attestations/slsa-provenance/) attestation for the build (shorthand for `--attest=type=provenance`) |
| `pull` | Bool | Always attempt to pull all referenced images (default `false`) |
@ -259,6 +248,10 @@ The following inputs can be used as `step.with` keys:
| `ulimit` | List | [Ulimit](https://docs.docker.com/engine/reference/commandline/buildx_build/#ulimit) options (e.g., `nofile=1024:1024`) |
| `github-token` | String | GitHub Token used to authenticate against a repository for [Git context](#git-context) (default `${{ github.token }}`) |
> **Note**
>
> * ¹ multiple `outputs` are [not yet supported](https://github.com/moby/buildkit/issues/1555)
### outputs
The following outputs are available:
@ -269,15 +262,6 @@ The following outputs are available:
| `digest` | String | Image digest |
| `metadata` | JSON | Build result metadata |
### environment variables
| Name | Type | Default | Description |
|--------------------------------------|--------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `DOCKER_BUILD_CHECKS_ANNOTATIONS` | Bool | `true` | If `false`, GitHub annotations are not generated for [build checks](https://docs.docker.com/build/checks/) |
| `DOCKER_BUILD_SUMMARY` | Bool | `true` | If `false`, [build summary](https://docs.docker.com/build/ci/github-actions/build-summary/) generation is disabled |
| `DOCKER_BUILD_RECORD_UPLOAD` | Bool | `true` | If `false`, build record upload as [GitHub artifact](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts) is disabled |
| `DOCKER_BUILD_RECORD_RETENTION_DAYS` | Number | | Duration after which build record artifact will expire in days. Defaults to repository/org [retention settings](https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration#artifact-and-log-retention-policy) if unset or `0` |
## Troubleshooting
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md)

View File

@ -4,6 +4,7 @@
* [BuildKit container logs](#buildkit-container-logs)
* [With containerd](#with-containerd)
* [`repository name must be lowercase`](#repository-name-must-be-lowercase)
* [Image not loaded](#image-not-loaded)
## Cannot push to a registry
@ -58,7 +59,7 @@ jobs:
uses: crazy-max/ghaction-setup-containerd@v2
-
name: Build Docker image
uses: docker/build-push-action@v6
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
@ -111,7 +112,7 @@ to generate sanitized tags:
tags: latest
- name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v5
with:
context: .
push: true
@ -129,9 +130,35 @@ Or a dedicated step to sanitize the slug:
script: return 'ghcr.io/${{ github.repository }}'.toLowerCase()
- name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.repo_slug.outputs.result }}:latest
```
## Image not loaded
Sometimes when your workflows are heavy consumers of disk storage, it can happen that build-push-action declares that the built image is loaded, but then not found in the following workflow steps.
- You can use the following solution as workaround, to free space on disk before building docker image using the following workflow step
```yaml
# Free disk space
- name: Free Disk space
shell: bash
run: |
sudo rm -rf /usr/local/lib/android # will release about 10 GB if you don't need Android
sudo rm -rf /usr/share/dotnet # will release about 20GB if you don't need .NET
```
- Another workaround can be to call `docker/setup-buildx-action` with docker driver
```yaml
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
```
More details in the [related issue](https://github.com/docker/build-push-action/issues/321)

View File

@ -1,16 +1,13 @@
import {beforeEach, describe, expect, jest, test} from '@jest/globals';
import * as fs from 'fs';
import * as path from 'path';
import {Builder} from '@docker/actions-toolkit/lib/buildx/builder';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
import {Build} from '@docker/actions-toolkit/lib/buildx/build';
import {Context} from '@docker/actions-toolkit/lib/context';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {GitHub} from '@docker/actions-toolkit/lib/github';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {BuilderInfo} from '@docker/actions-toolkit/lib/types/buildx/builder';
import {BuilderInfo} from '@docker/actions-toolkit/lib/types/builder';
import {GitHubRepo} from '@docker/actions-toolkit/lib/types/github';
import * as context from '../src/context';
@ -38,16 +35,6 @@ jest.spyOn(Docker, 'isAvailable').mockImplementation(async (): Promise<boolean>
return true;
});
const metadataJson = path.join(tmpDir, 'metadata.json');
jest.spyOn(Build.prototype, 'getMetadataFilePath').mockImplementation((): string => {
return metadataJson;
});
const imageIDFilePath = path.join(tmpDir, 'iidfile.txt');
jest.spyOn(Build.prototype, 'getImageIDFilePath').mockImplementation((): string => {
return imageIDFilePath;
});
jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<BuilderInfo> => {
return {
name: 'builder2',
@ -91,7 +78,7 @@ describe('getArgs', () => {
]),
[
'build',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'.'
]
],
@ -114,7 +101,7 @@ ccc"`],
'--build-arg', 'MY_ARG=val1,val2,val3',
'--build-arg', 'ARG=val',
'--build-arg', `MULTILINE=aaaa\nbbbb\nccc`,
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'https://github.com/docker/build-push-action.git#refs/heads/master'
]
],
@ -130,7 +117,7 @@ ccc"`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--tag', 'name/app:7.4',
'--tag', 'name/app:latest',
'https://github.com/docker/build-push-action.git#refs/heads/master'
@ -185,7 +172,7 @@ ccc"`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'.'
]
],
@ -202,7 +189,7 @@ ccc"`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`,
'.'
]
@ -243,7 +230,7 @@ ccc"`],
[
'build',
'--file', './test/Dockerfile',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--platform', 'linux/amd64,linux/arm64',
'--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`,
'--builder', 'builder-git-context-2',
@ -277,7 +264,7 @@ ccc"`],
[
'build',
'--file', './test/Dockerfile',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--platform', 'linux/amd64,linux/arm64',
'--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`,
'--secret', `id=MYSECRET,src=${tmpName}`,
@ -314,7 +301,7 @@ ccc`],
[
'build',
'--file', './test/Dockerfile',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--platform', 'linux/amd64,linux/arm64',
'--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`,
'--secret', `id=MYSECRET,src=${tmpName}`,
@ -343,7 +330,7 @@ ccc`],
[
'build',
'--file', './test/Dockerfile',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--secret', `id=MY_SECRET,src=${tmpName}`,
'--builder', 'builder-git-context-2',
'--network', 'host',
@ -390,8 +377,8 @@ ccc`],
'--add-host', 'docker:10.180.0.1',
'--add-host', 'foo:10.0.0.1',
'--file', './test/Dockerfile',
'--iidfile', imageIDFilePath,
'--metadata-file', metadataJson,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'--network', 'host',
'--push',
'.'
@ -419,11 +406,11 @@ nproc=3`],
'--add-host', 'foo:10.0.0.1',
'--cgroup-parent', 'foo',
'--file', './test/Dockerfile',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--shm-size', '2g',
'--ulimit', 'nofile=1024:1024',
'--ulimit', 'nproc=3',
'--metadata-file', metadataJson,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -439,8 +426,8 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--metadata-file', metadataJson,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'https://github.com/docker/build-push-action.git#refs/heads/master:docker'
]
],
@ -457,9 +444,9 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`,
'--metadata-file', metadataJson,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'https://github.com/docker/build-push-action.git#refs/heads/master:subdir'
]
],
@ -476,8 +463,8 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--metadata-file', metadataJson,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -493,9 +480,9 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
'--iidfile', path.join(tmpDir, 'iidfile'),
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -512,9 +499,9 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', `type=provenance,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
'--iidfile', path.join(tmpDir, 'iidfile'),
"--provenance", `builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -531,9 +518,9 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', `type=provenance,mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
'--iidfile', path.join(tmpDir, 'iidfile'),
"--provenance", `mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -550,9 +537,9 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', 'type=provenance,disabled=true',
'--metadata-file', metadataJson,
'--iidfile', path.join(tmpDir, 'iidfile'),
"--provenance", 'false',
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -569,9 +556,9 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', 'type=provenance,builder-id=foo',
'--metadata-file', metadataJson,
'--iidfile', path.join(tmpDir, 'iidfile'),
"--provenance", 'builder-id=foo',
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -588,9 +575,9 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
"--output", 'type=docker',
'--metadata-file', metadataJson,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -606,9 +593,9 @@ nproc=3`],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--load',
'--metadata-file', metadataJson,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
@ -626,14 +613,14 @@ nproc=3`],
[
'build',
'--build-arg', 'FOO=bar#baz',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--load',
'--metadata-file', metadataJson,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
[
26,
25,
'0.10.0',
new Map<string, string>([
['context', '.'],
@ -648,14 +635,14 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
'build',
'--secret', 'id=MY_SECRET,env=MY_SECRET_ENV',
'--secret', 'id=ANOTHER_SECRET,env=ANOTHER_SECRET_ENV',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--load',
'--metadata-file', metadataJson,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
[
27,
26,
'0.10.0',
new Map<string, string>([
['context', '.'],
@ -669,14 +656,14 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
'build',
'--secret', 'id=MY_SECRET,env=MY_SECRET_ENV',
'--secret', 'id=ANOTHER_SECRET,env=ANOTHER_SECRET_ENV',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
'--load',
'--metadata-file', metadataJson,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
[
28,
27,
'0.11.0',
new Map<string, string>([
['context', '.'],
@ -690,13 +677,13 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
[
'build',
'--output', 'type=local,dest=./release-out',
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
[
29,
28,
'0.12.0',
new Map<string, string>([
['context', '.'],
@ -714,13 +701,13 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
'--annotation', 'manifest:example3=yyy',
'--annotation', 'manifest-descriptor[linux/amd64]:example4=zzz',
'--output', 'type=local,dest=./release-out',
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
[
30,
29,
'0.12.0',
new Map<string, string>([
['context', '.'],
@ -732,73 +719,13 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
]),
[
'build',
'--iidfile', imageIDFilePath,
'--iidfile', path.join(tmpDir, 'iidfile'),
"--output", `type=image,"name=localhost:5000/name/app:latest,localhost:5000/name/app:foo",push-by-digest=true,name-canonical=true,push=true`,
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
'--metadata-file', path.join(tmpDir, 'metadata-file'),
'.'
]
],
[
31,
'0.13.1',
new Map<string, string>([
['context', '.'],
['load', 'false'],
['no-cache', 'false'],
['push', 'false'],
['pull', 'false'],
['provenance', 'mode=max'],
['sbom', 'true'],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', `type=provenance,mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--attest', `type=sbom,disabled=false`,
'--metadata-file', metadataJson,
'.'
]
],
[
32,
'0.13.1',
new Map<string, string>([
['context', '.'],
['load', 'false'],
['no-cache', 'false'],
['push', 'false'],
['pull', 'false'],
['attests', 'type=provenance,mode=min'],
['provenance', 'mode=max'],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', `type=provenance,mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
'.'
]
],
[
33,
'0.13.1',
new Map<string, string>([
['context', '.'],
['load', 'false'],
['no-cache', 'false'],
['push', 'false'],
['pull', 'false'],
['attests', 'type=provenance,mode=min'],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', `type=provenance,mode=min,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
'.'
]
],
]
])(
'[%d] given %p with %p as inputs, returns %p',
async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {

View File

@ -34,9 +34,6 @@ inputs:
cache-to:
description: "List of cache export destinations for buildx (e.g., user/app:cache, type=local,dest=path/to/dir)"
required: false
call:
description: "Set method for evaluating build (e.g., check)"
required: false
cgroup-parent:
description: "Optional parent cgroup for the container used in the build"
required: false

View File

@ -5,16 +5,9 @@ ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git
WORKDIR /src
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache <<EOT
corepack enable
yarn --version
yarn config set --home enableTelemetry 0
EOT
FROM base AS deps
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
yarn install && mkdir /vendor && cp yarn.lock /vendor
@ -23,19 +16,18 @@ COPY --from=deps /vendor /
FROM deps AS vendor-validate
RUN --mount=type=bind,target=.,rw <<EOT
set -e
git add -A
cp -rf /vendor/* .
if [ -n "$(git status --porcelain -- yarn.lock)" ]; then
echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'
git status --porcelain -- yarn.lock
exit 1
fi
set -e
git add -A
cp -rf /vendor/* .
if [ -n "$(git status --porcelain -- yarn.lock)" ]; then
echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'
git status --porcelain -- yarn.lock
exit 1
fi
EOT
FROM deps AS build
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
yarn run build && mkdir /out && cp -Rf dist /out/
@ -44,35 +36,32 @@ COPY --from=build /out /
FROM build AS build-validate
RUN --mount=type=bind,target=.,rw <<EOT
set -e
git add -A
cp -rf /out/* .
if [ -n "$(git status --porcelain -- dist)" ]; then
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
git status --porcelain -- dist
exit 1
fi
set -e
git add -A
cp -rf /out/* .
if [ -n "$(git status --porcelain -- dist)" ]; then
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
git status --porcelain -- dist
exit 1
fi
EOT
FROM deps AS format
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
yarn run format \
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' -not -path './.yarn/*' | cpio -pdm /out
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out
FROM scratch AS format-update
COPY --from=format /out /
FROM deps AS lint
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
yarn run lint
FROM deps AS test
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
yarn run test --coverage --coverageDirectory=/tmp/coverage

87
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

2065
dist/licenses.txt generated vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,9 @@
target "_common" {
args = {
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
}
}
group "default" {
targets = ["build"]
}
group "pre-checkin" {
targets = ["vendor", "format", "build"]
targets = ["vendor-update", "format", "build"]
}
group "validate" {
@ -17,49 +11,42 @@ group "validate" {
}
target "build" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
target = "build-update"
output = ["."]
}
target "build-validate" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
target = "build-validate"
output = ["type=cacheonly"]
}
target "format" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
target = "format-update"
output = ["."]
}
target "lint" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
target = "lint"
output = ["type=cacheonly"]
}
target "vendor" {
inherits = ["_common"]
target "vendor-update" {
dockerfile = "dev.Dockerfile"
target = "vendor-update"
output = ["."]
}
target "vendor-validate" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
target = "vendor-validate"
output = ["type=cacheonly"]
}
target "test" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
target = "test-coverage"
output = ["./coverage"]

3
docs/advanced/cache.md Normal file
View File

@ -0,0 +1,3 @@
# Cache
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/cache/)

View File

@ -0,0 +1,3 @@
# Copy images between registries
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/copy-image-registries/)

View File

@ -0,0 +1,3 @@
# Update Docker Hub repo description
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/update-dockerhub-desc/)

View File

@ -0,0 +1,3 @@
# Export image to Docker
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/export-docker/)

View File

@ -0,0 +1,3 @@
# Isolated builders
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/configure-builder/#isolated-builders)

View File

@ -0,0 +1,3 @@
# Local registry
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/local-registry/)

View File

@ -0,0 +1,3 @@
# Multi-platform image
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/multi-platform/)

View File

@ -0,0 +1,3 @@
# Named contexts
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/named-contexts/)

View File

@ -0,0 +1,3 @@
# Push to multi-registries
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/push-multi-registries/)

3
docs/advanced/secrets.md Normal file
View File

@ -0,0 +1,3 @@
# Secrets
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/secrets/)

View File

@ -0,0 +1,3 @@
# Share built image between jobs
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/share-image-jobs/)

View File

@ -0,0 +1,3 @@
# Handle tags and labels
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/manage-tags-labels/)

View File

@ -0,0 +1,3 @@
# Test your image before pushing it
This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/test-before-push/)

View File

@ -1,16 +1,17 @@
{
"name": "docker-build-push",
"description": "Build and push Docker images",
"main": "src/main.ts",
"main": "lib/main.js",
"scripts": {
"build": "ncc build --source-map --minify --license licenses.txt",
"build": "ncc build src/main.ts --source-map --minify --license licenses.txt",
"lint": "yarn run prettier && yarn run eslint",
"format": "yarn run prettier:fix && yarn run eslint:fix",
"eslint": "eslint --max-warnings=0 .",
"eslint:fix": "eslint --fix .",
"prettier": "prettier --check \"./**/*.ts\"",
"prettier:fix": "prettier --write \"./**/*.ts\"",
"test": "jest"
"test": "jest",
"all": "yarn run build && yarn run format && yarn test"
},
"repository": {
"type": "git",
@ -24,25 +25,25 @@
],
"author": "Docker Inc.",
"license": "Apache-2.0",
"packageManager": "yarn@3.6.3",
"dependencies": {
"@actions/core": "^1.11.1",
"@docker/actions-toolkit": "0.59.0",
"@actions/core": "^1.10.1",
"@docker/actions-toolkit": "0.18.0",
"handlebars": "^4.7.7"
},
"devDependencies": {
"@types/node": "^20.12.12",
"@typescript-eslint/eslint-plugin": "^7.9.0",
"@typescript-eslint/parser": "^7.9.0",
"@vercel/ncc": "^0.38.1",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jest": "^28.5.0",
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"prettier": "^3.2.5",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"typescript": "^5.4.5"
"@types/csv-parse": "^1.2.2",
"@types/node": "^20.5.9",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"@vercel/ncc": "^0.38.0",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-jest": "^27.2.3",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.6.4",
"prettier": "^3.0.3",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
}
}

View File

@ -1,31 +1,29 @@
import * as core from '@actions/core';
import * as handlebars from 'handlebars';
import {Build} from '@docker/actions-toolkit/lib/buildx/build';
import {Context} from '@docker/actions-toolkit/lib/context';
import {GitHub} from '@docker/actions-toolkit/lib/github';
import {Inputs as BuildxInputs} from '@docker/actions-toolkit/lib/buildx/inputs';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Util} from '@docker/actions-toolkit/lib/util';
export interface Inputs {
'add-hosts': string[];
addHosts: string[];
allow: string[];
annotations: string[];
attests: string[];
'build-args': string[];
'build-contexts': string[];
buildArgs: string[];
buildContexts: string[];
builder: string;
'cache-from': string[];
'cache-to': string[];
call: string;
'cgroup-parent': string;
cacheFrom: string[];
cacheTo: string[];
cgroupParent: string;
context: string;
file: string;
labels: string[];
load: boolean;
network: string;
'no-cache': boolean;
'no-cache-filters': string[];
noCache: boolean;
noCacheFilters: string[];
outputs: string[];
platforms: string[];
provenance: string;
@ -33,51 +31,50 @@ export interface Inputs {
push: boolean;
sbom: string;
secrets: string[];
'secret-envs': string[];
'secret-files': string[];
'shm-size': string;
secretEnvs: string[];
secretFiles: string[];
shmSize: string;
ssh: string[];
tags: string[];
target: string;
ulimit: string[];
'github-token': string;
githubToken: string;
}
export async function getInputs(): Promise<Inputs> {
return {
'add-hosts': Util.getInputList('add-hosts'),
addHosts: Util.getInputList('add-hosts'),
allow: Util.getInputList('allow'),
annotations: Util.getInputList('annotations', {ignoreComma: true}),
attests: Util.getInputList('attests', {ignoreComma: true}),
'build-args': Util.getInputList('build-args', {ignoreComma: true}),
'build-contexts': Util.getInputList('build-contexts', {ignoreComma: true}),
buildArgs: Util.getInputList('build-args', {ignoreComma: true}),
buildContexts: Util.getInputList('build-contexts', {ignoreComma: true}),
builder: core.getInput('builder'),
'cache-from': Util.getInputList('cache-from', {ignoreComma: true}),
'cache-to': Util.getInputList('cache-to', {ignoreComma: true}),
call: core.getInput('call'),
'cgroup-parent': core.getInput('cgroup-parent'),
cacheFrom: Util.getInputList('cache-from', {ignoreComma: true}),
cacheTo: Util.getInputList('cache-to', {ignoreComma: true}),
cgroupParent: core.getInput('cgroup-parent'),
context: core.getInput('context') || Context.gitContext(),
file: core.getInput('file'),
labels: Util.getInputList('labels', {ignoreComma: true}),
load: core.getBooleanInput('load'),
network: core.getInput('network'),
'no-cache': core.getBooleanInput('no-cache'),
'no-cache-filters': Util.getInputList('no-cache-filters'),
noCache: core.getBooleanInput('no-cache'),
noCacheFilters: Util.getInputList('no-cache-filters'),
outputs: Util.getInputList('outputs', {ignoreComma: true, quote: false}),
platforms: Util.getInputList('platforms'),
provenance: Build.getProvenanceInput('provenance'),
provenance: BuildxInputs.getProvenanceInput('provenance'),
pull: core.getBooleanInput('pull'),
push: core.getBooleanInput('push'),
sbom: core.getInput('sbom'),
secrets: Util.getInputList('secrets', {ignoreComma: true}),
'secret-envs': Util.getInputList('secret-envs'),
'secret-files': Util.getInputList('secret-files', {ignoreComma: true}),
'shm-size': core.getInput('shm-size'),
secretEnvs: Util.getInputList('secret-envs'),
secretFiles: Util.getInputList('secret-files', {ignoreComma: true}),
shmSize: core.getInput('shm-size'),
ssh: Util.getInputList('ssh'),
tags: Util.getInputList('tags'),
target: core.getInput('target'),
ulimit: Util.getInputList('ulimit', {ignoreComma: true}),
'github-token': core.getInput('github-token')
githubToken: core.getInput('github-token')
};
}
@ -95,12 +92,19 @@ export async function getArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<s
async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit): Promise<Array<string>> {
const args: Array<string> = ['build'];
await Util.asyncForEach(inputs['add-hosts'], async addHost => {
await Util.asyncForEach(inputs.addHosts, async addHost => {
args.push('--add-host', addHost);
});
await Util.asyncForEach(inputs.allow, async allow => {
args.push('--allow', allow);
});
if (inputs.allow.length > 0) {
args.push('--allow', inputs.allow.join(','));
}
if (await toolkit.buildx.versionSatisfies('>=0.10.0')) {
await Util.asyncForEach(inputs.attests, async attest => {
args.push('--attest', attest);
});
} else if (inputs.attests.length > 0) {
core.warning("Attestations are only supported by buildx >= 0.10.0; the input 'attests' is ignored.");
}
if (await toolkit.buildx.versionSatisfies('>=0.12.0')) {
await Util.asyncForEach(inputs.annotations, async annotation => {
args.push('--annotation', annotation);
@ -108,39 +112,28 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit):
} else if (inputs.annotations.length > 0) {
core.warning("Annotations are only supported by buildx >= 0.12.0; the input 'annotations' is ignored.");
}
await Util.asyncForEach(inputs['build-args'], async buildArg => {
await Util.asyncForEach(inputs.buildArgs, async buildArg => {
args.push('--build-arg', buildArg);
});
if (await toolkit.buildx.versionSatisfies('>=0.8.0')) {
await Util.asyncForEach(inputs['build-contexts'], async buildContext => {
args.push(
'--build-context',
handlebars.compile(buildContext)({
defaultContext: Context.gitContext()
})
);
await Util.asyncForEach(inputs.buildContexts, async buildContext => {
args.push('--build-context', buildContext);
});
} else if (inputs['build-contexts'].length > 0) {
} else if (inputs.buildContexts.length > 0) {
core.warning("Build contexts are only supported by buildx >= 0.8.0; the input 'build-contexts' is ignored.");
}
await Util.asyncForEach(inputs['cache-from'], async cacheFrom => {
await Util.asyncForEach(inputs.cacheFrom, async cacheFrom => {
args.push('--cache-from', cacheFrom);
});
await Util.asyncForEach(inputs['cache-to'], async cacheTo => {
await Util.asyncForEach(inputs.cacheTo, async cacheTo => {
args.push('--cache-to', cacheTo);
});
if (inputs.call) {
if (!(await toolkit.buildx.versionSatisfies('>=0.15.0'))) {
throw new Error(`Buildx >= 0.15.0 is required to use the call flag.`);
}
args.push('--call', inputs.call);
if (inputs.cgroupParent) {
args.push('--cgroup-parent', inputs.cgroupParent);
}
if (inputs['cgroup-parent']) {
args.push('--cgroup-parent', inputs['cgroup-parent']);
}
await Util.asyncForEach(inputs['secret-envs'], async secretEnv => {
await Util.asyncForEach(inputs.secretEnvs, async secretEnv => {
try {
args.push('--secret', Build.resolveSecretEnv(secretEnv));
args.push('--secret', BuildxInputs.resolveBuildSecretEnv(secretEnv));
} catch (err) {
core.warning(err.message);
}
@ -148,13 +141,13 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit):
if (inputs.file) {
args.push('--file', inputs.file);
}
if (!Build.hasLocalExporter(inputs.outputs) && !Build.hasTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || (await toolkit.buildx.versionSatisfies('>=0.4.2')))) {
args.push('--iidfile', toolkit.buildxBuild.getImageIDFilePath());
if (!BuildxInputs.hasLocalExporter(inputs.outputs) && !BuildxInputs.hasTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || (await toolkit.buildx.versionSatisfies('>=0.4.2')))) {
args.push('--iidfile', BuildxInputs.getBuildImageIDFilePath());
}
await Util.asyncForEach(inputs.labels, async label => {
args.push('--label', label);
});
await Util.asyncForEach(inputs['no-cache-filters'], async noCacheFilter => {
await Util.asyncForEach(inputs.noCacheFilters, async noCacheFilter => {
args.push('--no-cache-filter', noCacheFilter);
});
await Util.asyncForEach(inputs.outputs, async output => {
@ -164,29 +157,46 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit):
args.push('--platform', inputs.platforms.join(','));
}
if (await toolkit.buildx.versionSatisfies('>=0.10.0')) {
args.push(...(await getAttestArgs(inputs, toolkit)));
} else {
core.warning("Attestations are only supported by buildx >= 0.10.0; the inputs 'attests', 'provenance' and 'sbom' are ignored.");
if (inputs.provenance) {
args.push('--provenance', inputs.provenance);
} else if ((await toolkit.buildkit.versionSatisfies(inputs.builder, '>=0.11.0')) && !BuildxInputs.hasDockerExporter(inputs.outputs, inputs.load)) {
// if provenance not specified and BuildKit version compatible for
// attestation, set default provenance. Also needs to make sure user
// doesn't want to explicitly load the image to docker.
if (GitHub.context.payload.repository?.private ?? false) {
// if this is a private repository, we set the default provenance
// attributes being set in buildx: https://github.com/docker/buildx/blob/fb27e3f919dcbf614d7126b10c2bc2d0b1927eb6/build/build.go#L603
args.push('--provenance', BuildxInputs.resolveProvenanceAttrs(`mode=min,inline-only=true`));
} else {
// for a public repository, we set max provenance mode.
args.push('--provenance', BuildxInputs.resolveProvenanceAttrs(`mode=max`));
}
}
if (inputs.sbom) {
args.push('--sbom', inputs.sbom);
}
} else if (inputs.provenance || inputs.sbom) {
core.warning("Attestations are only supported by buildx >= 0.10.0; the inputs 'provenance' and 'sbom' are ignored.");
}
await Util.asyncForEach(inputs.secrets, async secret => {
try {
args.push('--secret', Build.resolveSecretString(secret));
args.push('--secret', BuildxInputs.resolveBuildSecretString(secret));
} catch (err) {
core.warning(err.message);
}
});
await Util.asyncForEach(inputs['secret-files'], async secretFile => {
await Util.asyncForEach(inputs.secretFiles, async secretFile => {
try {
args.push('--secret', Build.resolveSecretFile(secretFile));
args.push('--secret', BuildxInputs.resolveBuildSecretFile(secretFile));
} catch (err) {
core.warning(err.message);
}
});
if (inputs['github-token'] && !Build.hasGitAuthTokenSecret(inputs.secrets) && context.startsWith(Context.gitContext())) {
args.push('--secret', Build.resolveSecretString(`GIT_AUTH_TOKEN=${inputs['github-token']}`));
if (inputs.githubToken && !BuildxInputs.hasGitAuthTokenSecret(inputs.secrets) && context.startsWith(Context.gitContext())) {
args.push('--secret', BuildxInputs.resolveBuildSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
}
if (inputs['shm-size']) {
args.push('--shm-size', inputs['shm-size']);
if (inputs.shmSize) {
args.push('--shm-size', inputs.shmSize);
}
await Util.asyncForEach(inputs.ssh, async ssh => {
args.push('--ssh', ssh);
@ -212,12 +222,12 @@ async function getCommonArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<st
args.push('--load');
}
if (await toolkit.buildx.versionSatisfies('>=0.6.0')) {
args.push('--metadata-file', toolkit.buildxBuild.getMetadataFilePath());
args.push('--metadata-file', BuildxInputs.getBuildMetadataFilePath());
}
if (inputs.network) {
args.push('--network', inputs.network);
}
if (inputs['no-cache']) {
if (inputs.noCache) {
args.push('--no-cache');
}
if (inputs.pull) {
@ -228,52 +238,3 @@ async function getCommonArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<st
}
return args;
}
async function getAttestArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
const args: Array<string> = [];
// check if provenance attestation is set in attests input
let hasAttestProvenance = false;
await Util.asyncForEach(inputs.attests, async (attest: string) => {
if (Build.hasAttestationType('provenance', attest)) {
hasAttestProvenance = true;
}
});
let provenanceSet = false;
let sbomSet = false;
if (inputs.provenance) {
args.push('--attest', Build.resolveAttestationAttrs(`type=provenance,${inputs.provenance}`));
provenanceSet = true;
} else if (!hasAttestProvenance && (await toolkit.buildkit.versionSatisfies(inputs.builder, '>=0.11.0')) && !Build.hasDockerExporter(inputs.outputs, inputs.load)) {
// if provenance not specified in provenance or attests inputs and BuildKit
// version compatible for attestation, set default provenance. Also needs
// to make sure user doesn't want to explicitly load the image to docker.
if (GitHub.context.payload.repository?.private ?? false) {
// if this is a private repository, we set the default provenance
// attributes being set in buildx: https://github.com/docker/buildx/blob/fb27e3f919dcbf614d7126b10c2bc2d0b1927eb6/build/build.go#L603
args.push('--attest', `type=provenance,${Build.resolveProvenanceAttrs(`mode=min,inline-only=true`)}`);
} else {
// for a public repository, we set max provenance mode.
args.push('--attest', `type=provenance,${Build.resolveProvenanceAttrs(`mode=max`)}`);
}
}
if (inputs.sbom) {
args.push('--attest', Build.resolveAttestationAttrs(`type=sbom,${inputs.sbom}`));
sbomSet = true;
}
// set attests but check if provenance or sbom types already set as
// provenance and sbom inputs take precedence over attests input.
await Util.asyncForEach(inputs.attests, async (attest: string) => {
if (!Build.hasAttestationType('provenance', attest) && !Build.hasAttestationType('sbom', attest)) {
args.push('--attest', Build.resolveAttestationAttrs(attest));
} else if (!provenanceSet && Build.hasAttestationType('provenance', attest)) {
args.push('--attest', Build.resolveProvenanceAttrs(attest));
} else if (!sbomSet && Build.hasAttestationType('sbom', attest)) {
args.push('--attest', attest);
}
});
return args;
}

View File

@ -3,28 +3,20 @@ import * as path from 'path';
import * as stateHelper from './state-helper';
import * as core from '@actions/core';
import * as actionsToolkit from '@docker/actions-toolkit';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
import {History as BuildxHistory} from '@docker/actions-toolkit/lib/buildx/history';
import {Context} from '@docker/actions-toolkit/lib/context';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Exec} from '@docker/actions-toolkit/lib/exec';
import {GitHub} from '@docker/actions-toolkit/lib/github';
import {Inputs as BuildxInputs} from '@docker/actions-toolkit/lib/buildx/inputs';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Util} from '@docker/actions-toolkit/lib/util';
import {BuilderInfo} from '@docker/actions-toolkit/lib/types/buildx/builder';
import {ConfigFile} from '@docker/actions-toolkit/lib/types/docker/docker';
import {UploadArtifactResponse} from '@docker/actions-toolkit/lib/types/github';
import {ConfigFile} from '@docker/actions-toolkit/lib/types/docker';
import * as context from './context';
actionsToolkit.run(
// main
async () => {
const startedTime = new Date();
const inputs: context.Inputs = await context.getInputs();
stateHelper.setSummaryInputs(inputs);
core.debug(`inputs: ${JSON.stringify(inputs)}`);
const toolkit = new Toolkit();
@ -82,12 +74,6 @@ actionsToolkit.run(
await toolkit.buildx.printVersion();
});
let builder: BuilderInfo;
await core.group(`Builder info`, async () => {
builder = await toolkit.builder.inspect(inputs.builder);
core.info(JSON.stringify(builder, null, 2));
});
const args: string[] = await context.getArgs(inputs, toolkit);
core.debug(`context.getArgs: ${JSON.stringify(args)}`);
@ -95,29 +81,18 @@ actionsToolkit.run(
core.debug(`buildCmd.command: ${buildCmd.command}`);
core.debug(`buildCmd.args: ${JSON.stringify(buildCmd.args)}`);
let err: Error | undefined;
await Exec.getExecOutput(buildCmd.command, buildCmd.args, {
ignoreReturnCode: true,
env: Object.assign({}, process.env, {
BUILDX_METADATA_WARNINGS: 'true'
}) as {
[key: string]: string;
}
ignoreReturnCode: true
}).then(res => {
if (res.exitCode != 0) {
if (inputs.call && inputs.call === 'check' && res.stdout.length > 0) {
// checks warnings are printed to stdout: https://github.com/docker/buildx/pull/2647
// take the first line with the message summaryzing the warnings
err = new Error(res.stdout.split('\n')[0]?.trim());
} else if (res.stderr.length > 0) {
err = new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
}
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
}
});
const imageID = toolkit.buildxBuild.resolveImageID();
const metadata = toolkit.buildxBuild.resolveMetadata();
const digest = toolkit.buildxBuild.resolveDigest(metadata);
const imageID = BuildxInputs.resolveBuildImageID();
const metadata = BuildxInputs.resolveBuildMetadata();
const digest = BuildxInputs.resolveDigest();
if (imageID) {
await core.group(`ImageID`, async () => {
core.info(imageID);
@ -132,165 +107,17 @@ actionsToolkit.run(
}
if (metadata) {
await core.group(`Metadata`, async () => {
const metadatadt = JSON.stringify(metadata, null, 2);
core.info(metadatadt);
core.setOutput('metadata', metadatadt);
core.info(metadata);
core.setOutput('metadata', metadata);
});
}
let ref: string | undefined;
await core.group(`Reference`, async () => {
ref = await buildRef(toolkit, startedTime, inputs.builder);
if (ref) {
core.info(ref);
stateHelper.setBuildRef(ref);
} else {
core.info('No build reference found');
}
});
if (buildChecksAnnotationsEnabled()) {
const warnings = toolkit.buildxBuild.resolveWarnings(metadata);
if (ref && warnings && warnings.length > 0) {
const annotations = await Buildx.convertWarningsToGitHubAnnotations(warnings, [ref]);
core.debug(`annotations: ${JSON.stringify(annotations, null, 2)}`);
if (annotations && annotations.length > 0) {
await core.group(`Generating GitHub annotations (${annotations.length} build checks found)`, async () => {
for (const annotation of annotations) {
core.warning(annotation.message, annotation);
}
});
}
}
}
await core.group(`Check build summary support`, async () => {
if (!buildSummaryEnabled()) {
core.info('Build summary disabled');
} else if (inputs.call && inputs.call !== 'build') {
core.info(`Build summary skipped for ${inputs.call} subrequest`);
} else if (GitHub.isGHES) {
core.info('Build summary is not yet supported on GHES');
} else if (!(await toolkit.buildx.versionSatisfies('>=0.13.0'))) {
core.info('Build summary requires Buildx >= 0.13.0');
} else if (builder && builder.driver === 'cloud') {
core.info('Build summary is not yet supported with Docker Build Cloud');
} else if (!ref) {
core.info('Build summary requires a build reference');
} else {
core.info('Build summary supported!');
stateHelper.setSummarySupported();
}
});
if (err) {
throw err;
}
},
// post
async () => {
if (stateHelper.isSummarySupported) {
await core.group(`Generating build summary`, async () => {
try {
const recordUploadEnabled = buildRecordUploadEnabled();
let recordRetentionDays: number | undefined;
if (recordUploadEnabled) {
recordRetentionDays = buildRecordRetentionDays();
}
const buildxHistory = new BuildxHistory();
const exportRes = await buildxHistory.export({
refs: stateHelper.buildRef ? [stateHelper.buildRef] : []
});
core.info(`Build record written to ${exportRes.dockerbuildFilename} (${Util.formatFileSize(exportRes.dockerbuildSize)})`);
let uploadRes: UploadArtifactResponse | undefined;
if (recordUploadEnabled) {
uploadRes = await GitHub.uploadArtifact({
filename: exportRes.dockerbuildFilename,
mimeType: 'application/gzip',
retentionDays: recordRetentionDays
});
}
await GitHub.writeBuildSummary({
exportRes: exportRes,
uploadRes: uploadRes,
inputs: stateHelper.summaryInputs
});
} catch (e) {
core.warning(e.message);
}
});
}
if (stateHelper.tmpDir.length > 0) {
await core.group(`Removing temp folder ${stateHelper.tmpDir}`, async () => {
try {
fs.rmSync(stateHelper.tmpDir, {recursive: true});
} catch (e) {
core.warning(`Failed to remove temp folder ${stateHelper.tmpDir}`);
}
fs.rmSync(stateHelper.tmpDir, {recursive: true});
});
}
}
);
async function buildRef(toolkit: Toolkit, since: Date, builder?: string): Promise<string> {
// get ref from metadata file
const ref = toolkit.buildxBuild.resolveRef();
if (ref) {
return ref;
}
// otherwise, look for the very first build ref since the build has started
if (!builder) {
const currentBuilder = await toolkit.builder.inspect();
builder = currentBuilder.name;
}
const refs = Buildx.refs({
dir: Buildx.refsDir,
builderName: builder,
since: since
});
return Object.keys(refs).length > 0 ? Object.keys(refs)[0] : '';
}
function buildChecksAnnotationsEnabled(): boolean {
if (process.env.DOCKER_BUILD_CHECKS_ANNOTATIONS) {
return Util.parseBool(process.env.DOCKER_BUILD_CHECKS_ANNOTATIONS);
}
return true;
}
function buildSummaryEnabled(): boolean {
if (process.env.DOCKER_BUILD_NO_SUMMARY) {
core.warning('DOCKER_BUILD_NO_SUMMARY is deprecated. Set DOCKER_BUILD_SUMMARY to false instead.');
return !Util.parseBool(process.env.DOCKER_BUILD_NO_SUMMARY);
} else if (process.env.DOCKER_BUILD_SUMMARY) {
return Util.parseBool(process.env.DOCKER_BUILD_SUMMARY);
}
return true;
}
function buildRecordUploadEnabled(): boolean {
if (process.env.DOCKER_BUILD_RECORD_UPLOAD) {
return Util.parseBool(process.env.DOCKER_BUILD_RECORD_UPLOAD);
}
return true;
}
function buildRecordRetentionDays(): number | undefined {
let val: string | undefined;
if (process.env.DOCKER_BUILD_EXPORT_RETENTION_DAYS) {
core.warning('DOCKER_BUILD_EXPORT_RETENTION_DAYS is deprecated. Use DOCKER_BUILD_RECORD_RETENTION_DAYS instead.');
val = process.env.DOCKER_BUILD_EXPORT_RETENTION_DAYS;
} else if (process.env.DOCKER_BUILD_RECORD_RETENTION_DAYS) {
val = process.env.DOCKER_BUILD_RECORD_RETENTION_DAYS;
}
if (val) {
const res = parseInt(val);
if (isNaN(res)) {
throw new Error(`Invalid build record retention days: ${val}`);
}
return res;
}
}

View File

@ -1,58 +1,7 @@
import * as core from '@actions/core';
import {Build} from '@docker/actions-toolkit/lib/buildx/build';
import {Inputs} from './context';
export const tmpDir = process.env['STATE_tmpDir'] || '';
export const buildRef = process.env['STATE_buildRef'] || '';
export const isSummarySupported = !!process.env['STATE_isSummarySupported'];
export const summaryInputs = process.env['STATE_summaryInputs'] ? JSON.parse(process.env['STATE_summaryInputs']) : undefined;
export function setTmpDir(tmpDir: string) {
core.saveState('tmpDir', tmpDir);
}
export function setBuildRef(buildRef: string) {
core.saveState('buildRef', buildRef);
}
export function setSummarySupported() {
core.saveState('isSummarySupported', 'true');
}
export function setSummaryInputs(inputs: Inputs) {
const res = {};
for (const key of Object.keys(inputs)) {
if (key === 'github-token') {
continue;
}
const value: string | string[] | boolean = inputs[key];
if (typeof value === 'boolean' && !value) {
continue;
} else if (Array.isArray(value)) {
if (value.length === 0) {
continue;
} else if (key === 'secrets' && value.length > 0) {
const secretKeys: string[] = [];
for (const secret of value) {
try {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [skey, _] = Build.parseSecretKvp(secret, true);
secretKeys.push(skey);
} catch (err) {
// ignore invalid secret
}
}
if (secretKeys.length > 0) {
res[key] = secretKeys;
}
continue;
}
} else if (!value) {
continue;
}
res[key] = value;
}
core.saveState('summaryInputs', JSON.stringify(res));
}

View File

@ -1,12 +0,0 @@
frOM busybox as base
cOpy lint.Dockerfile .
from scratch
MAINTAINER moby@example.com
COPy --from=base \
/lint.Dockerfile \
/
CMD [ "echo", "Hello, Norway!" ]
CMD [ "echo", "Hello, Sweden!" ]
ENTRYPOINT my-program start

View File

@ -1,6 +1,5 @@
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM alpine AS build
FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
@ -13,7 +12,7 @@ RUN apk --update --no-cache add \
&& rm -rf /tmp/* /var/cache/apk/*
USER buildx
RUN sudo chown buildx: /log
RUN sudo chown buildx. /log
USER root
FROM alpine

10860
yarn.lock

File diff suppressed because it is too large Load Diff