mirror of
https://github.com/docker/build-push-action.git
synced 2025-06-13 22:57:12 +02:00
Compare commits
81 Commits
Author | SHA1 | Date | |
---|---|---|---|
7f9d37fa54 | |||
d7458455bb | |||
1ca185b339 | |||
eebf87aed1 | |||
d8b0ca6f0e | |||
da767377fb | |||
8c76bb76c2 | |||
b598b2a3bd | |||
eb2857f4ca | |||
f4cf574474 | |||
5c924147ba | |||
253376207c | |||
6f7a604875 | |||
604f033158 | |||
5645ea7274 | |||
1814d3dfb3 | |||
fc5a732e0c | |||
b1aeb1103e | |||
e31f93ab9f | |||
9ed5823618 | |||
4222161e3e | |||
67ff4df4b7 | |||
91274a04da | |||
ff329397c0 | |||
04841f2a72 | |||
049b7cab08 | |||
0a196c9deb | |||
94e0a28d6a | |||
5e11b373bf | |||
6f3b90dea1 | |||
f71a68fb09 | |||
82446970f9 | |||
2cf7b61533 | |||
0732bea0f8 | |||
96daefdf52 | |||
9f46d13e71 | |||
a8f79af565 | |||
04d5124fcb | |||
541dfa92f4 | |||
291bae5a41 | |||
91520dfd9f | |||
a41d90ba13 | |||
22baeb6cdf | |||
6061a365d8 | |||
9962be8aaf | |||
375f72aff6 | |||
8ba85ead00 | |||
c6dca826de | |||
0c3d31c275 | |||
5681933133 | |||
821890eae4 | |||
d0931a71a9 | |||
326ec1ede4 | |||
b0c26e5619 | |||
3139e8d280 | |||
a66e35b9cb | |||
6a98f97e24 | |||
26f24d6851 | |||
b0b7751850 | |||
c0b121fe44 | |||
09d66c261a | |||
24d162ecb4 | |||
6484a61448 | |||
c40e0ee07a | |||
e06a3af40d | |||
2e10e1984b | |||
1a60e0d706 | |||
3530a97c47 | |||
3c507bedc4 | |||
7c64fd5e10 | |||
c65ff7ffb1 | |||
2a8d638779 | |||
900c06250b | |||
b5e5b85e1b | |||
cf25934f0f | |||
37831a7a20 | |||
ad1d2e93be | |||
e80adc3299 | |||
7594ecce5b | |||
1bc1040cae | |||
fcaaa5e487 |
BIN
.github/build-push-action.png
vendored
BIN
.github/build-push-action.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 19 KiB |
196
.github/workflows/ci.yml
vendored
196
.github/workflows/ci.yml
vendored
@ -4,10 +4,10 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- 'master'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- 'master'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
minimal:
|
minimal:
|
||||||
@ -70,9 +70,6 @@ jobs:
|
|||||||
name: Inspect
|
name: Inspect
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
||||||
-
|
|
||||||
name: Image digest
|
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
|
||||||
-
|
-
|
||||||
name: Check digest
|
name: Check digest
|
||||||
run: |
|
run: |
|
||||||
@ -133,9 +130,6 @@ jobs:
|
|||||||
name: Inspect
|
name: Inspect
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
||||||
-
|
|
||||||
name: Image digest
|
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
|
||||||
-
|
-
|
||||||
name: Check digest
|
name: Check digest
|
||||||
run: |
|
run: |
|
||||||
@ -191,9 +185,6 @@ jobs:
|
|||||||
name: Inspect
|
name: Inspect
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
||||||
-
|
|
||||||
name: Image digest
|
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
|
||||||
-
|
-
|
||||||
name: Check digest
|
name: Check digest
|
||||||
run: |
|
run: |
|
||||||
@ -345,6 +336,110 @@ jobs:
|
|||||||
if: always()
|
if: always()
|
||||||
uses: crazy-max/ghaction-dump-context@v1
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
|
||||||
|
shm-size:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
with:
|
||||||
|
version: v0.7.0
|
||||||
|
driver-opts: |
|
||||||
|
image=moby/buildkit:master
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
context: ./test
|
||||||
|
file: ./test/shmsize.Dockerfile
|
||||||
|
tags: name/app:latest
|
||||||
|
shm-size: 2g
|
||||||
|
-
|
||||||
|
name: Dump context
|
||||||
|
if: always()
|
||||||
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
|
||||||
|
ulimit:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
with:
|
||||||
|
version: v0.7.0
|
||||||
|
driver-opts: |
|
||||||
|
image=moby/buildkit:master
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
context: ./test
|
||||||
|
file: ./test/ulimit.Dockerfile
|
||||||
|
tags: name/app:latest
|
||||||
|
ulimit: |
|
||||||
|
nofile=1024:1024
|
||||||
|
nproc=3
|
||||||
|
-
|
||||||
|
name: Dump context
|
||||||
|
if: always()
|
||||||
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
|
||||||
|
cgroup-parent:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
with:
|
||||||
|
version: v0.7.0
|
||||||
|
driver-opts: |
|
||||||
|
image=moby/buildkit:master
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
context: ./test
|
||||||
|
file: ./test/cgroup.Dockerfile
|
||||||
|
tags: name/app:latest
|
||||||
|
cgroup-parent: foo
|
||||||
|
-
|
||||||
|
name: Dump context
|
||||||
|
if: always()
|
||||||
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
|
||||||
|
add-hosts:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
context: ./test
|
||||||
|
file: ./test/addhost.Dockerfile
|
||||||
|
tags: name/app:latest
|
||||||
|
add-hosts: |
|
||||||
|
docker:10.180.0.1
|
||||||
|
foo:10.0.0.1
|
||||||
|
-
|
||||||
|
name: Dump context
|
||||||
|
if: always()
|
||||||
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
|
||||||
multi:
|
multi:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
@ -392,9 +487,6 @@ jobs:
|
|||||||
name: Inspect
|
name: Inspect
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
||||||
-
|
|
||||||
name: Image digest
|
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
|
||||||
-
|
-
|
||||||
name: Check digest
|
name: Check digest
|
||||||
run: |
|
run: |
|
||||||
@ -447,9 +539,6 @@ jobs:
|
|||||||
name: Inspect (1)
|
name: Inspect (1)
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect localhost:5000/name/app:latest
|
docker buildx imagetools inspect localhost:5000/name/app:latest
|
||||||
-
|
|
||||||
name: Image digest (1)
|
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
|
||||||
-
|
-
|
||||||
name: Check digest (1)
|
name: Check digest (1)
|
||||||
run: |
|
run: |
|
||||||
@ -480,9 +569,6 @@ jobs:
|
|||||||
name: Inspect (2)
|
name: Inspect (2)
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect localhost:5000/name/app:latest
|
docker buildx imagetools inspect localhost:5000/name/app:latest
|
||||||
-
|
|
||||||
name: Image digest (2)
|
|
||||||
run: echo ${{ steps.docker_build2.outputs.digest }}
|
|
||||||
-
|
-
|
||||||
name: Check digest (2)
|
name: Check digest (2)
|
||||||
run: |
|
run: |
|
||||||
@ -503,7 +589,7 @@ jobs:
|
|||||||
if: always()
|
if: always()
|
||||||
uses: crazy-max/ghaction-dump-context@v1
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
|
||||||
github-cache-first:
|
local-cache-first:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
digest: ${{ steps.docker_build.outputs.digest }}
|
digest: ${{ steps.docker_build.outputs.digest }}
|
||||||
@ -531,7 +617,7 @@ jobs:
|
|||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: /tmp/.buildx-cache
|
path: /tmp/.buildx-cache
|
||||||
key: ${{ runner.os }}-buildx-ghcache-${{ github.sha }}
|
key: ${{ runner.os }}-buildx-local-${{ github.sha }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-buildx-ghcache-
|
${{ runner.os }}-buildx-ghcache-
|
||||||
-
|
-
|
||||||
@ -557,9 +643,6 @@ jobs:
|
|||||||
name: Inspect
|
name: Inspect
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
||||||
-
|
|
||||||
name: Image digest
|
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
|
||||||
-
|
-
|
||||||
name: Check digest
|
name: Check digest
|
||||||
run: |
|
run: |
|
||||||
@ -572,9 +655,9 @@ jobs:
|
|||||||
if: always()
|
if: always()
|
||||||
uses: crazy-max/ghaction-dump-context@v1
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
|
||||||
github-cache-hit:
|
local-cache-hit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: github-cache-first
|
needs: local-cache-first
|
||||||
services:
|
services:
|
||||||
registry:
|
registry:
|
||||||
image: registry:2
|
image: registry:2
|
||||||
@ -600,7 +683,7 @@ jobs:
|
|||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: /tmp/.buildx-cache
|
path: /tmp/.buildx-cache
|
||||||
key: ${{ runner.os }}-buildx-ghcache-${{ github.sha }}
|
key: ${{ runner.os }}-buildx-local-${{ github.sha }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-buildx-ghcache-
|
${{ runner.os }}-buildx-ghcache-
|
||||||
-
|
-
|
||||||
@ -622,9 +705,6 @@ jobs:
|
|||||||
name: Inspect
|
name: Inspect
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
||||||
-
|
|
||||||
name: Image digest
|
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
|
||||||
-
|
-
|
||||||
name: Check digest
|
name: Check digest
|
||||||
run: |
|
run: |
|
||||||
@ -635,8 +715,8 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: Compare digests
|
name: Compare digests
|
||||||
run: |
|
run: |
|
||||||
echo Compare "${{ needs.github-cache-first.outputs.digest }}" with "${{ steps.docker_build.outputs.digest }}"
|
echo Compare "${{ needs.local-cache-first.outputs.digest }}" with "${{ steps.docker_build.outputs.digest }}"
|
||||||
if [ "${{ needs.github-cache-first.outputs.digest }}" != "${{ steps.docker_build.outputs.digest }}" ]; then
|
if [ "${{ needs.local-cache-first.outputs.digest }}" != "${{ steps.docker_build.outputs.digest }}" ]; then
|
||||||
echo "::error::Digests should be identical"
|
echo "::error::Digests should be identical"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@ -647,3 +727,53 @@ jobs:
|
|||||||
name: Dump context
|
name: Dump context
|
||||||
if: always()
|
if: always()
|
||||||
uses: crazy-max/ghaction-dump-context@v1
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
|
||||||
|
github-cache:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
buildx_version:
|
||||||
|
- ""
|
||||||
|
- latest
|
||||||
|
services:
|
||||||
|
registry:
|
||||||
|
image: registry:2
|
||||||
|
ports:
|
||||||
|
- 5000:5000
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
with:
|
||||||
|
version: ${{ matrix.buildx_version }}
|
||||||
|
driver-opts: |
|
||||||
|
network=host
|
||||||
|
buildkitd-flags: --debug
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
context: ./test
|
||||||
|
file: ./test/multi.Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
localhost:5000/name/app:latest
|
||||||
|
localhost:5000/name/app:1.0.0
|
||||||
|
cache-from: type=gha,scope=ci-${{ matrix.buildx_version }}
|
||||||
|
cache-to: type=gha,scope=ci-${{ matrix.buildx_version }}
|
||||||
|
-
|
||||||
|
name: Inspect
|
||||||
|
run: |
|
||||||
|
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
|
||||||
|
-
|
||||||
|
name: Dump context
|
||||||
|
if: always()
|
||||||
|
uses: crazy-max/ghaction-dump-context@v1
|
||||||
|
9
.github/workflows/e2e.yml
vendored
9
.github/workflows/e2e.yml
vendored
@ -3,10 +3,10 @@ name: e2e
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 10 * * *' # everyday at 10am
|
- cron: '0 10 * * *'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- 'master'
|
||||||
tags:
|
tags:
|
||||||
- v*
|
- v*
|
||||||
|
|
||||||
@ -52,6 +52,11 @@ jobs:
|
|||||||
slug: gcr.io/sandbox-298914/test-docker-action
|
slug: gcr.io/sandbox-298914/test-docker-action
|
||||||
username_secret: GCR_USERNAME
|
username_secret: GCR_USERNAME
|
||||||
password_secret: GCR_JSON_KEY
|
password_secret: GCR_JSON_KEY
|
||||||
|
-
|
||||||
|
registry: officialgithubactions.azurecr.io
|
||||||
|
slug: officialgithubactions.azurecr.io/test-docker-action
|
||||||
|
username_secret: AZURE_CLIENT_ID
|
||||||
|
password_secret: AZURE_CLIENT_SECRET
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
|
4
.github/workflows/example.yml
vendored
4
.github/workflows/example.yml
vendored
@ -1,9 +1,9 @@
|
|||||||
# This workflow is provided just as an usage example and not for repo testing/verification
|
# This workflow is provided just as an example and not for repo testing/verification
|
||||||
name: example
|
name: example
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 10 * * 0' # everyday sunday at 10am
|
- cron: '0 10 * * 0'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- '**'
|
||||||
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -27,6 +27,6 @@ jobs:
|
|||||||
targets: test
|
targets: test
|
||||||
-
|
-
|
||||||
name: Upload coverage
|
name: Upload coverage
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
file: ./coverage/clover.xml
|
file: ./coverage/clover.xml
|
||||||
|
9
.github/workflows/virtual-env.yml
vendored
9
.github/workflows/virtual-env.yml
vendored
@ -3,7 +3,7 @@ name: virtual-env
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 10 * * *' # everyday at 10am
|
- cron: '0 10 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
os:
|
os:
|
||||||
@ -15,8 +15,10 @@ jobs:
|
|||||||
- ubuntu-latest
|
- ubuntu-latest
|
||||||
- ubuntu-20.04
|
- ubuntu-20.04
|
||||||
- ubuntu-18.04
|
- ubuntu-18.04
|
||||||
- ubuntu-16.04
|
|
||||||
steps:
|
steps:
|
||||||
|
-
|
||||||
|
name: File system
|
||||||
|
run: df -ah
|
||||||
-
|
-
|
||||||
name: List install packages
|
name: List install packages
|
||||||
run: apt list --installed
|
run: apt list --installed
|
||||||
@ -32,6 +34,9 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: containerd version
|
name: containerd version
|
||||||
run: containerd --version
|
run: containerd --version
|
||||||
|
-
|
||||||
|
name: Docker images
|
||||||
|
run: docker image ls
|
||||||
-
|
-
|
||||||
name: Dump context
|
name: Dump context
|
||||||
if: always()
|
if: always()
|
||||||
|
107
README.md
107
README.md
@ -4,15 +4,6 @@
|
|||||||
[](https://github.com/docker/build-push-action/actions?workflow=test)
|
[](https://github.com/docker/build-push-action/actions?workflow=test)
|
||||||
[](https://codecov.io/gh/docker/build-push-action)
|
[](https://codecov.io/gh/docker/build-push-action)
|
||||||
|
|
||||||
## Upgrade from v1
|
|
||||||
|
|
||||||
`v2` of this action includes significant updates and now uses Docker [Buildx](https://github.com/docker/buildx). It's
|
|
||||||
also rewritten as a [typescript-action](https://github.com/actions/typescript-action/) to be as close as possible
|
|
||||||
of the [GitHub Runner](https://github.com/actions/virtual-environments) during its execution.
|
|
||||||
|
|
||||||
[Upgrade notes](UPGRADE.md) with many [usage examples](#advanced-usage) have been added to handle most use cases but
|
|
||||||
`v1` is still available through [`releases/v1` branch](https://github.com/docker/build-push-action/tree/releases/v1).
|
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
GitHub Action to build and push Docker images with [Buildx](https://github.com/docker/buildx) with full support of the
|
GitHub Action to build and push Docker images with [Buildx](https://github.com/docker/buildx) with full support of the
|
||||||
@ -33,11 +24,10 @@ ___
|
|||||||
* [Push to multi-registries](docs/advanced/push-multi-registries.md)
|
* [Push to multi-registries](docs/advanced/push-multi-registries.md)
|
||||||
* [Copy between registries](docs/advanced/copy-between-registries.md)
|
* [Copy between registries](docs/advanced/copy-between-registries.md)
|
||||||
* [Cache](docs/advanced/cache.md)
|
* [Cache](docs/advanced/cache.md)
|
||||||
* [Registry cache](docs/advanced/cache.md#registry-cache)
|
|
||||||
* [GitHub cache](docs/advanced/cache.md#github-cache)
|
|
||||||
* [Local registry](docs/advanced/local-registry.md)
|
* [Local registry](docs/advanced/local-registry.md)
|
||||||
* [Export image to Docker](docs/advanced/export-docker.md)
|
* [Export image to Docker](docs/advanced/export-docker.md)
|
||||||
* [Share built image between jobs](docs/advanced/share-image-jobs.md)
|
* [Share built image between jobs](docs/advanced/share-image-jobs.md)
|
||||||
|
* [Test your image before pushing it](docs/advanced/test-before-push.md)
|
||||||
* [Handle tags and labels](docs/advanced/tags-labels.md)
|
* [Handle tags and labels](docs/advanced/tags-labels.md)
|
||||||
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md)
|
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md)
|
||||||
* [Customizing](#customizing)
|
* [Customizing](#customizing)
|
||||||
@ -48,17 +38,7 @@ ___
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
By default, this action uses the [Git context](#git-context) so you don't need to use the
|
In the examples below we are also using 3 other actions:
|
||||||
[`actions/checkout`](https://github.com/actions/checkout/) action to checkout the repository because this will be
|
|
||||||
done directly by buildkit. The git reference will be based on the [event that triggered your workflow](https://docs.github.com/en/actions/reference/events-that-trigger-workflows)
|
|
||||||
and will result in the following context: `https://github.com/<owner>/<repo>.git#<ref>`.
|
|
||||||
|
|
||||||
Be careful because **any file mutation in the steps that precede the build step will be ignored** since
|
|
||||||
the context is based on the git reference. However, you can use the [Path context](#path-context) using the
|
|
||||||
[`context` input](#inputs) alongside the [`actions/checkout`](https://github.com/actions/checkout/) action to remove
|
|
||||||
this restriction.
|
|
||||||
|
|
||||||
In the examples below we are using 3 other actions:
|
|
||||||
|
|
||||||
* [`setup-buildx`](https://github.com/docker/setup-buildx-action) action will create and boot a builder using by
|
* [`setup-buildx`](https://github.com/docker/setup-buildx-action) action will create and boot a builder using by
|
||||||
default the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver).
|
default the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver).
|
||||||
@ -69,13 +49,20 @@ to add emulation support with QEMU to be able to build against more platforms.
|
|||||||
|
|
||||||
### Git context
|
### Git context
|
||||||
|
|
||||||
|
By default, this action uses the [Git context](#git-context) so you don't need
|
||||||
|
to use the [`actions/checkout`](https://github.com/actions/checkout/) action to
|
||||||
|
check out the repository because this will be done directly by [BuildKit](https://github.com/moby/buildkit).
|
||||||
|
|
||||||
|
The git reference will be based on the [event that triggered your workflow](https://docs.github.com/en/actions/reference/events-that-trigger-workflows)
|
||||||
|
and will result in the following context: `https://github.com/<owner>/<repo>.git#<ref>`.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: ci
|
name: ci
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
@ -95,24 +82,42 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
id: docker_build
|
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v2
|
||||||
with:
|
with:
|
||||||
push: true
|
push: true
|
||||||
tags: user/app:latest
|
tags: user/app:latest
|
||||||
-
|
|
||||||
name: Image digest
|
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Building from the current repository automatically uses the [GitHub Token](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token)
|
Be careful because **any file mutation in the steps that precede the build step
|
||||||
so it does not need to be passed. If you want to authenticate against another private repository, you have to use
|
will be ignored, including processing of the `.dockerignore` file** since
|
||||||
a [secret](docs/advanced/secrets.md) named `GIT_AUTH_TOKEN` to be able to authenticate against it with buildx:
|
the context is based on the Git reference. However, you can use the
|
||||||
|
[Path context](#path-context) using the [`context` input](#inputs) alongside
|
||||||
|
the [`actions/checkout`](https://github.com/actions/checkout/) action to remove
|
||||||
|
this restriction.
|
||||||
|
|
||||||
|
Default Git context can also be provided using the [Handlebars template](https://handlebarsjs.com/guide/)
|
||||||
|
expression `{{defaultContext}}`. Here we can use it to provide a subdirectory
|
||||||
|
to the default Git context:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: "{{defaultContext}}:mysubdir"
|
||||||
|
push: true
|
||||||
|
tags: user/app:latest
|
||||||
|
```
|
||||||
|
> :warning: Subdirectory for Git context is not yet available for the buildx [`docker` driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver).
|
||||||
|
|
||||||
|
Building from the current repository automatically uses the [GitHub Token](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token)
|
||||||
|
so it does not need to be passed. If you want to authenticate against another
|
||||||
|
private repository, you have to use a [secret](docs/advanced/secrets.md) named
|
||||||
|
`GIT_AUTH_TOKEN` to be able to authenticate against it with buildx:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
-
|
-
|
||||||
name: Build and push
|
name: Build and push
|
||||||
id: docker_build
|
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v2
|
||||||
with:
|
with:
|
||||||
push: true
|
push: true
|
||||||
@ -121,9 +126,6 @@ a [secret](docs/advanced/secrets.md) named `GIT_AUTH_TOKEN` to be able to authen
|
|||||||
GIT_AUTH_TOKEN=${{ secrets.MYTOKEN }}
|
GIT_AUTH_TOKEN=${{ secrets.MYTOKEN }}
|
||||||
```
|
```
|
||||||
|
|
||||||
> :warning: Subdir for Git context is not yet supported ([moby/buildkit#1684](https://github.com/moby/buildkit/issues/1684))
|
|
||||||
> but you can use the [path context](#path-context) in the meantime. More info on [Docker docs website](https://docs.docker.com/engine/reference/commandline/build/#git-repositories).
|
|
||||||
|
|
||||||
### Path context
|
### Path context
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@ -132,7 +134,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
@ -170,11 +172,10 @@ jobs:
|
|||||||
* [Push to multi-registries](docs/advanced/push-multi-registries.md)
|
* [Push to multi-registries](docs/advanced/push-multi-registries.md)
|
||||||
* [Copy between registries](docs/advanced/copy-between-registries.md)
|
* [Copy between registries](docs/advanced/copy-between-registries.md)
|
||||||
* [Cache](docs/advanced/cache.md)
|
* [Cache](docs/advanced/cache.md)
|
||||||
* [Registry cache](docs/advanced/cache.md#registry-cache)
|
|
||||||
* [GitHub cache](docs/advanced/cache.md#github-cache)
|
|
||||||
* [Local registry](docs/advanced/local-registry.md)
|
* [Local registry](docs/advanced/local-registry.md)
|
||||||
* [Export image to Docker](docs/advanced/export-docker.md)
|
* [Export image to Docker](docs/advanced/export-docker.md)
|
||||||
* [Share built image between jobs](docs/advanced/share-image-jobs.md)
|
* [Share built image between jobs](docs/advanced/share-image-jobs.md)
|
||||||
|
* [Test your image before pushing it](docs/advanced/test-before-push.md)
|
||||||
* [Handle tags and labels](docs/advanced/tags-labels.md)
|
* [Handle tags and labels](docs/advanced/tags-labels.md)
|
||||||
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md)
|
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md)
|
||||||
|
|
||||||
@ -198,11 +199,13 @@ Following inputs can be used as `step.with` keys
|
|||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
|---------------------|----------|------------------------------------|
|
|---------------------|----------|------------------------------------|
|
||||||
| `allow` | List/CSV | List of [extra privileged entitlement](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#allow) (eg. `network.host,security.insecure`) |
|
| `add-hosts` | List/CSV | List of [customs host-to-IP mapping](https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host) (e.g., `docker:10.180.0.1`) |
|
||||||
|
| `allow` | List/CSV | List of [extra privileged entitlement](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#allow) (e.g., `network.host,security.insecure`) |
|
||||||
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
|
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
|
||||||
| `build-args` | List | List of build-time variables |
|
| `build-args` | List | List of build-time variables |
|
||||||
| `cache-from` | List | List of [external cache sources](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from) (eg. `type=local,src=path/to/dir`) |
|
| `cache-from` | List | List of [external cache sources](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from) (e.g., `type=local,src=path/to/dir`) |
|
||||||
| `cache-to` | List | List of [cache export destinations](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-to) (eg. `type=local,dest=path/to/dir`) |
|
| `cache-to` | List | List of [cache export destinations](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-to) (e.g., `type=local,dest=path/to/dir`) |
|
||||||
|
| `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)) |
|
| `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`) |
|
| `file` | String | Path to the Dockerfile. (default `{context}/Dockerfile`) |
|
||||||
| `labels` | List | List of metadata for an image |
|
| `labels` | List | List of metadata for an image |
|
||||||
@ -213,19 +216,33 @@ Following inputs can be used as `step.with` keys
|
|||||||
| `platforms` | List/CSV | List of [target platforms](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#platform) for build |
|
| `platforms` | List/CSV | List of [target platforms](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#platform) for build |
|
||||||
| `pull` | Bool | Always attempt to pull a newer version of the image (default `false`) |
|
| `pull` | Bool | Always attempt to pull a newer version of the image (default `false`) |
|
||||||
| `push` | Bool | [Push](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#push) is a shorthand for `--output=type=registry` (default `false`) |
|
| `push` | Bool | [Push](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#push) is a shorthand for `--output=type=registry` (default `false`) |
|
||||||
| `secrets` | List | List of secrets to expose to the build (eg. `key=string`, `GIT_AUTH_TOKEN=mytoken`) |
|
| `secrets` | List | List of secrets to expose to the build (e.g., `key=string`, `GIT_AUTH_TOKEN=mytoken`) |
|
||||||
| `secret-files` | List | List of secret files to expose to the build (eg. `key=filename`, `MY_SECRET=./secret.txt`) |
|
| `secret-files` | List | List of secret files to expose to the build (e.g., `key=filename`, `MY_SECRET=./secret.txt`) |
|
||||||
|
| `shm-size`¹ | String | Size of [`/dev/shm`](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#-size-of-devshm---shm-size) (e.g., `2g`) |
|
||||||
| `ssh` | List | List of SSH agent socket or keys to expose to the build |
|
| `ssh` | List | List of SSH agent socket or keys to expose to the build |
|
||||||
| `tags` | List/CSV | List of tags |
|
| `tags` | List/CSV | List of tags |
|
||||||
| `target` | String | Sets the target stage to build |
|
| `target` | String | Sets the target stage to build |
|
||||||
|
| `ulimit`¹ | List | [Ulimit](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#-set-ulimits---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 }}`) |
|
||||||
|
|
||||||
|
> ¹ `cgroup-parent`, `shm-size` and `ulimit` are only available using `moby/buildkit:master`
|
||||||
|
> as builder image atm:
|
||||||
|
> ```yaml
|
||||||
|
> - name: Set up Docker Buildx
|
||||||
|
> uses: docker/setup-buildx-action@v1
|
||||||
|
> with:
|
||||||
|
> driver-opts: |
|
||||||
|
> image=moby/buildkit:master
|
||||||
|
> ```
|
||||||
|
|
||||||
### outputs
|
### outputs
|
||||||
|
|
||||||
Following outputs are available
|
Following outputs are available
|
||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
|---------------|---------|---------------------------------------|
|
|-------------------|---------|---------------------------------------|
|
||||||
| `digest` | String | Image content-addressable identifier also called a digest |
|
| `digest` | String | Image content-addressable identifier also called a digest |
|
||||||
|
| `metadata` | JSON | Build result metadata |
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
* [Cannot push to a registry](#cannot-push-to-a-registry)
|
* [Cannot push to a registry](#cannot-push-to-a-registry)
|
||||||
* [BuildKit container logs](#buildkit-container-logs)
|
* [BuildKit container logs](#buildkit-container-logs)
|
||||||
* [With containerd](#with-containerd)
|
* [With containerd](#with-containerd)
|
||||||
|
* [`repository name must be lowercase`](#repository-name-must-be-lowercase)
|
||||||
|
|
||||||
## Cannot push to a registry
|
## Cannot push to a registry
|
||||||
|
|
||||||
@ -14,9 +15,11 @@ While pushing to a registry, you may encounter these kinds of issues:
|
|||||||
* `failed commit on ref "manifest-sha256:...": unexpected status: 401 Unauthorized`
|
* `failed commit on ref "manifest-sha256:...": unexpected status: 401 Unauthorized`
|
||||||
* `unexpected response: 401 Unauthorized`
|
* `unexpected response: 401 Unauthorized`
|
||||||
|
|
||||||
These issues are not directly related to this action but are rather linked to [buildx](https://github.com/docker/buildx),
|
These issues are not directly related to this action but are rather linked to
|
||||||
[buildkit](https://github.com/moby/buildkit), [containerd](https://github.com/containerd/containerd) or the registry
|
[buildx](https://github.com/docker/buildx), [buildkit](https://github.com/moby/buildkit),
|
||||||
on which you're pushing your image. The quality of error message depends on the registry and are usually not very informative.
|
[containerd](https://github.com/containerd/containerd) or the registry on which
|
||||||
|
you're pushing your image. The quality of error message depends on the registry
|
||||||
|
and are usually not very informative.
|
||||||
|
|
||||||
### BuildKit container logs
|
### BuildKit container logs
|
||||||
|
|
||||||
@ -25,8 +28,9 @@ action step and attach BuildKit container logs to your issue.
|
|||||||
|
|
||||||
### With containerd
|
### With containerd
|
||||||
|
|
||||||
Next you can test pushing with [containerd action](https://github.com/crazy-max/ghaction-setup-containerd) using the
|
Next you can test pushing with [containerd action](https://github.com/crazy-max/ghaction-setup-containerd)
|
||||||
following workflow. If it works then open an issue on [buildkit](https://github.com/moby/buildkit) repository.
|
using the following workflow. If it works then open an issue on [buildkit](https://github.com/moby/buildkit)
|
||||||
|
repository.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: containerd
|
name: containerd
|
||||||
@ -69,3 +73,65 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sudo ctr --debug i push --user "${{ secrets.DOCKER_USERNAME }}:${{ secrets.DOCKER_PASSWORD }}" docker.io/user/app:latest
|
sudo ctr --debug i push --user "${{ secrets.DOCKER_USERNAME }}:${{ secrets.DOCKER_PASSWORD }}" docker.io/user/app:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `repository name must be lowercase`
|
||||||
|
|
||||||
|
You may encounter this issue if you're using `github.repository` as a repo slug
|
||||||
|
in your tag:
|
||||||
|
|
||||||
|
```
|
||||||
|
#6 exporting to image
|
||||||
|
#6 exporting layers
|
||||||
|
#6 exporting layers 1.2s done
|
||||||
|
#6 exporting manifest sha256:b47f7dfb97b89ccd5de553af3c8cd94c4795884cbe5693e93946b1d95a7b1d12 0.0s done
|
||||||
|
#6 exporting config sha256:995e93fab8196893192f08a38deea6769dc4d98f86cf705eccc24ec96a3e271c 0.0s done
|
||||||
|
#6 ERROR: invalid reference format: repository name must be lowercase
|
||||||
|
------
|
||||||
|
> exporting to image:
|
||||||
|
------
|
||||||
|
error: failed to solve: invalid reference format: repository name must be lowercase
|
||||||
|
```
|
||||||
|
|
||||||
|
or a cache reference:
|
||||||
|
|
||||||
|
```
|
||||||
|
#10 importing cache manifest from ghcr.io/My-Org/repo:main
|
||||||
|
#10 ERROR: invalid reference format: repository name must be lowercase
|
||||||
|
```
|
||||||
|
|
||||||
|
To fix this issue you can use our [metadata action](https://github.com/docker/metadata-action)
|
||||||
|
to generate sanitized tags:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository }}
|
||||||
|
tags: latest
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or a dedicated step to sanitize the slug:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Sanitize repo slug
|
||||||
|
uses: actions/github-script@v4
|
||||||
|
id: repo_slug
|
||||||
|
with:
|
||||||
|
result-encoding: string
|
||||||
|
script: return 'ghcr.io/${{ github.repository }}'.toLowerCase()
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.repo_slug.outputs.result }}:latest
|
||||||
|
```
|
||||||
|
46
UPGRADE.md
46
UPGRADE.md
@ -28,7 +28,7 @@
|
|||||||
# v1
|
# v1
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout code
|
name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
-
|
-
|
||||||
name: Build and push Docker images
|
name: Build and push Docker images
|
||||||
@ -47,7 +47,7 @@ steps:
|
|||||||
# v2
|
# v2
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout code
|
name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
@ -79,7 +79,7 @@ steps:
|
|||||||
# v1
|
# v1
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout code
|
name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
-
|
-
|
||||||
name: Build and push Docker images
|
name: Build and push Docker images
|
||||||
@ -101,25 +101,17 @@ steps:
|
|||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
-
|
-
|
||||||
name: Prepare
|
name: Docker meta
|
||||||
id: prep
|
id: meta
|
||||||
run: |
|
uses: docker/metadata-action@v3
|
||||||
DOCKER_IMAGE=myorg/myrepository
|
with:
|
||||||
VERSION=edge
|
images: |
|
||||||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
myorg/myrepository
|
||||||
VERSION=${GITHUB_REF#refs/tags/}
|
tags: |
|
||||||
elif [[ $GITHUB_REF == refs/heads/* ]]; then
|
type=ref,event=branch
|
||||||
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
|
type=ref,event=pr
|
||||||
elif [[ $GITHUB_REF == refs/pull/* ]]; then
|
type=semver,pattern={{version}}
|
||||||
VERSION=pr-${{ github.event.number }}
|
type=sha
|
||||||
fi
|
|
||||||
TAGS="${DOCKER_IMAGE}:${VERSION}"
|
|
||||||
if [ "${{ github.event_name }}" = "push" ]; then
|
|
||||||
TAGS="$TAGS,${DOCKER_IMAGE}:sha-${GITHUB_SHA::8}"
|
|
||||||
fi
|
|
||||||
echo ::set-output name=version::${VERSION}
|
|
||||||
echo ::set-output name=tags::${TAGS}
|
|
||||||
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v1
|
||||||
@ -136,12 +128,6 @@ steps:
|
|||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.prep.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: |
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
org.opencontainers.image.source=${{ github.event.repository.html_url }}
|
|
||||||
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
|
|
||||||
org.opencontainers.image.revision=${{ github.sha }}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> You can also use the [Docker meta action to handle tags and labels](docs/advanced/tags-labels.md) based on GitHub
|
|
||||||
> actions events and Git metadata.
|
|
||||||
|
@ -8,6 +8,10 @@ import * as context from '../src/context';
|
|||||||
|
|
||||||
const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
|
const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
|
||||||
const digest = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
|
const digest = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
|
||||||
|
const metadata = `{
|
||||||
|
"containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd",
|
||||||
|
"containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
|
||||||
|
}`;
|
||||||
|
|
||||||
jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
|
jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
|
||||||
const tmpDir = path.join('/tmp/.docker-build-push-jest').split(path.sep).join(path.posix.sep);
|
const tmpDir = path.join('/tmp/.docker-build-push-jest').split(path.sep).join(path.posix.sep);
|
||||||
@ -24,14 +28,21 @@ jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
|
|||||||
describe('getImageID', () => {
|
describe('getImageID', () => {
|
||||||
it('matches', async () => {
|
it('matches', async () => {
|
||||||
const imageIDFile = await buildx.getImageIDFile();
|
const imageIDFile = await buildx.getImageIDFile();
|
||||||
console.log(`imageIDFile: ${imageIDFile}`);
|
|
||||||
await fs.writeFileSync(imageIDFile, digest);
|
await fs.writeFileSync(imageIDFile, digest);
|
||||||
const imageID = await buildx.getImageID();
|
const imageID = await buildx.getImageID();
|
||||||
console.log(`imageID: ${imageID}`);
|
|
||||||
expect(imageID).toEqual(digest);
|
expect(imageID).toEqual(digest);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getMetadata', () => {
|
||||||
|
it('matches', async () => {
|
||||||
|
const metadataFile = await buildx.getMetadataFile();
|
||||||
|
await fs.writeFileSync(metadataFile, metadata);
|
||||||
|
const expected = await buildx.getMetadata();
|
||||||
|
expect(expected).toEqual(metadata);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('isLocalOrTarExporter', () => {
|
describe('isLocalOrTarExporter', () => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
test.each([
|
test.each([
|
||||||
@ -117,7 +128,6 @@ describe('getVersion', () => {
|
|||||||
'valid',
|
'valid',
|
||||||
async () => {
|
async () => {
|
||||||
const version = await buildx.getVersion();
|
const version = await buildx.getVersion();
|
||||||
console.log(`version: ${version}`);
|
|
||||||
expect(semver.valid(version)).not.toBeNull();
|
expect(semver.valid(version)).not.toBeNull();
|
||||||
},
|
},
|
||||||
100000
|
100000
|
||||||
@ -164,10 +174,8 @@ describe('getSecret', () => {
|
|||||||
secret = await buildx.getSecretString(kvp);
|
secret = await buildx.getSecretString(kvp);
|
||||||
}
|
}
|
||||||
expect(true).toBe(!invalid);
|
expect(true).toBe(!invalid);
|
||||||
console.log(`secret: ${secret}`);
|
|
||||||
expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`);
|
expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`);
|
||||||
const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8');
|
const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8');
|
||||||
console.log(`secretValue: ${secretValue}`);
|
|
||||||
expect(secretValue).toEqual(exValue);
|
expect(secretValue).toEqual(exValue);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(true).toBe(invalid);
|
expect(true).toBe(invalid);
|
||||||
|
@ -140,13 +140,14 @@ describe('getArgs', () => {
|
|||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
test.each([
|
test.each([
|
||||||
[
|
[
|
||||||
|
0,
|
||||||
'0.4.1',
|
'0.4.1',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
@ -156,13 +157,14 @@ describe('getArgs', () => {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
1,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['build-args', 'MY_ARG=val1,val2,val3\nARG=val'],
|
['build-args', 'MY_ARG=val1,val2,val3\nARG=val'],
|
||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
@ -174,24 +176,26 @@ describe('getArgs', () => {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
2,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['tags', 'name/app:7.4, name/app:latest'],
|
['tags', 'name/app:7.4, name/app:latest'],
|
||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
'build',
|
'build',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
'--tag', 'name/app:7.4',
|
'--tag', 'name/app:7.4',
|
||||||
'--tag', 'name/app:latest',
|
'--tag', 'name/app:latest',
|
||||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
|
||||||
'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
|
'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
3,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
@ -200,7 +204,7 @@ describe('getArgs', () => {
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
@ -212,6 +216,7 @@ describe('getArgs', () => {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
4,
|
||||||
'0.4.1',
|
'0.4.1',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
@ -219,7 +224,7 @@ describe('getArgs', () => {
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
@ -229,13 +234,14 @@ describe('getArgs', () => {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
5,
|
||||||
'0.4.1',
|
'0.4.1',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
@ -245,6 +251,7 @@ describe('getArgs', () => {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
6,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
@ -252,7 +259,7 @@ describe('getArgs', () => {
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
@ -263,6 +270,7 @@ describe('getArgs', () => {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
7,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['github-token', 'abcdefghijklmno0123456789'],
|
['github-token', 'abcdefghijklmno0123456789'],
|
||||||
@ -270,7 +278,7 @@ describe('getArgs', () => {
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
@ -281,6 +289,7 @@ describe('getArgs', () => {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
8,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
||||||
@ -292,21 +301,22 @@ describe('getArgs', () => {
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'true'],
|
['push', 'true'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
'build',
|
'build',
|
||||||
'--platform', 'linux/amd64,linux/arm64',
|
|
||||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
|
||||||
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
|
||||||
'--file', './test/Dockerfile',
|
'--file', './test/Dockerfile',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
'--platform', 'linux/amd64,linux/arm64',
|
||||||
|
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--builder', 'builder-git-context-2',
|
'--builder', 'builder-git-context-2',
|
||||||
'--push',
|
'--push',
|
||||||
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
9,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
||||||
@ -326,24 +336,25 @@ ccc"`],
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'true'],
|
['push', 'true'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
'build',
|
'build',
|
||||||
'--platform', 'linux/amd64,linux/arm64',
|
'--file', './test/Dockerfile',
|
||||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
'--platform', 'linux/amd64,linux/arm64',
|
||||||
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--file', './test/Dockerfile',
|
|
||||||
'--builder', 'builder-git-context-2',
|
'--builder', 'builder-git-context-2',
|
||||||
'--push',
|
'--push',
|
||||||
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
10,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
||||||
@ -363,24 +374,25 @@ ccc`],
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'true'],
|
['push', 'true'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
'build',
|
'build',
|
||||||
'--platform', 'linux/amd64,linux/arm64',
|
'--file', './test/Dockerfile',
|
||||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
'--platform', 'linux/amd64,linux/arm64',
|
||||||
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--file', './test/Dockerfile',
|
|
||||||
'--builder', 'builder-git-context-2',
|
'--builder', 'builder-git-context-2',
|
||||||
'--push',
|
'--push',
|
||||||
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
11,
|
||||||
'0.5.1',
|
'0.5.1',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
||||||
@ -392,14 +404,14 @@ ccc`],
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'true'],
|
['push', 'true'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
'build',
|
'build',
|
||||||
|
'--file', './test/Dockerfile',
|
||||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
'--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
'--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||||
'--file', './test/Dockerfile',
|
|
||||||
'--builder', 'builder-git-context-2',
|
'--builder', 'builder-git-context-2',
|
||||||
'--network', 'host',
|
'--network', 'host',
|
||||||
'--push',
|
'--push',
|
||||||
@ -407,6 +419,7 @@ ccc`],
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
12,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
@ -415,7 +428,7 @@ ccc`],
|
|||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
['pull', 'false']
|
['pull', 'false'],
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
'buildx',
|
'buildx',
|
||||||
@ -425,18 +438,92 @@ ccc`],
|
|||||||
'--output', 'type=local,dest=./release-out',
|
'--output', 'type=local,dest=./release-out',
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
]
|
],
|
||||||
|
[
|
||||||
|
13,
|
||||||
|
'0.6.0',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['tag', 'localhost:5000/name/app:latest'],
|
||||||
|
['file', './test/Dockerfile'],
|
||||||
|
['add-hosts', 'docker:10.180.0.1,foo:10.0.0.1'],
|
||||||
|
['network', 'host'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'true'],
|
||||||
|
['pull', 'false'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'buildx',
|
||||||
|
'build',
|
||||||
|
'--add-host', 'docker:10.180.0.1',
|
||||||
|
'--add-host', 'foo:10.0.0.1',
|
||||||
|
'--file', './test/Dockerfile',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'--network', 'host',
|
||||||
|
'--push',
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
14,
|
||||||
|
'0.7.0',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['file', './test/Dockerfile'],
|
||||||
|
['add-hosts', 'docker:10.180.0.1\nfoo:10.0.0.1'],
|
||||||
|
['cgroup-parent', 'foo'],
|
||||||
|
['shm-size', '2g'],
|
||||||
|
['ulimit', `nofile=1024:1024
|
||||||
|
nproc=3`],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'buildx',
|
||||||
|
'build',
|
||||||
|
'--add-host', 'docker:10.180.0.1',
|
||||||
|
'--add-host', 'foo:10.0.0.1',
|
||||||
|
'--cgroup-parent', 'foo',
|
||||||
|
'--file', './test/Dockerfile',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
'--shm-size', '2g',
|
||||||
|
'--ulimit', 'nofile=1024:1024',
|
||||||
|
'--ulimit', 'nproc=3',
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
15,
|
||||||
|
'0.7.0',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '{{defaultContext}}:docker'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'buildx',
|
||||||
|
'build',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'https://github.com/docker/build-push-action.git#refs/heads/test-jest:docker'
|
||||||
|
]
|
||||||
|
],
|
||||||
])(
|
])(
|
||||||
'given %p with %p as inputs, returns %p',
|
'[%d] given %p with %p as inputs, returns %p',
|
||||||
async (buildxVersion: string, inputs: Map<string, any>, expected: Array<string>) => {
|
async (num: number, buildxVersion: string, inputs: Map<string, any>, expected: Array<string>) => {
|
||||||
await inputs.forEach((value: string, name: string) => {
|
await inputs.forEach((value: string, name: string) => {
|
||||||
setInput(name, value);
|
setInput(name, value);
|
||||||
});
|
});
|
||||||
const defContext = context.defaultContext();
|
const defContext = context.defaultContext();
|
||||||
const inp = await context.getInputs(defContext);
|
const inp = await context.getInputs(defContext);
|
||||||
console.log(inp);
|
|
||||||
const res = await context.getArgs(inp, defContext, buildxVersion);
|
const res = await context.getArgs(inp, defContext, buildxVersion);
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(expected);
|
expect(res).toEqual(expected);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -446,63 +533,54 @@ describe('getInputList', () => {
|
|||||||
it('single line correctly', async () => {
|
it('single line correctly', async () => {
|
||||||
await setInput('foo', 'bar');
|
await setInput('foo', 'bar');
|
||||||
const res = await context.getInputList('foo');
|
const res = await context.getInputList('foo');
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['bar']);
|
expect(res).toEqual(['bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multiline correctly', async () => {
|
it('multiline correctly', async () => {
|
||||||
setInput('foo', 'bar\nbaz');
|
setInput('foo', 'bar\nbaz');
|
||||||
const res = await context.getInputList('foo');
|
const res = await context.getInputList('foo');
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['bar', 'baz']);
|
expect(res).toEqual(['bar', 'baz']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('empty lines correctly', async () => {
|
it('empty lines correctly', async () => {
|
||||||
setInput('foo', 'bar\n\nbaz');
|
setInput('foo', 'bar\n\nbaz');
|
||||||
const res = await context.getInputList('foo');
|
const res = await context.getInputList('foo');
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['bar', 'baz']);
|
expect(res).toEqual(['bar', 'baz']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('comma correctly', async () => {
|
it('comma correctly', async () => {
|
||||||
setInput('foo', 'bar,baz');
|
setInput('foo', 'bar,baz');
|
||||||
const res = await context.getInputList('foo');
|
const res = await context.getInputList('foo');
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['bar', 'baz']);
|
expect(res).toEqual(['bar', 'baz']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('empty result correctly', async () => {
|
it('empty result correctly', async () => {
|
||||||
setInput('foo', 'bar,baz,');
|
setInput('foo', 'bar,baz,');
|
||||||
const res = await context.getInputList('foo');
|
const res = await context.getInputList('foo');
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['bar', 'baz']);
|
expect(res).toEqual(['bar', 'baz']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('different new lines correctly', async () => {
|
it('different new lines correctly', async () => {
|
||||||
setInput('foo', 'bar\r\nbaz');
|
setInput('foo', 'bar\r\nbaz');
|
||||||
const res = await context.getInputList('foo');
|
const res = await context.getInputList('foo');
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['bar', 'baz']);
|
expect(res).toEqual(['bar', 'baz']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('different new lines and comma correctly', async () => {
|
it('different new lines and comma correctly', async () => {
|
||||||
setInput('foo', 'bar\r\nbaz,bat');
|
setInput('foo', 'bar\r\nbaz,bat');
|
||||||
const res = await context.getInputList('foo');
|
const res = await context.getInputList('foo');
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['bar', 'baz', 'bat']);
|
expect(res).toEqual(['bar', 'baz', 'bat']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multiline and ignoring comma correctly', async () => {
|
it('multiline and ignoring comma correctly', async () => {
|
||||||
setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir');
|
setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir');
|
||||||
const res = await context.getInputList('cache-from', true);
|
const res = await context.getInputList('cache-from', true);
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('different new lines and ignoring comma correctly', async () => {
|
it('different new lines and ignoring comma correctly', async () => {
|
||||||
setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir');
|
setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir');
|
||||||
const res = await context.getInputList('cache-from', true);
|
const res = await context.getInputList('cache-from', true);
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -516,7 +594,6 @@ ccccccccc"
|
|||||||
FOO=bar`
|
FOO=bar`
|
||||||
);
|
);
|
||||||
const res = await context.getInputList('secrets', true);
|
const res = await context.getInputList('secrets', true);
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual([
|
expect(res).toEqual([
|
||||||
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
||||||
`MYSECRET=aaaaaaaa
|
`MYSECRET=aaaaaaaa
|
||||||
@ -540,7 +617,6 @@ bbbb
|
|||||||
ccc"`
|
ccc"`
|
||||||
);
|
);
|
||||||
const res = await context.getInputList('secrets', true);
|
const res = await context.getInputList('secrets', true);
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual([
|
expect(res).toEqual([
|
||||||
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
||||||
`MYSECRET=aaaaaaaa
|
`MYSECRET=aaaaaaaa
|
||||||
@ -564,7 +640,6 @@ ccccccccc
|
|||||||
FOO=bar`
|
FOO=bar`
|
||||||
);
|
);
|
||||||
const res = await context.getInputList('secrets', true);
|
const res = await context.getInputList('secrets', true);
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']);
|
expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -575,7 +650,6 @@ FOO=bar`
|
|||||||
FOO=bar`
|
FOO=bar`
|
||||||
);
|
);
|
||||||
const res = await context.getInputList('secrets', true);
|
const res = await context.getInputList('secrets', true);
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']);
|
expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -589,7 +663,6 @@ ccccccccc"
|
|||||||
FOO=bar`
|
FOO=bar`
|
||||||
);
|
);
|
||||||
const res = await context.getInputList('secrets', true);
|
const res = await context.getInputList('secrets', true);
|
||||||
console.log(res);
|
|
||||||
expect(res).toEqual([
|
expect(res).toEqual([
|
||||||
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
||||||
`MYSECRET=aaaaaaaa
|
`MYSECRET=aaaaaaaa
|
||||||
|
24
action.yml
24
action.yml
@ -7,8 +7,11 @@ branding:
|
|||||||
color: 'blue'
|
color: 'blue'
|
||||||
|
|
||||||
inputs:
|
inputs:
|
||||||
|
add-hosts:
|
||||||
|
description: "List of a customs host-to-IP mapping (e.g., docker:10.180.0.1)"
|
||||||
|
required: false
|
||||||
allow:
|
allow:
|
||||||
description: "List of extra privileged entitlement (eg. network.host,security.insecure)"
|
description: "List of extra privileged entitlement (e.g., network.host,security.insecure)"
|
||||||
required: false
|
required: false
|
||||||
build-args:
|
build-args:
|
||||||
description: "List of build-time variables"
|
description: "List of build-time variables"
|
||||||
@ -17,10 +20,13 @@ inputs:
|
|||||||
description: "Builder instance"
|
description: "Builder instance"
|
||||||
required: false
|
required: false
|
||||||
cache-from:
|
cache-from:
|
||||||
description: "List of external cache sources for buildx (eg. user/app:cache, type=local,src=path/to/dir)"
|
description: "List of external cache sources for buildx (e.g., user/app:cache, type=local,src=path/to/dir)"
|
||||||
required: false
|
required: false
|
||||||
cache-to:
|
cache-to:
|
||||||
description: "List of cache export destinations for buildx (eg. user/app:cache, type=local,dest=path/to/dir)"
|
description: "List of cache export destinations for buildx (e.g., user/app:cache, type=local,dest=path/to/dir)"
|
||||||
|
required: false
|
||||||
|
cgroup-parent:
|
||||||
|
description: "Optional parent cgroup for the container used in the build"
|
||||||
required: false
|
required: false
|
||||||
context:
|
context:
|
||||||
description: "Build's context is the set of files located in the specified PATH or URL"
|
description: "Build's context is the set of files located in the specified PATH or URL"
|
||||||
@ -57,10 +63,13 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
default: 'false'
|
default: 'false'
|
||||||
secrets:
|
secrets:
|
||||||
description: "List of secrets to expose to the build (eg. key=string, GIT_AUTH_TOKEN=mytoken)"
|
description: "List of secrets to expose to the build (e.g., key=string, GIT_AUTH_TOKEN=mytoken)"
|
||||||
required: false
|
required: false
|
||||||
secret-files:
|
secret-files:
|
||||||
description: "List of secret files to expose to the build (eg. key=filename, MY_SECRET=./secret.txt)"
|
description: "List of secret files to expose to the build (e.g., key=filename, MY_SECRET=./secret.txt)"
|
||||||
|
required: false
|
||||||
|
shm-size:
|
||||||
|
description: "Size of /dev/shm (e.g., 2g)"
|
||||||
required: false
|
required: false
|
||||||
ssh:
|
ssh:
|
||||||
description: "List of SSH agent socket or keys to expose to the build"
|
description: "List of SSH agent socket or keys to expose to the build"
|
||||||
@ -71,6 +80,9 @@ inputs:
|
|||||||
target:
|
target:
|
||||||
description: "Sets the target stage to build"
|
description: "Sets the target stage to build"
|
||||||
required: false
|
required: false
|
||||||
|
ulimit:
|
||||||
|
description: "Ulimit options (e.g., nofile=1024:1024)"
|
||||||
|
required: false
|
||||||
github-token:
|
github-token:
|
||||||
description: "GitHub Token used to authenticate against a repository for Git context"
|
description: "GitHub Token used to authenticate against a repository for Git context"
|
||||||
default: ${{ github.token }}
|
default: ${{ github.token }}
|
||||||
@ -79,6 +91,8 @@ inputs:
|
|||||||
outputs:
|
outputs:
|
||||||
digest:
|
digest:
|
||||||
description: 'Image content-addressable identifier also called a digest'
|
description: 'Image content-addressable identifier also called a digest'
|
||||||
|
metadata:
|
||||||
|
description: 'Build result metadata'
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node12'
|
||||||
|
10953
dist/index.js
generated
vendored
10953
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
@ -31,6 +31,7 @@ target "build-validate" {
|
|||||||
inherits = ["node-version"]
|
inherits = ["node-version"]
|
||||||
dockerfile = "./hack/build.Dockerfile"
|
dockerfile = "./hack/build.Dockerfile"
|
||||||
target = "build-validate"
|
target = "build-validate"
|
||||||
|
output = ["type=cacheonly"]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "format" {
|
target "format" {
|
||||||
@ -44,24 +45,26 @@ target "format-validate" {
|
|||||||
inherits = ["node-version"]
|
inherits = ["node-version"]
|
||||||
dockerfile = "./hack/build.Dockerfile"
|
dockerfile = "./hack/build.Dockerfile"
|
||||||
target = "format-validate"
|
target = "format-validate"
|
||||||
|
output = ["type=cacheonly"]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "vendor-update" {
|
target "vendor-update" {
|
||||||
inherits = ["node-version"]
|
inherits = ["node-version"]
|
||||||
dockerfile = "./hack/vendor.Dockerfile"
|
dockerfile = "./hack/build.Dockerfile"
|
||||||
target = "update"
|
target = "vendor-update"
|
||||||
output = ["."]
|
output = ["."]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "vendor-validate" {
|
target "vendor-validate" {
|
||||||
inherits = ["node-version"]
|
inherits = ["node-version"]
|
||||||
dockerfile = "./hack/vendor.Dockerfile"
|
dockerfile = "./hack/build.Dockerfile"
|
||||||
target = "validate"
|
target = "vendor-validate"
|
||||||
|
output = ["type=cacheonly"]
|
||||||
}
|
}
|
||||||
|
|
||||||
target "test" {
|
target "test" {
|
||||||
inherits = ["node-version"]
|
inherits = ["node-version"]
|
||||||
dockerfile = "./hack/test.Dockerfile"
|
dockerfile = "./hack/build.Dockerfile"
|
||||||
target = "test-coverage"
|
target = "test-coverage"
|
||||||
output = ["./coverage"]
|
output = ["./coverage"]
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
# Cache
|
# Cache
|
||||||
|
|
||||||
|
* [Inline cache](#inline-cache)
|
||||||
* [Registry cache](#registry-cache)
|
* [Registry cache](#registry-cache)
|
||||||
* [GitHub cache](#github-cache)
|
* [GitHub cache](#github-cache)
|
||||||
|
* [Cache backend API](#cache-backend-api)
|
||||||
|
* [Local cache](#local-cache)
|
||||||
|
|
||||||
> More info about buildx cache: https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from
|
> More info about cache on [BuildKit](https://github.com/moby/buildkit#export-cache) and [Buildx](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from) repositories.
|
||||||
|
|
||||||
## Registry cache
|
## Inline cache
|
||||||
|
|
||||||
You can import/export cache from a cache manifest or (special) image configuration on the registry.
|
In most cases you want to use the [`type=inline` cache exporter](https://github.com/moby/buildkit#inline-push-image-and-cache-together).
|
||||||
|
However, note that the `inline` cache exporter only supports `min` cache mode. To enable `max` cache mode, push the
|
||||||
|
image and the cache separately by using the `registry` cache exporter as shown in the [next example](#registry-cache).
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: ci
|
name: ci
|
||||||
@ -15,7 +20,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
@ -44,16 +49,10 @@ jobs:
|
|||||||
cache-to: type=inline
|
cache-to: type=inline
|
||||||
```
|
```
|
||||||
|
|
||||||
## GitHub cache
|
## Registry cache
|
||||||
|
|
||||||
> :warning: At the moment caches are copied over the existing cache so it [keeps growing](https://github.com/docker/build-push-action/issues/252).
|
You can import/export cache from a cache manifest or (special) image configuration on the registry with the
|
||||||
> The `Move cache` step is used as a temporary fix (see https://github.com/moby/buildkit/issues/1896).
|
[`type=registry` cache exporter](https://github.com/moby/buildkit/tree/master#registry-push-image-and-cache-separately).
|
||||||
|
|
||||||
> :rocket: There is a new cache backend using GitHub cache being developed that will lighten your workflow.
|
|
||||||
> More info: https://github.com/docker/buildx/pull/535
|
|
||||||
|
|
||||||
You can leverage [GitHub cache](https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows)
|
|
||||||
using [actions/cache](https://github.com/actions/cache) with this action:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: ci
|
name: ci
|
||||||
@ -61,7 +60,101 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
-
|
||||||
|
name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: user/app:latest
|
||||||
|
cache-from: type=registry,ref=user/app:buildcache
|
||||||
|
cache-to: type=registry,ref=user/app:buildcache,mode=max
|
||||||
|
```
|
||||||
|
|
||||||
|
## GitHub cache
|
||||||
|
|
||||||
|
### Cache backend API
|
||||||
|
|
||||||
|
> :test_tube: This cache exporter is considered EXPERIMENTAL until further notice. Please provide feedback on
|
||||||
|
> [BuildKit repository](https://github.com/moby/buildkit) if you encounter any issues.
|
||||||
|
|
||||||
|
Since [buildx 0.6.0](https://github.com/docker/buildx/releases/tag/v0.6.0) and [BuildKit 0.9.0](https://github.com/moby/buildkit/releases/tag/v0.9.0),
|
||||||
|
you can use the [`type=gha` cache exporter](https://github.com/moby/buildkit/tree/master#github-actions-cache-experimental).
|
||||||
|
|
||||||
|
GitHub Actions cache exporter backend uses the [GitHub Cache API](https://github.com/tonistiigi/go-actions-cache/blob/master/api.md)
|
||||||
|
to fetch and upload cache blobs. That's why this type of cache should be exclusively used in a GitHub Action workflow
|
||||||
|
as the `url` (`$ACTIONS_CACHE_URL`) and `token` (`$ACTIONS_RUNTIME_TOKEN`) attributes are populated when a workflow
|
||||||
|
is started.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
-
|
||||||
|
name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: user/app:latest
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
```
|
||||||
|
|
||||||
|
### Local cache
|
||||||
|
|
||||||
|
> :warning: At the moment caches are copied over the existing cache so it [keeps growing](https://github.com/docker/build-push-action/issues/252).
|
||||||
|
> The `Move cache` step is used as a temporary fix (see https://github.com/moby/buildkit/issues/1896).
|
||||||
|
|
||||||
|
You can also leverage [GitHub cache](https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows)
|
||||||
|
using [actions/cache](https://github.com/actions/cache) and [`type=local` cache exporter](https://github.com/moby/buildkit#local-directory-1)
|
||||||
|
with this action:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
@ -95,7 +188,7 @@ jobs:
|
|||||||
push: true
|
push: true
|
||||||
tags: user/app:latest
|
tags: user/app:latest
|
||||||
cache-from: type=local,src=/tmp/.buildx-cache
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
cache-to: type=local,dest=/tmp/.buildx-cache-new
|
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||||
-
|
-
|
||||||
# Temp fix
|
# Temp fix
|
||||||
# https://github.com/docker/build-push-action/issues/252
|
# https://github.com/docker/build-push-action/issues/252
|
||||||
|
@ -12,7 +12,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
@ -62,7 +62,7 @@ jobs:
|
|||||||
run: make tests
|
run: make tests
|
||||||
- # copy multiplatform image from dockerhub to quay and ghcr
|
- # copy multiplatform image from dockerhub to quay and ghcr
|
||||||
name: Push Image to multiple registries
|
name: Push Image to multiple registries
|
||||||
uses: akhilerm/tag-push-action@v1.0.0
|
uses: akhilerm/tag-push-action@v2.0.0
|
||||||
with:
|
with:
|
||||||
src: docker.io/user/app:1.0.0
|
src: docker.io/user/app:1.0.0
|
||||||
dst: |
|
dst: |
|
||||||
|
@ -10,7 +10,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
@ -9,7 +9,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
@ -6,7 +6,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
@ -8,7 +8,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
@ -12,7 +12,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
@ -14,7 +14,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
@ -22,7 +22,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
@ -11,7 +11,7 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# Handle tags and labels
|
# Handle tags and labels
|
||||||
|
|
||||||
If you come from [`v1`](https://github.com/docker/build-push-action/tree/releases/v1#readme) and want an
|
If you want an "automatic" tag management and [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md)
|
||||||
"automatic" tag management and [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md)
|
|
||||||
for labels, you can do it in a dedicated step. The following workflow will use the [Docker metadata action](https://github.com/docker/metadata-action)
|
for labels, you can do it in a dedicated step. The following workflow will use the [Docker metadata action](https://github.com/docker/metadata-action)
|
||||||
to handle tags and labels based on GitHub actions events and Git metadata.
|
to handle tags and labels based on GitHub actions events and Git metadata.
|
||||||
|
|
||||||
@ -10,7 +9,7 @@ name: ci
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 10 * * *' # everyday at 10am
|
- cron: '0 10 * * *'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- '**'
|
||||||
@ -18,7 +17,7 @@ on:
|
|||||||
- 'v*.*.*'
|
- 'v*.*.*'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
|
64
docs/advanced/test-before-push.md
Normal file
64
docs/advanced/test-before-push.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# Test your image before pushing it
|
||||||
|
|
||||||
|
In some cases, you might want to validate that the image works as expected
|
||||||
|
before pushing it.
|
||||||
|
|
||||||
|
The workflow below will be composed of several steps to achieve this:
|
||||||
|
* Build and export the image to Docker
|
||||||
|
* Test your image
|
||||||
|
* Multi-platform build and push the image
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
|
||||||
|
env:
|
||||||
|
TEST_TAG: user/myapp:test
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
-
|
||||||
|
name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and export to Docker
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
load: true
|
||||||
|
tags: ${{ env.TEST_TAG }}
|
||||||
|
-
|
||||||
|
name: Test
|
||||||
|
run: |
|
||||||
|
docker run --rm ${{ env.TEST_TAG }}
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: user/app:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
> :bulb: Build time will not be increased with this workflow because internal
|
||||||
|
> cache for `linux/amd64` will be used from previous step on `Build and push`
|
||||||
|
> step so only `linux/arm64` will be actually built.
|
@ -1,5 +1,8 @@
|
|||||||
# syntax=docker/dockerfile:1.2
|
# syntax=docker/dockerfile:1.3-labs
|
||||||
|
|
||||||
ARG NODE_VERSION
|
ARG NODE_VERSION
|
||||||
|
ARG DOCKER_VERSION=20.10.10
|
||||||
|
ARG BUILDX_VERSION=0.7.0
|
||||||
|
|
||||||
FROM node:${NODE_VERSION}-alpine AS base
|
FROM node:${NODE_VERSION}-alpine AS base
|
||||||
RUN apk add --no-cache cpio findutils git
|
RUN apk add --no-cache cpio findutils git
|
||||||
@ -8,7 +11,22 @@ WORKDIR /src
|
|||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn install
|
yarn install && mkdir /vendor && cp yarn.lock /vendor
|
||||||
|
|
||||||
|
FROM scratch AS vendor-update
|
||||||
|
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
|
||||||
|
EOT
|
||||||
|
|
||||||
FROM deps AS build
|
FROM deps AS build
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
@ -19,13 +37,16 @@ FROM scratch AS build-update
|
|||||||
COPY --from=build /out /
|
COPY --from=build /out /
|
||||||
|
|
||||||
FROM build AS build-validate
|
FROM build AS build-validate
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw <<EOT
|
||||||
git add -A && cp -rf /out/* .; \
|
set -e
|
||||||
if [ -n "$(git status --porcelain -- dist)" ]; then \
|
git add -A
|
||||||
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'; \
|
cp -rf /out/* .
|
||||||
git status --porcelain -- dist; \
|
if [ -n "$(git status --porcelain -- dist)" ]; then
|
||||||
exit 1; \
|
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
|
||||||
fi
|
git status --porcelain -- dist
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
EOT
|
||||||
|
|
||||||
FROM deps AS format
|
FROM deps AS format
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
@ -39,4 +60,19 @@ COPY --from=format /out /
|
|||||||
FROM deps AS format-validate
|
FROM deps AS format-validate
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn run format-check \
|
yarn run format-check
|
||||||
|
|
||||||
|
FROM docker:${DOCKER_VERSION} as docker
|
||||||
|
FROM docker/buildx-bin:${BUILDX_VERSION} as buildx
|
||||||
|
|
||||||
|
FROM deps AS test
|
||||||
|
ENV RUNNER_TEMP=/tmp/github_runner
|
||||||
|
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
|
||||||
|
RUN --mount=type=bind,target=.,rw \
|
||||||
|
--mount=type=cache,target=/src/node_modules \
|
||||||
|
--mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
|
||||||
|
--mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \
|
||||||
|
yarn run test --coverageDirectory=/tmp/coverage
|
||||||
|
|
||||||
|
FROM scratch AS test-coverage
|
||||||
|
COPY --from=test /tmp/coverage /
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
# syntax=docker/dockerfile:1.2
|
|
||||||
ARG NODE_VERSION
|
|
||||||
|
|
||||||
FROM node:${NODE_VERSION}-alpine AS base
|
|
||||||
RUN apk add --no-cache git
|
|
||||||
WORKDIR /src
|
|
||||||
|
|
||||||
FROM base AS deps
|
|
||||||
RUN --mount=type=bind,target=.,rw \
|
|
||||||
--mount=type=cache,target=/src/node_modules \
|
|
||||||
yarn install
|
|
||||||
|
|
||||||
FROM deps AS test
|
|
||||||
ENV RUNNER_TEMP=/tmp/github_runner
|
|
||||||
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
|
|
||||||
RUN --mount=type=bind,target=.,rw \
|
|
||||||
--mount=type=cache,target=/src/node_modules \
|
|
||||||
--mount=type=bind,from=crazymax/docker,source=/usr/libexec/docker/cli-plugins/docker-buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \
|
|
||||||
--mount=type=bind,from=crazymax/docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
|
|
||||||
yarn run test --coverageDirectory=/tmp/coverage
|
|
||||||
|
|
||||||
FROM scratch AS test-coverage
|
|
||||||
COPY --from=test /tmp/coverage /
|
|
@ -1,23 +0,0 @@
|
|||||||
# syntax=docker/dockerfile:1.2
|
|
||||||
ARG NODE_VERSION
|
|
||||||
|
|
||||||
FROM node:${NODE_VERSION}-alpine AS base
|
|
||||||
RUN apk add --no-cache git
|
|
||||||
WORKDIR /src
|
|
||||||
|
|
||||||
FROM base AS vendored
|
|
||||||
RUN --mount=type=bind,target=.,rw \
|
|
||||||
--mount=type=cache,target=/src/node_modules \
|
|
||||||
yarn install && mkdir /out && cp yarn.lock /out
|
|
||||||
|
|
||||||
FROM scratch AS update
|
|
||||||
COPY --from=vendored /out /
|
|
||||||
|
|
||||||
FROM vendored AS validate
|
|
||||||
RUN --mount=type=bind,target=.,rw \
|
|
||||||
git add -A && cp -rf /out/* .; \
|
|
||||||
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
|
|
@ -28,10 +28,11 @@
|
|||||||
],
|
],
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.4.0",
|
"@actions/core": "^1.6.0",
|
||||||
"@actions/exec": "^1.1.0",
|
"@actions/exec": "^1.1.0",
|
||||||
"@actions/github": "^5.0.0",
|
"@actions/github": "^5.0.0",
|
||||||
"csv-parse": "^4.16.0",
|
"csv-parse": "^4.16.3",
|
||||||
|
"handlebars": "^4.7.7",
|
||||||
"semver": "^7.3.5",
|
"semver": "^7.3.5",
|
||||||
"tmp": "^0.2.1"
|
"tmp": "^0.2.1"
|
||||||
},
|
},
|
||||||
|
@ -15,7 +15,23 @@ export async function getImageID(): Promise<string | undefined> {
|
|||||||
if (!fs.existsSync(iidFile)) {
|
if (!fs.existsSync(iidFile)) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return fs.readFileSync(iidFile, {encoding: 'utf-8'});
|
return fs.readFileSync(iidFile, {encoding: 'utf-8'}).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getMetadataFile(): Promise<string> {
|
||||||
|
return path.join(context.tmpDir(), 'metadata-file').split(path.sep).join(path.posix.sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getMetadata(): Promise<string | undefined> {
|
||||||
|
const metadataFile = await getMetadataFile();
|
||||||
|
if (!fs.existsSync(metadataFile)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const content = fs.readFileSync(metadataFile, {encoding: 'utf-8'}).trim();
|
||||||
|
if (content === 'null') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getSecretString(kvp: string): Promise<string> {
|
export async function getSecretString(kvp: string): Promise<string> {
|
||||||
@ -103,7 +119,7 @@ export async function getVersion(): Promise<string> {
|
|||||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||||
throw new Error(res.stderr.trim());
|
throw new Error(res.stderr.trim());
|
||||||
}
|
}
|
||||||
return parseVersion(res.stdout);
|
return parseVersion(res.stdout.trim());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ import csvparse from 'csv-parse/lib/sync';
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as semver from 'semver';
|
|
||||||
import * as tmp from 'tmp';
|
import * as tmp from 'tmp';
|
||||||
|
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
@ -10,15 +9,18 @@ import {issueCommand} from '@actions/core/lib/command';
|
|||||||
import * as github from '@actions/github';
|
import * as github from '@actions/github';
|
||||||
|
|
||||||
import * as buildx from './buildx';
|
import * as buildx from './buildx';
|
||||||
|
import * as handlebars from 'handlebars';
|
||||||
|
|
||||||
let _defaultContext, _tmpDir: string;
|
let _defaultContext, _tmpDir: string;
|
||||||
|
|
||||||
export interface Inputs {
|
export interface Inputs {
|
||||||
|
addHosts: string[];
|
||||||
allow: string[];
|
allow: string[];
|
||||||
buildArgs: string[];
|
buildArgs: string[];
|
||||||
builder: string;
|
builder: string;
|
||||||
cacheFrom: string[];
|
cacheFrom: string[];
|
||||||
cacheTo: string[];
|
cacheTo: string[];
|
||||||
|
cgroupParent: string;
|
||||||
context: string;
|
context: string;
|
||||||
file: string;
|
file: string;
|
||||||
labels: string[];
|
labels: string[];
|
||||||
@ -31,9 +33,11 @@ export interface Inputs {
|
|||||||
push: boolean;
|
push: boolean;
|
||||||
secrets: string[];
|
secrets: string[];
|
||||||
secretFiles: string[];
|
secretFiles: string[];
|
||||||
|
shmSize: string;
|
||||||
ssh: string[];
|
ssh: string[];
|
||||||
tags: string[];
|
tags: string[];
|
||||||
target: string;
|
target: string;
|
||||||
|
ulimit: string[];
|
||||||
githubToken: string;
|
githubToken: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,11 +68,13 @@ export function tmpNameSync(options?: tmp.TmpNameOptions): string {
|
|||||||
|
|
||||||
export async function getInputs(defaultContext: string): Promise<Inputs> {
|
export async function getInputs(defaultContext: string): Promise<Inputs> {
|
||||||
return {
|
return {
|
||||||
|
addHosts: await getInputList('add-hosts'),
|
||||||
allow: await getInputList('allow'),
|
allow: await getInputList('allow'),
|
||||||
buildArgs: await getInputList('build-args', true),
|
buildArgs: await getInputList('build-args', true),
|
||||||
builder: core.getInput('builder'),
|
builder: core.getInput('builder'),
|
||||||
cacheFrom: await getInputList('cache-from', true),
|
cacheFrom: await getInputList('cache-from', true),
|
||||||
cacheTo: await getInputList('cache-to', true),
|
cacheTo: await getInputList('cache-to', true),
|
||||||
|
cgroupParent: core.getInput('cgroup-parent'),
|
||||||
context: core.getInput('context') || defaultContext,
|
context: core.getInput('context') || defaultContext,
|
||||||
file: core.getInput('file'),
|
file: core.getInput('file'),
|
||||||
labels: await getInputList('labels', true),
|
labels: await getInputList('labels', true),
|
||||||
@ -81,9 +87,11 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
|
|||||||
push: core.getBooleanInput('push'),
|
push: core.getBooleanInput('push'),
|
||||||
secrets: await getInputList('secrets', true),
|
secrets: await getInputList('secrets', true),
|
||||||
secretFiles: await getInputList('secret-files', true),
|
secretFiles: await getInputList('secret-files', true),
|
||||||
|
shmSize: core.getInput('shm-size'),
|
||||||
ssh: await getInputList('ssh'),
|
ssh: await getInputList('ssh'),
|
||||||
tags: await getInputList('tags'),
|
tags: await getInputList('tags'),
|
||||||
target: core.getInput('target'),
|
target: core.getInput('target'),
|
||||||
|
ulimit: await getInputList('ulimit', true),
|
||||||
githubToken: core.getInput('github-token')
|
githubToken: core.getInput('github-token')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -91,43 +99,46 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
|
|||||||
export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
|
export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
|
||||||
let args: Array<string> = ['buildx'];
|
let args: Array<string> = ['buildx'];
|
||||||
args.push.apply(args, await getBuildArgs(inputs, defaultContext, buildxVersion));
|
args.push.apply(args, await getBuildArgs(inputs, defaultContext, buildxVersion));
|
||||||
args.push.apply(args, await getCommonArgs(inputs));
|
args.push.apply(args, await getCommonArgs(inputs, buildxVersion));
|
||||||
args.push(inputs.context);
|
args.push(handlebars.compile(inputs.context)({defaultContext}));
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
|
async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
|
||||||
let args: Array<string> = ['build'];
|
let args: Array<string> = ['build'];
|
||||||
await asyncForEach(inputs.buildArgs, async buildArg => {
|
await asyncForEach(inputs.addHosts, async addHost => {
|
||||||
args.push('--build-arg', buildArg);
|
args.push('--add-host', addHost);
|
||||||
});
|
});
|
||||||
await asyncForEach(inputs.labels, async label => {
|
|
||||||
args.push('--label', label);
|
|
||||||
});
|
|
||||||
await asyncForEach(inputs.tags, async tag => {
|
|
||||||
args.push('--tag', tag);
|
|
||||||
});
|
|
||||||
if (inputs.target) {
|
|
||||||
args.push('--target', inputs.target);
|
|
||||||
}
|
|
||||||
if (inputs.allow.length > 0) {
|
if (inputs.allow.length > 0) {
|
||||||
args.push('--allow', inputs.allow.join(','));
|
args.push('--allow', inputs.allow.join(','));
|
||||||
}
|
}
|
||||||
if (inputs.platforms.length > 0) {
|
await asyncForEach(inputs.buildArgs, async buildArg => {
|
||||||
args.push('--platform', inputs.platforms.join(','));
|
args.push('--build-arg', buildArg);
|
||||||
}
|
|
||||||
await asyncForEach(inputs.outputs, async output => {
|
|
||||||
args.push('--output', output);
|
|
||||||
});
|
});
|
||||||
if (!buildx.isLocalOrTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || buildx.satisfies(buildxVersion, '>=0.4.2'))) {
|
|
||||||
args.push('--iidfile', await buildx.getImageIDFile());
|
|
||||||
}
|
|
||||||
await asyncForEach(inputs.cacheFrom, async cacheFrom => {
|
await asyncForEach(inputs.cacheFrom, async cacheFrom => {
|
||||||
args.push('--cache-from', cacheFrom);
|
args.push('--cache-from', cacheFrom);
|
||||||
});
|
});
|
||||||
await asyncForEach(inputs.cacheTo, async cacheTo => {
|
await asyncForEach(inputs.cacheTo, async cacheTo => {
|
||||||
args.push('--cache-to', cacheTo);
|
args.push('--cache-to', cacheTo);
|
||||||
});
|
});
|
||||||
|
if (inputs.cgroupParent) {
|
||||||
|
args.push('--cgroup-parent', inputs.cgroupParent);
|
||||||
|
}
|
||||||
|
if (inputs.file) {
|
||||||
|
args.push('--file', inputs.file);
|
||||||
|
}
|
||||||
|
if (!buildx.isLocalOrTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || buildx.satisfies(buildxVersion, '>=0.4.2'))) {
|
||||||
|
args.push('--iidfile', await buildx.getImageIDFile());
|
||||||
|
}
|
||||||
|
await asyncForEach(inputs.labels, async label => {
|
||||||
|
args.push('--label', label);
|
||||||
|
});
|
||||||
|
await asyncForEach(inputs.outputs, async output => {
|
||||||
|
args.push('--output', output);
|
||||||
|
});
|
||||||
|
if (inputs.platforms.length > 0) {
|
||||||
|
args.push('--platform', inputs.platforms.join(','));
|
||||||
|
}
|
||||||
await asyncForEach(inputs.secrets, async secret => {
|
await asyncForEach(inputs.secrets, async secret => {
|
||||||
try {
|
try {
|
||||||
args.push('--secret', await buildx.getSecretString(secret));
|
args.push('--secret', await buildx.getSecretString(secret));
|
||||||
@ -145,32 +156,44 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
|
|||||||
if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) {
|
if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) {
|
||||||
args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
|
args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
|
||||||
}
|
}
|
||||||
|
if (inputs.shmSize) {
|
||||||
|
args.push('--shm-size', inputs.shmSize);
|
||||||
|
}
|
||||||
await asyncForEach(inputs.ssh, async ssh => {
|
await asyncForEach(inputs.ssh, async ssh => {
|
||||||
args.push('--ssh', ssh);
|
args.push('--ssh', ssh);
|
||||||
});
|
});
|
||||||
if (inputs.file) {
|
await asyncForEach(inputs.tags, async tag => {
|
||||||
args.push('--file', inputs.file);
|
args.push('--tag', tag);
|
||||||
|
});
|
||||||
|
if (inputs.target) {
|
||||||
|
args.push('--target', inputs.target);
|
||||||
}
|
}
|
||||||
|
await asyncForEach(inputs.ulimit, async ulimit => {
|
||||||
|
args.push('--ulimit', ulimit);
|
||||||
|
});
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getCommonArgs(inputs: Inputs): Promise<Array<string>> {
|
async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> {
|
||||||
let args: Array<string> = [];
|
let args: Array<string> = [];
|
||||||
if (inputs.noCache) {
|
|
||||||
args.push('--no-cache');
|
|
||||||
}
|
|
||||||
if (inputs.builder) {
|
if (inputs.builder) {
|
||||||
args.push('--builder', inputs.builder);
|
args.push('--builder', inputs.builder);
|
||||||
}
|
}
|
||||||
if (inputs.pull) {
|
|
||||||
args.push('--pull');
|
|
||||||
}
|
|
||||||
if (inputs.load) {
|
if (inputs.load) {
|
||||||
args.push('--load');
|
args.push('--load');
|
||||||
}
|
}
|
||||||
|
if (buildx.satisfies(buildxVersion, '>=0.6.0')) {
|
||||||
|
args.push('--metadata-file', await buildx.getMetadataFile());
|
||||||
|
}
|
||||||
if (inputs.network) {
|
if (inputs.network) {
|
||||||
args.push('--network', inputs.network);
|
args.push('--network', inputs.network);
|
||||||
}
|
}
|
||||||
|
if (inputs.noCache) {
|
||||||
|
args.push('--no-cache');
|
||||||
|
}
|
||||||
|
if (inputs.pull) {
|
||||||
|
args.push('--pull');
|
||||||
|
}
|
||||||
if (inputs.push) {
|
if (inputs.push) {
|
||||||
args.push('--push');
|
args.push('--push');
|
||||||
}
|
}
|
||||||
|
21
src/main.ts
21
src/main.ts
@ -29,17 +29,22 @@ async function run(): Promise<void> {
|
|||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||||
throw new Error(`buildx bake failed with: ${res.stderr.match(/(.*)\s*$/)![0].trim()}`);
|
throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)![0].trim()}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const imageID = await buildx.getImageID();
|
await core.group(`Setting outputs`, async () => {
|
||||||
if (imageID) {
|
const imageID = await buildx.getImageID();
|
||||||
core.startGroup(`Extracting digest`);
|
const metadata = await buildx.getMetadata();
|
||||||
core.info(`${imageID}`);
|
if (imageID) {
|
||||||
context.setOutput('digest', imageID);
|
core.info(`digest=${imageID}`);
|
||||||
core.endGroup();
|
context.setOutput('digest', imageID);
|
||||||
}
|
}
|
||||||
|
if (metadata) {
|
||||||
|
core.info(`metadata=${metadata}`);
|
||||||
|
context.setOutput('metadata', metadata);
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
2
test/addhost.Dockerfile
Normal file
2
test/addhost.Dockerfile
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
FROM busybox
|
||||||
|
RUN cat /etc/hosts
|
2
test/cgroup.Dockerfile
Normal file
2
test/cgroup.Dockerfile
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
FROM alpine
|
||||||
|
RUN cat /proc/self/cgroup
|
2
test/shmsize.Dockerfile
Normal file
2
test/shmsize.Dockerfile
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
FROM busybox
|
||||||
|
RUN mount | grep /dev/shm
|
2
test/ulimit.Dockerfile
Normal file
2
test/ulimit.Dockerfile
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
FROM busybox
|
||||||
|
RUN ulimit -a
|
83
yarn.lock
83
yarn.lock
@ -2,10 +2,12 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@actions/core@^1.4.0":
|
"@actions/core@^1.6.0":
|
||||||
version "1.4.0"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.4.0.tgz#cf2e6ee317e314b03886adfeb20e448d50d6e524"
|
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.6.0.tgz#0568e47039bfb6a9170393a73f3b7eb3b22462cb"
|
||||||
integrity sha512-CGx2ilGq5i7zSLgiiGUtBCxhRRxibJYU6Fim0Q1Wg2aQL2LTnF27zbqZOrxfvFQ55eSBW0L8uVStgtKMpa0Qlg==
|
integrity sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==
|
||||||
|
dependencies:
|
||||||
|
"@actions/http-client" "^1.0.11"
|
||||||
|
|
||||||
"@actions/exec@^1.1.0":
|
"@actions/exec@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
@ -828,9 +830,9 @@ ansi-escapes@^4.2.1:
|
|||||||
type-fest "^0.21.3"
|
type-fest "^0.21.3"
|
||||||
|
|
||||||
ansi-regex@^5.0.0:
|
ansi-regex@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||||
|
|
||||||
ansi-styles@^3.2.1:
|
ansi-styles@^3.2.1:
|
||||||
version "3.2.1"
|
version "3.2.1"
|
||||||
@ -1270,10 +1272,10 @@ cssstyle@^2.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
cssom "~0.3.6"
|
cssom "~0.3.6"
|
||||||
|
|
||||||
csv-parse@*, csv-parse@^4.16.0:
|
csv-parse@*, csv-parse@^4.16.3:
|
||||||
version "4.16.0"
|
version "4.16.3"
|
||||||
resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.16.0.tgz#b4c875e288a41f7ff917cb0d7d45880d563034f6"
|
resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.16.3.tgz#7ca624d517212ebc520a36873c3478fa66efbaf7"
|
||||||
integrity sha512-Zb4tGPANH4SW0LgC9+s9Mnequs9aqn7N3/pCqNbVjs2XhEF6yWNU2Vm4OGl1v2Go9nw8rXt87Cm2QN/o6Vpqgg==
|
integrity sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==
|
||||||
|
|
||||||
data-urls@^2.0.0:
|
data-urls@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
@ -1694,6 +1696,18 @@ growly@^1.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||||
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
|
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
|
||||||
|
|
||||||
|
handlebars@^4.7.7:
|
||||||
|
version "4.7.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
|
||||||
|
integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
|
||||||
|
dependencies:
|
||||||
|
minimist "^1.2.5"
|
||||||
|
neo-async "^2.6.0"
|
||||||
|
source-map "^0.6.1"
|
||||||
|
wordwrap "^1.0.0"
|
||||||
|
optionalDependencies:
|
||||||
|
uglify-js "^3.1.4"
|
||||||
|
|
||||||
has-flag@^3.0.0:
|
has-flag@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||||
@ -2709,15 +2723,22 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||||
|
|
||||||
|
neo-async@^2.6.0:
|
||||||
|
version "2.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
|
||||||
|
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||||
|
|
||||||
nice-try@^1.0.4:
|
nice-try@^1.0.4:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||||
|
|
||||||
node-fetch@^2.3.0, node-fetch@^2.6.1:
|
node-fetch@^2.3.0, node-fetch@^2.6.1:
|
||||||
version "2.6.1"
|
version "2.6.7"
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||||
|
dependencies:
|
||||||
|
whatwg-url "^5.0.0"
|
||||||
|
|
||||||
node-int64@^0.4.0:
|
node-int64@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
@ -3422,9 +3443,9 @@ tmp@^0.2.1:
|
|||||||
rimraf "^3.0.0"
|
rimraf "^3.0.0"
|
||||||
|
|
||||||
tmpl@1.0.x:
|
tmpl@1.0.x:
|
||||||
version "1.0.4"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
|
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
|
||||||
integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=
|
integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
|
||||||
|
|
||||||
to-fast-properties@^2.0.0:
|
to-fast-properties@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
@ -3479,6 +3500,11 @@ tr46@^2.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode "^2.1.1"
|
punycode "^2.1.1"
|
||||||
|
|
||||||
|
tr46@~0.0.3:
|
||||||
|
version "0.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||||
|
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||||
|
|
||||||
ts-jest@^26.5.6:
|
ts-jest@^26.5.6:
|
||||||
version "26.5.6"
|
version "26.5.6"
|
||||||
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.6.tgz#c32e0746425274e1dfe333f43cd3c800e014ec35"
|
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.6.tgz#c32e0746425274e1dfe333f43cd3c800e014ec35"
|
||||||
@ -3547,6 +3573,11 @@ typescript@^4.3.4:
|
|||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
|
||||||
integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
|
integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
|
||||||
|
|
||||||
|
uglify-js@^3.1.4:
|
||||||
|
version "3.14.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.5.tgz#cdabb7d4954231d80cb4a927654c4655e51f4859"
|
||||||
|
integrity sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==
|
||||||
|
|
||||||
union-value@^1.0.0:
|
union-value@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
|
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
|
||||||
@ -3628,6 +3659,11 @@ walker@^1.0.7, walker@~1.0.5:
|
|||||||
dependencies:
|
dependencies:
|
||||||
makeerror "1.0.x"
|
makeerror "1.0.x"
|
||||||
|
|
||||||
|
webidl-conversions@^3.0.0:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||||
|
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
|
||||||
|
|
||||||
webidl-conversions@^5.0.0:
|
webidl-conversions@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
|
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
|
||||||
@ -3650,6 +3686,14 @@ whatwg-mimetype@^2.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||||
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
||||||
|
|
||||||
|
whatwg-url@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||||
|
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
|
||||||
|
dependencies:
|
||||||
|
tr46 "~0.0.3"
|
||||||
|
webidl-conversions "^3.0.0"
|
||||||
|
|
||||||
whatwg-url@^8.0.0, whatwg-url@^8.5.0:
|
whatwg-url@^8.0.0, whatwg-url@^8.5.0:
|
||||||
version "8.6.0"
|
version "8.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.6.0.tgz#27c0205a4902084b872aecb97cf0f2a7a3011f4c"
|
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.6.0.tgz#27c0205a4902084b872aecb97cf0f2a7a3011f4c"
|
||||||
@ -3683,6 +3727,11 @@ word-wrap@~1.2.3:
|
|||||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||||
|
|
||||||
|
wordwrap@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||||
|
integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
|
||||||
|
|
||||||
wrap-ansi@^6.2.0:
|
wrap-ansi@^6.2.0:
|
||||||
version "6.2.0"
|
version "6.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
|
||||||
|
Reference in New Issue
Block a user