mirror of
https://github.com/docker/build-push-action.git
synced 2025-06-13 14:47:13 +02:00
Compare commits
129 Commits
Author | SHA1 | Date | |
---|---|---|---|
ad44023a93 | |||
57f367c048 | |||
74242a33cc | |||
2b2d125b68 | |||
5ac438e8df | |||
ae91a8353f | |||
ca26f5b713 | |||
c9589d1941 | |||
95f997534a | |||
655d1f6b37 | |||
6f4938aa75 | |||
18fa566857 | |||
11f0499b05 | |||
f3f2d78b13 | |||
5b3f377cdd | |||
cc23ce7e44 | |||
64708ddf75 | |||
8e208dd401 | |||
bb77c476bd | |||
8e1d874ee2 | |||
3a090ce0da | |||
17822e4df4 | |||
5e92e6623e | |||
3ce082ae8d | |||
d619a7ff00 | |||
19c07384dc | |||
4cef7b9d89 | |||
5676f00637 | |||
c0c3e27be3 | |||
c9b5cc4c4e | |||
6e53d9494f | |||
01f4a7369d | |||
91bb504133 | |||
c4742793d5 | |||
e1b7f96249 | |||
5a4a26c0fc | |||
8891861577 | |||
f6a733366a | |||
eb4f14646c | |||
646552f0a1 | |||
2ec8f1d346 | |||
8f5c91aad9 | |||
6a12baa867 | |||
da940a9403 | |||
9cf6eb2b16 | |||
3c2d8e5269 | |||
d693655c74 | |||
bfea497a8e | |||
8ca2ca55d4 | |||
460e0e47f5 | |||
edb2e175f1 | |||
09f8407c80 | |||
614833a85f | |||
0ec1157bb5 | |||
22d49d64f5 | |||
9379083e42 | |||
a63b18dea2 | |||
af867d4937 | |||
33eec1587d | |||
3db4797dd2 | |||
659fcba376 | |||
080cadd33e | |||
dc4c1fca8b | |||
b280b0485b | |||
b87564a5cc | |||
d2bc6a5d16 | |||
e5f26cdae4 | |||
616efcd405 | |||
0539e1a717 | |||
636b4540ec | |||
af932bfb2e | |||
2db03de115 | |||
4643aec7c4 | |||
4a531fa5a6 | |||
565d16e074 | |||
c473874c2c | |||
b94cedd686 | |||
76c8b42a58 | |||
920f0da143 | |||
e723b420bf | |||
f9deaa080c | |||
b4c22c3e33 | |||
a8587cb818 | |||
f2a733f179 | |||
35ab0dd217 | |||
46d5afd128 | |||
a8bb35be5a | |||
5c278cd8ab | |||
3b98ff3c03 | |||
6b88c3e647 | |||
0db984c182 | |||
35e3637576 | |||
a29353b5c7 | |||
241c03788f | |||
a6ea296fed | |||
13137a8f9b | |||
22b2fa68fc | |||
9ada3141a9 | |||
e53bafea73 | |||
b9335d6c83 | |||
d51711af0d | |||
b0a38c7db9 | |||
6925f94b6b | |||
bf3d577ea5 | |||
1f1cc26e46 | |||
3c98919e7f | |||
eae00c3028 | |||
1471dfb80d | |||
9c13ff40b3 | |||
61a74b1e3a | |||
d3ddc4b4ef | |||
50caab8424 | |||
d971423a6f | |||
ae5ee4ca11 | |||
3c6bad5f82 | |||
6e1d94b6b3 | |||
11ca7847e4 | |||
35f1834293 | |||
d651be4597 | |||
8832f2902d | |||
b6150991af | |||
6b0583b656 | |||
f96d0fb6b7 | |||
9e2f4416f3 | |||
6efc2b01cb | |||
953dc85723 | |||
2e36e439bc | |||
6e7bd99c53 | |||
fa61d38ad8 |
@ -1 +1,2 @@
|
||||
node_modules
|
||||
/coverage
|
||||
/node_modules
|
||||
|
35
.github/CONTRIBUTING.md
vendored
35
.github/CONTRIBUTING.md
vendored
@ -2,33 +2,20 @@
|
||||
|
||||
Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.
|
||||
|
||||
Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE).
|
||||
Contributions to this project are [released](https://docs.github.com/en/github/site-policy/github-terms-of-service#6-contributions-under-repository-license)
|
||||
to the public under the [project's open source license](LICENSE).
|
||||
|
||||
## Submitting a pull request
|
||||
|
||||
1. [Fork](https://github.com/docker/build-push-action/fork) and clone the repository
|
||||
2. Configure and install the dependencies: `yarn install`
|
||||
3. Make sure the tests pass on your machine: `yarn run test`
|
||||
4. Create a new branch: `git checkout -b my-branch-name`
|
||||
5. Make your change, add tests, and make sure the tests still pass
|
||||
6. Run pre-checkin: `yarn run pre-checkin`
|
||||
7. Push to your fork and [submit a pull request](https://github.com/docker/build-push-action/compare)
|
||||
8. Pat your self on the back and wait for your pull request to be reviewed and merged.
|
||||
|
||||
## Container based developer flow
|
||||
|
||||
If you don't want to maintain a Node developer environment that fits this project you can use containerized commands instead of invoking yarn directly.
|
||||
|
||||
```
|
||||
# format code and build javascript artifacts
|
||||
docker buildx bake pre-checkin
|
||||
|
||||
# validate all code has correctly formatted and built
|
||||
docker buildx bake validate
|
||||
|
||||
# run tests
|
||||
docker buildx bake test
|
||||
```
|
||||
3. Create a new branch: `git checkout -b my-branch-name`
|
||||
4. Make your changes
|
||||
5. Make sure the tests pass: `docker buildx bake test`
|
||||
6. Format code and build javascript artifacts: `docker buildx bake pre-checkin`
|
||||
7. Validate all code has correctly formatted and built: `docker buildx bake validate`
|
||||
8. Push to your fork and [submit a pull request](https://github.com/docker/build-push-action/compare)
|
||||
9. Pat your self on the back and wait for your pull request to be reviewed and merged.
|
||||
|
||||
Here are a few things you can do that will increase the likelihood of your pull request being accepted:
|
||||
|
||||
@ -40,5 +27,5 @@ Here are a few things you can do that will increase the likelihood of your pull
|
||||
## Resources
|
||||
|
||||
- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
|
||||
- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
|
||||
- [GitHub Help](https://help.github.com)
|
||||
- [Using Pull Requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests)
|
||||
- [GitHub Help](https://docs.github.com/en)
|
||||
|
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -34,4 +34,4 @@ Before sumbitting a bug report please read the [Troubleshooting doc](https://git
|
||||
|
||||
### Logs
|
||||
|
||||
> Download the [log file of your build](https://help.github.com/en/actions/configuring-and-managing-workflows/managing-a-workflow-run#downloading-logs) and [attach it](https://help.github.com/en/github/managing-your-work-on-github/file-attachments-on-issues-and-pull-requests) to this issue.
|
||||
> Download the [log file of your build](https://docs.github.com/en/actions/managing-workflow-runs/using-workflow-run-logs#downloading-logs) and [attach it](https://docs.github.com/en/github/managing-your-work-on-github/file-attachments-on-issues-and-pull-requests) to this issue.
|
||||
|
BIN
.github/build-push-action.png
vendored
BIN
.github/build-push-action.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 29 KiB |
79
.github/labels.yml
vendored
79
.github/labels.yml
vendored
@ -1,79 +0,0 @@
|
||||
## more info https://github.com/crazy-max/ghaction-github-labeler
|
||||
- # automerge
|
||||
name: ":bell: automerge"
|
||||
color: "8f4fbc"
|
||||
description: ""
|
||||
- # bot
|
||||
name: ":robot: bot"
|
||||
color: "69cde9"
|
||||
description: ""
|
||||
- # bug
|
||||
name: ":bug: bug"
|
||||
color: "b60205"
|
||||
description: ""
|
||||
- # dependencies
|
||||
name: ":game_die: dependencies"
|
||||
color: "0366d6"
|
||||
description: ""
|
||||
from_name: "dependencies"
|
||||
- # documentation
|
||||
name: ":memo: documentation"
|
||||
color: "c5def5"
|
||||
description: ""
|
||||
- # duplicate
|
||||
name: ":busts_in_silhouette: duplicate"
|
||||
color: "cccccc"
|
||||
description: ""
|
||||
- # enhancement
|
||||
name: ":sparkles: enhancement"
|
||||
color: "0054ca"
|
||||
description: ""
|
||||
- # feature request
|
||||
name: ":bulb: feature request"
|
||||
color: "0e8a16"
|
||||
description: ""
|
||||
- # feedback
|
||||
name: ":mega: feedback"
|
||||
color: "03a9f4"
|
||||
description: ""
|
||||
- # future maybe
|
||||
name: ":rocket: future maybe"
|
||||
color: "fef2c0"
|
||||
description: ""
|
||||
- # good first issue
|
||||
name: ":hatching_chick: good first issue"
|
||||
color: "7057ff"
|
||||
description: ""
|
||||
- # help wanted
|
||||
name: ":pray: help wanted"
|
||||
color: "4caf50"
|
||||
description: ""
|
||||
- # hold
|
||||
name: ":hand: hold"
|
||||
color: "24292f"
|
||||
description: ""
|
||||
- # invalid
|
||||
name: ":no_entry_sign: invalid"
|
||||
color: "e6e6e6"
|
||||
description: ""
|
||||
- # maybe bug
|
||||
name: ":interrobang: maybe bug"
|
||||
color: "ff5722"
|
||||
description: ""
|
||||
- # needs more info
|
||||
name: ":thinking: needs more info"
|
||||
color: "795548"
|
||||
description: ""
|
||||
- # question
|
||||
name: ":question: question"
|
||||
color: "3f51b5"
|
||||
description: ""
|
||||
from_name: "question"
|
||||
- # upstream
|
||||
name: ":eyes: upstream"
|
||||
color: "fbca04"
|
||||
description: ""
|
||||
- # wontfix
|
||||
name: ":coffin: wontfix"
|
||||
color: "ffffff"
|
||||
description: ""
|
115
.github/workflows/ci.yml
vendored
115
.github/workflows/ci.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: action
|
||||
-
|
||||
@ -41,7 +41,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: action
|
||||
-
|
||||
@ -95,7 +95,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: action
|
||||
-
|
||||
@ -121,6 +121,14 @@ jobs:
|
||||
localhost:5000/name/app:1.0.0
|
||||
secrets: |
|
||||
GIT_AUTH_TOKEN=${{ github.token }}
|
||||
"MYSECRET=aaaaaaaa
|
||||
bbbbbbb
|
||||
ccccccccc"
|
||||
FOO=bar
|
||||
"EMPTYLINE=aaaa
|
||||
|
||||
bbbb
|
||||
ccc"
|
||||
-
|
||||
name: Inspect
|
||||
run: |
|
||||
@ -156,7 +164,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
@ -203,7 +211,38 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Stop docker
|
||||
run: |
|
||||
sudo systemctl stop docker
|
||||
-
|
||||
name: Build
|
||||
id: docker_build
|
||||
continue-on-error: true
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile
|
||||
-
|
||||
name: Check
|
||||
run: |
|
||||
echo "${{ toJson(steps.docker_build) }}"
|
||||
if [ "${{ steps.docker_build.outcome }}" != "failure" ] || [ "${{ steps.docker_build.conclusion }}" != "success" ]; then
|
||||
echo "::error::Should have failed"
|
||||
exit 1
|
||||
fi
|
||||
-
|
||||
name: Dump context
|
||||
if: always()
|
||||
uses: crazy-max/ghaction-dump-context@v1
|
||||
|
||||
error-buildx:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
@ -236,12 +275,6 @@ jobs:
|
||||
|
||||
docker-driver:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
push:
|
||||
- true
|
||||
- false
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
@ -250,28 +283,16 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Build
|
||||
id: docker_build
|
||||
continue-on-error: ${{ matrix.push }}
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile
|
||||
push: ${{ matrix.push }}
|
||||
push: true
|
||||
tags: localhost:5000/name/app:latest
|
||||
-
|
||||
name: Check
|
||||
run: |
|
||||
echo "${{ toJson(steps.docker_build) }}"
|
||||
if [ "${{ matrix.push }}" = "false" ]; then
|
||||
exit 0
|
||||
fi
|
||||
if [ "${{ steps.docker_build.outcome }}" != "failure" ] || [ "${{ steps.docker_build.conclusion }}" != "success" ]; then
|
||||
echo "::error::Should have failed"
|
||||
exit 1
|
||||
fi
|
||||
-
|
||||
name: Dump context
|
||||
if: always()
|
||||
@ -282,7 +303,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Build
|
||||
uses: ./
|
||||
@ -300,6 +321,30 @@ jobs:
|
||||
if: always()
|
||||
uses: crazy-max/ghaction-dump-context@v1
|
||||
|
||||
network:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: List networks
|
||||
run: docker network ls
|
||||
-
|
||||
name: Build
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
tags: name/app:latest
|
||||
network: host
|
||||
-
|
||||
name: Dump context
|
||||
if: always()
|
||||
uses: crazy-max/ghaction-dump-context@v1
|
||||
|
||||
multi:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
@ -319,7 +364,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
@ -336,7 +381,7 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile-${{ matrix.dockerfile }}
|
||||
file: ./test/${{ matrix.dockerfile }}.Dockerfile
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
@ -372,7 +417,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
@ -389,7 +434,7 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile-multi
|
||||
file: ./test/multi.Dockerfile
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
@ -422,7 +467,7 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile-multi
|
||||
file: ./test/multi.Dockerfile
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
@ -470,7 +515,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
@ -499,7 +544,7 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile-multi
|
||||
file: ./test/multi.Dockerfile
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
@ -538,7 +583,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
@ -564,7 +609,7 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile-multi
|
||||
file: ./test/multi.Dockerfile
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
|
105
.github/workflows/e2e.yml
vendored
Normal file
105
.github/workflows/e2e.yml
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
name: e2e
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # everyday at 10am
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
-
|
||||
registry: ''
|
||||
slug: ghactionstest/ghactionstest
|
||||
username_secret: DOCKERHUB_USERNAME
|
||||
password_secret: DOCKERHUB_TOKEN
|
||||
-
|
||||
registry: ghcr.io
|
||||
slug: ghcr.io/docker-ghactiontest/test
|
||||
username_secret: GHCR_USERNAME
|
||||
password_secret: GHCR_PAT
|
||||
-
|
||||
registry: registry.gitlab.com
|
||||
slug: registry.gitlab.com/test1716/test
|
||||
username_secret: GITLAB_USERNAME
|
||||
password_secret: GITLAB_TOKEN
|
||||
-
|
||||
registry: 175142243308.dkr.ecr.us-east-2.amazonaws.com
|
||||
slug: 175142243308.dkr.ecr.us-east-2.amazonaws.com/sandbox/test-docker-action
|
||||
username_secret: AWS_ACCESS_KEY_ID
|
||||
password_secret: AWS_SECRET_ACCESS_KEY
|
||||
-
|
||||
registry: public.ecr.aws
|
||||
slug: public.ecr.aws/q3b5f1u4/test-docker-action
|
||||
username_secret: AWS_ACCESS_KEY_ID
|
||||
password_secret: AWS_SECRET_ACCESS_KEY
|
||||
-
|
||||
registry: us-east4-docker.pkg.dev
|
||||
slug: us-east4-docker.pkg.dev/sandbox-298914/docker-official-github-actions/test-docker-action
|
||||
username_secret: GAR_USERNAME
|
||||
password_secret: GAR_JSON_KEY
|
||||
-
|
||||
registry: gcr.io
|
||||
slug: gcr.io/sandbox-298914/test-docker-action
|
||||
username_secret: GCR_USERNAME
|
||||
password_secret: GCR_JSON_KEY
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: ${{ matrix.slug }}
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Login to Registry
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ${{ matrix.registry }}
|
||||
username: ${{ secrets[matrix.username_secret] }}
|
||||
password: ${{ secrets[matrix.password_secret] }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: ./
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/multi.Dockerfile
|
||||
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=registry,ref=${{ matrix.slug }}:master
|
||||
cache-to: type=inline
|
||||
-
|
||||
name: Inspect image
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
docker pull ${{ matrix.slug }}:${{ steps.meta.outputs.version }}
|
||||
docker image inspect ${{ matrix.slug }}:${{ steps.meta.outputs.version }}
|
||||
-
|
||||
name: Check manifest
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ matrix.slug }}:${{ steps.meta.outputs.version }}
|
||||
-
|
||||
name: Dump context
|
||||
if: always()
|
||||
uses: crazy-max/ghaction-dump-context@v1
|
73
.github/workflows/example.yml
vendored
73
.github/workflows/example.yml
vendored
@ -1,5 +1,4 @@
|
||||
# This workflow is provided just as an usage example and not for repo testing/verification
|
||||
# See https://github.com/docker/build-push-action#complete-workflow
|
||||
name: example
|
||||
|
||||
on:
|
||||
@ -12,6 +11,9 @@ on:
|
||||
- 'v*.*.*'
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
DOCKER_IMAGE: localhost:5000/name/app
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
@ -23,36 +25,21 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
DOCKER_IMAGE=localhost:5000/name/app
|
||||
VERSION=noop
|
||||
if [ "${{ github.event_name }}" = "schedule" ]; then
|
||||
VERSION=nightly
|
||||
elif [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
elif [[ $GITHUB_REF == refs/heads/* ]]; then
|
||||
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
|
||||
if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ]; then
|
||||
VERSION=edge
|
||||
fi
|
||||
elif [[ $GITHUB_REF == refs/pull/* ]]; then
|
||||
VERSION=pr-${{ github.event.number }}
|
||||
fi
|
||||
TAGS="${DOCKER_IMAGE}:${VERSION}"
|
||||
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
MINOR=${VERSION%.*}
|
||||
MAJOR=${MINOR%.*}
|
||||
TAGS="$TAGS,${DOCKER_IMAGE}:${MINOR},${DOCKER_IMAGE}:${MAJOR},${DOCKER_IMAGE}:latest"
|
||||
elif [ "${{ 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: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: ${{ env.DOCKER_IMAGE }}
|
||||
tags: |
|
||||
type=schedule
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
@ -64,15 +51,9 @@ jobs:
|
||||
with:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile
|
||||
outputs: type=docker
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
labels: |
|
||||
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
|
||||
org.opencontainers.image.url=${{ github.event.repository.html_url }}
|
||||
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
|
||||
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
org.opencontainers.image.licenses=${{ github.event.repository.license.spdx_id }}
|
||||
load: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
-
|
||||
name: Build and push to local registry
|
||||
uses: ./
|
||||
@ -80,23 +61,17 @@ jobs:
|
||||
context: ./test
|
||||
file: ./test/Dockerfile
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
labels: |
|
||||
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
|
||||
org.opencontainers.image.url=${{ github.event.repository.html_url }}
|
||||
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
|
||||
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
org.opencontainers.image.licenses=${{ github.event.repository.license.spdx_id }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
-
|
||||
name: Inspect image
|
||||
run: |
|
||||
docker image inspect localhost:5000/name/app:${{ steps.prep.outputs.version }}
|
||||
docker image inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }}
|
||||
-
|
||||
name: Check manifest
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
docker buildx imagetools inspect localhost:5000/name/app:${{ steps.prep.outputs.version }}
|
||||
docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }}
|
||||
-
|
||||
name: Dump context
|
||||
if: always()
|
||||
|
20
.github/workflows/labels.yml
vendored
20
.github/workflows/labels.yml
vendored
@ -1,20 +0,0 @@
|
||||
name: labels
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
paths:
|
||||
- '.github/labels.yml'
|
||||
- '.github/workflows/labels.yml'
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
-
|
||||
name: Run Labeler
|
||||
uses: crazy-max/ghaction-github-labeler@v3.1.0
|
33
.github/workflows/test.yml
vendored
33
.github/workflows/test.yml
vendored
@ -3,41 +3,30 @@ name: test
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- 'master'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
test-containerized:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
-
|
||||
name: Validate
|
||||
run: docker buildx bake validate
|
||||
-
|
||||
name: Test
|
||||
run: docker buildx bake test
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2.3.3
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Install
|
||||
run: yarn install
|
||||
name: Validate
|
||||
uses: docker/bake-action@v1
|
||||
with:
|
||||
targets: validate
|
||||
-
|
||||
name: Test
|
||||
run: yarn run test
|
||||
uses: docker/bake-action@v1
|
||||
with:
|
||||
targets: test
|
||||
-
|
||||
name: Upload coverage
|
||||
uses: codecov/codecov-action@v1.0.14
|
||||
if: success()
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
file: ./coverage/clover.xml
|
||||
|
38
.github/workflows/virtual-env.yml
vendored
Normal file
38
.github/workflows/virtual-env.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: virtual-env
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # everyday at 10am
|
||||
|
||||
jobs:
|
||||
os:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- ubuntu-20.04
|
||||
- ubuntu-18.04
|
||||
- ubuntu-16.04
|
||||
steps:
|
||||
-
|
||||
name: List install packages
|
||||
run: apt list --installed
|
||||
-
|
||||
name: Docker info
|
||||
run: docker info
|
||||
-
|
||||
name: Docker version
|
||||
run: docker version
|
||||
-
|
||||
name: buildx version
|
||||
run: docker buildx version
|
||||
-
|
||||
name: containerd version
|
||||
run: containerd --version
|
||||
-
|
||||
name: Dump context
|
||||
if: always()
|
||||
uses: crazy-max/ghaction-dump-context@v1
|
52
Dockerfile
52
Dockerfile
@ -1,52 +0,0 @@
|
||||
#syntax=docker/dockerfile:1.1-experimental
|
||||
|
||||
FROM node:12 AS deps
|
||||
WORKDIR /src
|
||||
COPY package.json yarn.lock ./
|
||||
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn \
|
||||
yarn install
|
||||
|
||||
FROM scratch AS update-yarn
|
||||
COPY --from=deps /src/yarn.lock /
|
||||
|
||||
FROM deps AS validate-yarn
|
||||
COPY .git .git
|
||||
RUN status=$(git status --porcelain -- yarn.lock); if [ -n "$status" ]; then echo $status; exit 1; fi
|
||||
|
||||
FROM deps AS base
|
||||
COPY . .
|
||||
|
||||
FROM base AS build
|
||||
RUN yarn build
|
||||
|
||||
FROM deps AS test
|
||||
COPY --from=docker /usr/local/bin/docker /usr/bin/
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
ARG BUILDX_VERSION=v0.4.2
|
||||
ENV RUNNER_TEMP=/tmp/github_runner
|
||||
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
|
||||
RUN mkdir -p /usr/local/lib/docker/cli-plugins && \
|
||||
curl -fsSL https://github.com/docker/buildx/releases/download/$BUILDX_VERSION/buildx-$BUILDX_VERSION.$TARGETOS-$TARGETARCH > /usr/local/lib/docker/cli-plugins/docker-buildx && \
|
||||
chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx && \
|
||||
docker buildx version
|
||||
COPY . .
|
||||
RUN yarn run test
|
||||
|
||||
FROM base AS run-format
|
||||
RUN yarn run format
|
||||
|
||||
FROM scratch AS format
|
||||
COPY --from=run-format /src/src/*.ts /src/
|
||||
|
||||
FROM base AS validate-format
|
||||
RUN yarn run format-check
|
||||
|
||||
FROM scratch AS dist
|
||||
COPY --from=build /src/dist/ /dist/
|
||||
|
||||
FROM build AS validate-build
|
||||
RUN status=$(git status --porcelain -- dist); if [ -n "$status" ]; then echo $status; exit 1; fi
|
||||
|
||||
FROM base AS dev
|
||||
ENTRYPOINT ["bash"]
|
617
README.md
617
README.md
@ -6,23 +6,18 @@
|
||||
|
||||
## Upgrade from v1
|
||||
|
||||
`v2` of this action includes significant updates and now uses Docker [Buildx](https://github.com/docker/buildx). It
|
||||
works with 3 new actions ([login](https://github.com/docker/login-action), [setup-buildx](https://github.com/docker/setup-buildx-action)
|
||||
and [setup-qemu](https://github.com/docker/setup-qemu-action)) that we have created. It's also rewritten as a
|
||||
[typescript-action](https://github.com/actions/typescript-action/) to be as closed as possible of the
|
||||
[GitHub Runner](https://github.com/actions/virtual-environments) during its execution.
|
||||
`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) and many [usage examples](#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).
|
||||
[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
|
||||
|
||||
GitHub Action to build and push Docker images with [Buildx](https://github.com/docker/buildx).
|
||||
|
||||
> :bulb: See also:
|
||||
> * [login](https://github.com/docker/login-action) action
|
||||
> * [setup-buildx](https://github.com/docker/setup-buildx-action) action
|
||||
> * [setup-qemu](https://github.com/docker/setup-qemu-action) action
|
||||
GitHub Action to build and push Docker images with [Buildx](https://github.com/docker/buildx) with full support of the
|
||||
features provided by [Moby BuildKit](https://github.com/moby/buildkit) builder toolkit. This includes multi-platform
|
||||
build, secrets, remote cache, etc. and different builder deployment/namespacing options.
|
||||
|
||||

|
||||
|
||||
@ -31,44 +26,59 @@ ___
|
||||
* [Usage](#usage)
|
||||
* [Git context](#git-context)
|
||||
* [Path context](#path-context)
|
||||
* [Isolated builders](#isolated-builders)
|
||||
* [Multi-platform image](#multi-platform-image)
|
||||
* [Advanced usage](#advanced-usage)
|
||||
* [Push to multi-registries](#push-to-multi-registries)
|
||||
* [Cache to registry](#push-to-multi-registries)
|
||||
* [Local registry](#local-registry)
|
||||
* [Export image to Docker](#export-image-to-docker)
|
||||
* [Leverage GitHub cache](#leverage-github-cache)
|
||||
* [Complete workflow](#complete-workflow)
|
||||
* [Update DockerHub repo description](#update-dockerhub-repo-description)
|
||||
* [Multi-platform image](docs/advanced/multi-platform.md)
|
||||
* [Secrets](docs/advanced/secrets.md)
|
||||
* [Isolated builders](docs/advanced/isolated-builders.md)
|
||||
* [Push to multi-registries](docs/advanced/push-multi-registries.md)
|
||||
* [Copy between registries](docs/advanced/copy-between-registries.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)
|
||||
* [Export image to Docker](docs/advanced/export-docker.md)
|
||||
* [Share built image between jobs](docs/advanced/share-image-jobs.md)
|
||||
* [Handle tags and labels](docs/advanced/tags-labels.md)
|
||||
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md)
|
||||
* [Customizing](#customizing)
|
||||
* [inputs](#inputs)
|
||||
* [outputs](#outputs)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
* [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot)
|
||||
* [Limitation](#limitation)
|
||||
|
||||
## Usage
|
||||
|
||||
This action uses our [setup-buildx](https://github.com/docker/setup-buildx-action) action that extends the
|
||||
`docker build` command named [buildx](https://github.com/docker/buildx) with the full support of the features
|
||||
provided by [Moby BuildKit](https://github.com/moby/buildkit) builder toolkit. This includes multi-arch build,
|
||||
build-secrets, remote cache, etc. and different builder deployment/namespacing options.
|
||||
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 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
|
||||
default the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver).
|
||||
This is **not required but recommended** using it to be able to build multi-platform images, export cache, etc.
|
||||
* [`setup-qemu`](https://github.com/docker/setup-qemu-action) action can be useful if you want
|
||||
to add emulation support with QEMU to be able to build against more platforms.
|
||||
* [`login`](https://github.com/docker/login-action) action will take care to log in against a Docker registry.
|
||||
|
||||
### Git context
|
||||
|
||||
The default behavior of this action is to use the [Git context invoked](https://github.com/docker/build-push-action/blob/master/src/context.ts#L31-L35)
|
||||
by your workflow.
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
main:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
@ -90,17 +100,14 @@ jobs:
|
||||
with:
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
build-args: |
|
||||
arg1=value1
|
||||
arg2=value2
|
||||
-
|
||||
name: Image digest
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
```
|
||||
|
||||
Building from current repository automatically uses the [GitHub Token](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token)
|
||||
as provided by `secrets` so it does not need to be passed. But if you want to authenticate against another private
|
||||
repository, you have to use a secret named `GIT_AUTH_TOKEN` to be able to authenticate against it with buildx:
|
||||
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
|
||||
-
|
||||
@ -114,24 +121,21 @@ repository, you have to use a secret named `GIT_AUTH_TOKEN` to be able to authen
|
||||
GIT_AUTH_TOKEN=${{ secrets.MYTOKEN }}
|
||||
```
|
||||
|
||||
> :warning: Subdir for Git context is [not yet supported](https://github.com/docker/build-push-action/issues/120).
|
||||
> For the moment you can use the [path context](#path-context).
|
||||
|
||||
> More info: https://docs.docker.com/engine/reference/commandline/build/#git-repositories
|
||||
> :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
|
||||
|
||||
You can also use the `PATH` context alongside the [`actions/checkout`](https://github.com/actions/checkout/) action.
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
path-context:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
@ -154,487 +158,25 @@ jobs:
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64,linux/arm64,linux/386
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
```
|
||||
|
||||
### Isolated builders
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
|
||||
jobs:
|
||||
multi-builders:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
uses: docker/setup-buildx-action@v1
|
||||
id: builder1
|
||||
-
|
||||
uses: docker/setup-buildx-action@v1
|
||||
id: builder2
|
||||
-
|
||||
name: Builder 1 name
|
||||
run: echo ${{ steps.builder1.outputs.name }}
|
||||
-
|
||||
name: Builder 2 name
|
||||
run: echo ${{ steps.builder2.outputs.name }}
|
||||
-
|
||||
name: Build against builder1
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
builder: ${{ steps.builder1.outputs.name }}
|
||||
target: mytarget1
|
||||
-
|
||||
name: Build against builder2
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
builder: ${{ steps.builder2.outputs.name }}
|
||||
target: mytarget2
|
||||
```
|
||||
|
||||
### Multi-platform image
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
|
||||
jobs:
|
||||
multi:
|
||||
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 push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
|
||||
push: true
|
||||
tags: |
|
||||
user/app:latest
|
||||
user/app:1.0.0
|
||||
```
|
||||
|
||||
## Advanced usage
|
||||
|
||||
### Push to multi-registries
|
||||
|
||||
The following workflow will connect you to [DockerHub](https://github.com/docker/login-action#dockerhub)
|
||||
and [GitHub Container Registry](https://github.com/docker/login-action#github-container-registry) and push the
|
||||
image to these registries.
|
||||
|
||||
<details>
|
||||
<summary><b>Show workflow</b></summary>
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
|
||||
jobs:
|
||||
multi-registries:
|
||||
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: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.CR_PAT }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
|
||||
push: true
|
||||
tags: |
|
||||
user/app:latest
|
||||
user/app:1.0.0
|
||||
ghcr.io/user/app:latest
|
||||
ghcr.io/user/app:1.0.0
|
||||
```
|
||||
</details>
|
||||
|
||||
### Cache to registry
|
||||
|
||||
You can import/export cache from a cache manifest or (special) image configuration on the registry.
|
||||
|
||||
<details>
|
||||
<summary><b>Show workflow</b></summary>
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
|
||||
jobs:
|
||||
registry-cache:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
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:
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
cache-from: type=registry,ref=user/app:latest
|
||||
cache-to: type=inline
|
||||
```
|
||||
</details>
|
||||
|
||||
### Local registry
|
||||
|
||||
For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry) to push images into:
|
||||
|
||||
<details>
|
||||
<summary><b>Show workflow</b></summary>
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
|
||||
jobs:
|
||||
local-registry:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
steps:
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
driver-opts: network=host
|
||||
-
|
||||
name: Build and push to local registry
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
tags: localhost:5000/name/app:latest
|
||||
-
|
||||
name: Inspect
|
||||
run: |
|
||||
docker buildx imagetools inspect localhost:5000/name/app:latest
|
||||
```
|
||||
</details>
|
||||
|
||||
### Export image to Docker
|
||||
|
||||
You may want your build result to be available in the Docker client through `docker images` to be able to use it
|
||||
in another step of your workflow:
|
||||
|
||||
<details>
|
||||
<summary><b>Show workflow</b></summary>
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
|
||||
jobs:
|
||||
export-docker:
|
||||
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: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
load: true
|
||||
tags: myimage:latest
|
||||
-
|
||||
name: Inspect
|
||||
run: |
|
||||
docker image inspect myimage:latest
|
||||
```
|
||||
</details>
|
||||
|
||||
### Leverage GitHub cache
|
||||
|
||||
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:
|
||||
|
||||
<details>
|
||||
<summary><b>Show workflow</b></summary>
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
|
||||
jobs:
|
||||
github-cache:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
-
|
||||
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:
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||
```
|
||||
</details>
|
||||
|
||||
> If you want to [export layers for all stages](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue),
|
||||
> you have to specify `mode=max` attribute in `cache-to`.
|
||||
|
||||
### Complete workflow
|
||||
|
||||
If you come from [`v1`](https://github.com/docker/build-push-action/tree/releases/v1#readme) and want an
|
||||
"automatic" tag management through Git reference and [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md)
|
||||
for labels, you will have to do it in a dedicated step.
|
||||
|
||||
The following workflow with the `Prepare` step will generate some [outputs](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjobs_idoutputs)
|
||||
to handle tags and labels based on GitHub actions events.
|
||||
|
||||
This is just an example to show many cases that you might want to use and that you will have to adapt according
|
||||
to your needs:
|
||||
|
||||
<details>
|
||||
<summary><b>Show workflow</b></summary>
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # everyday at 10am
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Repo metadata
|
||||
id: repo
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
script: |
|
||||
const repo = await github.repos.get(context.repo)
|
||||
return repo.data
|
||||
-
|
||||
name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
DOCKER_IMAGE=name/app
|
||||
VERSION=noop
|
||||
if [ "${{ github.event_name }}" = "schedule" ]; then
|
||||
VERSION=nightly
|
||||
elif [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
elif [[ $GITHUB_REF == refs/heads/* ]]; then
|
||||
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
|
||||
if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ]; then
|
||||
VERSION=edge
|
||||
fi
|
||||
elif [[ $GITHUB_REF == refs/pull/* ]]; then
|
||||
VERSION=pr-${{ github.event.number }}
|
||||
fi
|
||||
TAGS="${DOCKER_IMAGE}:${VERSION}"
|
||||
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
MINOR=${VERSION%.*}
|
||||
MAJOR=${MINOR%.*}
|
||||
TAGS="$TAGS,${DOCKER_IMAGE}:${MINOR},${DOCKER_IMAGE}:${MAJOR},${DOCKER_IMAGE}:latest"
|
||||
elif [ "${{ 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 QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64,linux/arm64,linux/386
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
labels: |
|
||||
org.opencontainers.image.title=${{ fromJson(steps.repo.outputs.result).name }}
|
||||
org.opencontainers.image.description=${{ fromJson(steps.repo.outputs.result).description }}
|
||||
org.opencontainers.image.url=${{ fromJson(steps.repo.outputs.result).html_url }}
|
||||
org.opencontainers.image.source=${{ fromJson(steps.repo.outputs.result).clone_url }}
|
||||
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
|
||||
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
org.opencontainers.image.licenses=${{ fromJson(steps.repo.outputs.result).license.spdx_id }}
|
||||
```
|
||||
</details>
|
||||
|
||||
| Event | Ref | Commit SHA | Docker Tag | Pushed |
|
||||
|-----------------|-------------------------------|------------|------------------------------------|--------|
|
||||
| `schedule` | | | `nightly` | Yes |
|
||||
| `pull_request` | `refs/pull/2/merge` | `a123b57` | `pr-2` | No |
|
||||
| `push` | `refs/heads/<default_branch>` | `676cae2` | `sha-676cae2`, `edge` | Yes |
|
||||
| `push` | `refs/heads/dev` | `cf20257` | `sha-cf20257`, `dev` | Yes |
|
||||
| `push` | `refs/heads/my/branch` | `a5df687` | `sha-a5df687`, `my-branch` | Yes |
|
||||
| `push tag` | `refs/tags/v1.2.3` | | `v1.2.3`, `v1.2`, `v1`, `latest` | Yes |
|
||||
|
||||
### Update DockerHub repo description
|
||||
|
||||
You can update the [DockerHub repository description](https://docs.docker.com/docker-hub/repos/) using
|
||||
a third-party action called [DockerHub Description](https://github.com/peter-evans/dockerhub-description)
|
||||
with this action:
|
||||
|
||||
<details>
|
||||
<summary><b>Show workflow</b></summary>
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: master
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
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 push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
-
|
||||
name: Update repo description
|
||||
uses: peter-evans/dockerhub-description@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
repository: user/app
|
||||
```
|
||||
</details>
|
||||
* [Multi-platform image](docs/advanced/multi-platform.md)
|
||||
* [Secrets](docs/advanced/secrets.md)
|
||||
* [Isolated builders](docs/advanced/isolated-builders.md)
|
||||
* [Push to multi-registries](docs/advanced/push-multi-registries.md)
|
||||
* [Copy between registries](docs/advanced/copy-between-registries.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)
|
||||
* [Export image to Docker](docs/advanced/export-docker.md)
|
||||
* [Share built image between jobs](docs/advanced/share-image-jobs.md)
|
||||
* [Handle tags and labels](docs/advanced/tags-labels.md)
|
||||
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md)
|
||||
|
||||
## Customizing
|
||||
|
||||
@ -656,23 +198,26 @@ Following inputs can be used as `step.with` keys
|
||||
|
||||
| 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`) |
|
||||
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
|
||||
| `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 `Dockerfile`) |
|
||||
| `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-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`) |
|
||||
| `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`) |
|
||||
| `labels` | List | List of metadata for an image |
|
||||
| `tags` | List/CSV | List of tags |
|
||||
| `pull` | Bool | Always attempt to pull a newer version of the image (default `false`) |
|
||||
| `target` | String | Sets the target stage to build |
|
||||
| `allow` | List/CSV | List of [extra privileged entitlement](https://github.com/docker/buildx#--allowentitlement) (eg. `network.host,security.insecure`) |
|
||||
| `load` | Bool | [Load](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#load) is a shorthand for `--output=type=docker` (default `false`) |
|
||||
| `network` | String | Set the networking mode for the `RUN` instructions during build |
|
||||
| `no-cache` | Bool | Do not use cache when building the image (default `false`) |
|
||||
| `platforms` | List/CSV | List of [target platforms](https://github.com/docker/buildx#---platformvaluevalue) for build |
|
||||
| `load` | Bool | [Load](https://github.com/docker/buildx#--load) is a shorthand for `--output=type=docker` (default `false`) |
|
||||
| `push` | Bool | [Push](https://github.com/docker/buildx#--push) is a shorthand for `--output=type=registry` (default `false`) |
|
||||
| `outputs` | List | List of [output destinations](https://github.com/docker/buildx#-o---outputpath-typetypekeyvalue) (format: `type=local,dest=path`) |
|
||||
| `cache-from` | List | List of [external cache sources](https://github.com/docker/buildx#--cache-fromnametypetypekeyvalue) (eg. `type=local,src=path/to/dir`) |
|
||||
| `cache-to` | List | List of [cache export destinations](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue) (eg. `type=local,dest=path/to/dir`) |
|
||||
| `secrets` | List | List of secrets to expose to the build (eg. `key=value`, `GIT_AUTH_TOKEN=mytoken`) |
|
||||
| `outputs` | List | List of [output destinations](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#output) (format: `type=local,dest=path`) |
|
||||
| `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`) |
|
||||
| `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`) |
|
||||
| `secret-files` | List | List of secret files to expose to the build (eg. `key=filename`, `MY_SECRET=./secret.txt`) |
|
||||
| `ssh` | List | List of SSH agent socket or keys to expose to the build |
|
||||
| `tags` | List/CSV | List of tags |
|
||||
| `target` | String | Sets the target stage to build |
|
||||
|
||||
### outputs
|
||||
|
||||
@ -701,7 +246,3 @@ updates:
|
||||
schedule:
|
||||
interval: "daily"
|
||||
```
|
||||
|
||||
## Limitation
|
||||
|
||||
This action is only available for Linux [virtual environments](https://help.github.com/en/articles/virtual-environments-for-github-actions#supported-virtual-environments-and-hardware-resources).
|
||||
|
@ -1,112 +1,8 @@
|
||||
# Troubleshooting
|
||||
|
||||
* [`auto-push is currently not implemented for docker driver`](#auto-push-is-currently-not-implemented-for-docker-driver)
|
||||
* [Cannot push to a registry](#cannot-push-to-a-registry)
|
||||
|
||||
## `auto-push is currently not implemented for docker driver`
|
||||
|
||||
If you're using the default builder (which uses the docker driver) without using our `setup-buildx-action`, you may
|
||||
encounter this error message if you try to push your image:
|
||||
|
||||
```
|
||||
Run docker/build-push-action@v2
|
||||
📣 Buildx version: 0.4.2
|
||||
🏃 Starting build...
|
||||
/usr/bin/docker buildx build --tag localhost:5000/name/app:latest --iidfile /tmp/docker-build-push-eYl8PB/iidfile --file ./test/Dockerfile --push ./test
|
||||
auto-push is currently not implemented for docker driver
|
||||
Error: buildx call failed with: auto-push is currently not implemented for docker driver
|
||||
```
|
||||
|
||||
While waiting for an implementation to be done on buildx/buildkit, you have the following possibilities
|
||||
to solve this atm:
|
||||
|
||||
### With `docker-container` driver and `setup-buildx`
|
||||
|
||||
> Recommended solution
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Login
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.USER }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
tags: ${{ env.REGISTRY }}/myapp:latest
|
||||
push: true
|
||||
```
|
||||
|
||||
### With `docker` driver
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Login
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.USER }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
tags: ${{ env.REGISTRY }}/myapp:latest
|
||||
load: true
|
||||
-
|
||||
name: Push
|
||||
run: docker push ${{ env.REGISTRY }}/myapp:latest
|
||||
```
|
||||
|
||||
### With `docker` driver and `setup-buildx`
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
driver: docker
|
||||
-
|
||||
name: Login
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.USER }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
-
|
||||
name: Build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
tags: ${{ env.REGISTRY }}/myapp:latest
|
||||
load: true
|
||||
-
|
||||
name: Push
|
||||
run: docker push ${{ env.REGISTRY }}/myapp:latest
|
||||
```
|
||||
* [BuildKit container logs](#buildkit-container-logs)
|
||||
* [With containerd](#with-containerd)
|
||||
|
||||
## Cannot push to a registry
|
||||
|
||||
@ -122,16 +18,12 @@ These issues are not directly related to this action but are rather linked to [b
|
||||
[buildkit](https://github.com/moby/buildkit), [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.
|
||||
|
||||
To help you solve this, you should first enable debugging in the
|
||||
[setup-buildx action step](https://github.com/docker/setup-buildx-action):
|
||||
### BuildKit container logs
|
||||
|
||||
```yaml
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
buildkitd-flags: --debug
|
||||
```
|
||||
To help you solve this, you have to [enable debugging in the setup-buildx](https://github.com/docker/setup-buildx-action#buildkit-container-logs)
|
||||
action step and attach BuildKit container logs to your issue.
|
||||
|
||||
### With containerd
|
||||
|
||||
Next you can test pushing with [containerd action](https://github.com/crazy-max/ghaction-setup-containerd) using the
|
||||
following workflow. If it works then open an issue on [buildkit](https://github.com/moby/buildkit) repository.
|
||||
@ -165,8 +57,7 @@ jobs:
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: docker.io/user/app:latest
|
||||
outputs: type=oci,dest=/tmp/image.tar
|
||||
-
|
||||
|
21
UPGRADE.md
21
UPGRADE.md
@ -7,12 +7,13 @@
|
||||
* Rename `dockerfile` input to `file` for consistency with other Docker build tools
|
||||
* Rename `always_pull` input to `pull` for consistency with other Docker build tools
|
||||
* Add `builder` input to be able to choose a builder instance through our [setup-buildx action](https://github.com/docker/setup-buildx-action)
|
||||
* Add [`platforms`](https://github.com/docker/buildx#---platformvaluevalue) input to support multi-platform builds
|
||||
* Add [`allow`](https://github.com/docker/buildx#--allowentitlement) input
|
||||
* Add [`load`](https://github.com/docker/buildx#--load) input
|
||||
* Add [`outputs`](https://github.com/docker/buildx#-o---outputpath-typetypekeyvalue) input
|
||||
* Add [`cache-from`](https://github.com/docker/buildx#--cache-fromnametypetypekeyvalue) input (`cache_froms` removed)
|
||||
* Add [`cache-to`](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue) input
|
||||
* Add `platforms` input to support multi-platform builds
|
||||
* Add `allow` input
|
||||
* Add `load` input
|
||||
* Add `outputs` input
|
||||
* Add `cache-from` input (`cache_froms` removed)
|
||||
* Add `cache-to` input
|
||||
* Rename `build_args` input to `build-args` for consistency with other Docker build tools
|
||||
* Add `secrets` input
|
||||
* Review `tags` input
|
||||
* Remove `repository` input. See [Simple workflow](#simple-workflow) for migration
|
||||
@ -62,7 +63,6 @@ steps:
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
pull: true
|
||||
push: true
|
||||
build-args: |
|
||||
@ -91,6 +91,7 @@ steps:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tag_with_ref: true
|
||||
tag_with_sha: true
|
||||
add_git_labels: true
|
||||
```
|
||||
|
||||
```yaml
|
||||
@ -134,11 +135,13 @@ steps:
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
labels: |
|
||||
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
|
||||
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.
|
||||
|
@ -1,9 +1,10 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
|
||||
import * as buildx from '../src/buildx';
|
||||
import * as docker from '../src/docker';
|
||||
import * as context from '../src/context';
|
||||
import * as docker from '../src/docker';
|
||||
|
||||
const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
|
||||
const digest = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
|
||||
@ -118,15 +119,36 @@ describe('parseVersion', () => {
|
||||
|
||||
describe('getSecret', () => {
|
||||
test.each([
|
||||
['A_SECRET', 'abcdef0123456789'],
|
||||
['GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789'],
|
||||
['MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==']
|
||||
])('given %p key and %p secret', async (key, secret) => {
|
||||
const secretArgs = await buildx.getSecret(`${key}=${secret}`);
|
||||
console.log(`secretArgs: ${secretArgs}`);
|
||||
expect(secretArgs).toEqual(`id=${key},src=${tmpNameSync}`);
|
||||
const secretContent = await fs.readFileSync(tmpNameSync, 'utf-8');
|
||||
console.log(`secretValue: ${secretContent}`);
|
||||
expect(secretContent).toEqual(secret);
|
||||
['A_SECRET=abcdef0123456789', false, 'A_SECRET', 'abcdef0123456789', false],
|
||||
['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', false, 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', false],
|
||||
['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', false, 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', false],
|
||||
['aaaaaaaa', false, '', '', true],
|
||||
['aaaaaaaa=', false, '', '', true],
|
||||
['=bbbbbbb', false, '', '', true],
|
||||
[
|
||||
`foo=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`,
|
||||
true,
|
||||
'foo',
|
||||
'bar',
|
||||
false
|
||||
],
|
||||
[`notfound=secret`, true, '', '', true]
|
||||
])('given %p key and %p secret', async (kvp, file, exKey, exValue, invalid) => {
|
||||
try {
|
||||
let secret: string;
|
||||
if (file) {
|
||||
secret = await buildx.getSecretFile(kvp);
|
||||
} else {
|
||||
secret = await buildx.getSecretString(kvp);
|
||||
}
|
||||
expect(true).toBe(!invalid);
|
||||
console.log(`secret: ${secret}`);
|
||||
expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`);
|
||||
const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8');
|
||||
console.log(`secretValue: ${secretValue}`);
|
||||
expect(secretValue).toEqual(exValue);
|
||||
} catch (err) {
|
||||
expect(true).toBe(invalid);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,9 +1,118 @@
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
|
||||
import * as context from '../src/context';
|
||||
|
||||
const pgp = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
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
|
||||
PejgXO0uIRolYQ3sz2tMGhx1MfBqH64=
|
||||
=WbwB
|
||||
-----END PGP PRIVATE KEY BLOCK-----`;
|
||||
|
||||
jest.spyOn(context, 'defaultContext').mockImplementation((): string => {
|
||||
return 'https://github.com/docker/build-push-action.git#test-jest';
|
||||
return 'https://github.com/docker/build-push-action.git#refs/heads/test-jest';
|
||||
});
|
||||
|
||||
jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
|
||||
@ -39,7 +148,6 @@ describe('getArgs', () => {
|
||||
'buildx',
|
||||
'build',
|
||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||
'--file', 'Dockerfile',
|
||||
'.'
|
||||
]
|
||||
],
|
||||
@ -54,8 +162,21 @@ describe('getArgs', () => {
|
||||
'--build-arg', 'MY_ARG=val1,val2,val3',
|
||||
'--build-arg', 'ARG=val',
|
||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||
'--file', 'Dockerfile',
|
||||
'https://github.com/docker/build-push-action.git#test-jest'
|
||||
'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
|
||||
]
|
||||
],
|
||||
[
|
||||
'0.4.2',
|
||||
new Map<string, string>([
|
||||
['tags', 'name/app:7.4, name/app:latest'],
|
||||
]),
|
||||
[
|
||||
'buildx',
|
||||
'build',
|
||||
'--tag', 'name/app:7.4',
|
||||
'--tag', 'name/app:latest',
|
||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||
'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
|
||||
]
|
||||
],
|
||||
[
|
||||
@ -71,7 +192,6 @@ describe('getArgs', () => {
|
||||
'--label', 'org.opencontainers.image.title=buildkit',
|
||||
'--label', 'org.opencontainers.image.description=concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit',
|
||||
'--output', 'type=local,dest=./release-out',
|
||||
'--file', 'Dockerfile',
|
||||
'.'
|
||||
]
|
||||
],
|
||||
@ -85,7 +205,6 @@ describe('getArgs', () => {
|
||||
'buildx',
|
||||
'build',
|
||||
'--platform', 'linux/amd64,linux/arm64',
|
||||
'--file', 'Dockerfile',
|
||||
'.'
|
||||
]
|
||||
],
|
||||
@ -98,7 +217,6 @@ describe('getArgs', () => {
|
||||
'buildx',
|
||||
'build',
|
||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||
'--file', 'Dockerfile',
|
||||
'.'
|
||||
]
|
||||
],
|
||||
@ -113,7 +231,6 @@ describe('getArgs', () => {
|
||||
'build',
|
||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||
'--file', 'Dockerfile',
|
||||
'.'
|
||||
]
|
||||
],
|
||||
@ -128,14 +245,13 @@ describe('getArgs', () => {
|
||||
'build',
|
||||
'--output', '.',
|
||||
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||
'--file', 'Dockerfile',
|
||||
'https://github.com/docker/build-push-action.git#test-jest'
|
||||
'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
|
||||
]
|
||||
],
|
||||
[
|
||||
'0.4.2',
|
||||
new Map<string, string>([
|
||||
['context', 'https://github.com/docker/build-push-action.git#heads/master'],
|
||||
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
||||
['tag', 'localhost:5000/name/app:latest'],
|
||||
['platforms', 'linux/amd64,linux/arm64'],
|
||||
['secrets', 'GIT_AUTH_TOKEN=abcdefghijklmno=0123456789'],
|
||||
@ -152,7 +268,114 @@ describe('getArgs', () => {
|
||||
'--file', './test/Dockerfile',
|
||||
'--builder', 'builder-git-context-2',
|
||||
'--push',
|
||||
'https://github.com/docker/build-push-action.git#heads/master'
|
||||
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
||||
]
|
||||
],
|
||||
[
|
||||
'0.4.2',
|
||||
new Map<string, string>([
|
||||
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
||||
['tag', 'localhost:5000/name/app:latest'],
|
||||
['platforms', 'linux/amd64,linux/arm64'],
|
||||
['secrets', `GIT_AUTH_TOKEN=abcdefghi,jklmno=0123456789
|
||||
"MYSECRET=aaaaaaaa
|
||||
bbbbbbb
|
||||
ccccccccc"
|
||||
FOO=bar
|
||||
"EMPTYLINE=aaaa
|
||||
|
||||
bbbb
|
||||
ccc"`],
|
||||
['file', './test/Dockerfile'],
|
||||
['builder', 'builder-git-context-2'],
|
||||
['push', 'true']
|
||||
]),
|
||||
[
|
||||
'buildx',
|
||||
'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',
|
||||
'--secret', 'id=MYSECRET,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',
|
||||
'--file', './test/Dockerfile',
|
||||
'--builder', 'builder-git-context-2',
|
||||
'--push',
|
||||
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
||||
]
|
||||
],
|
||||
[
|
||||
'0.4.2',
|
||||
new Map<string, string>([
|
||||
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
||||
['tag', 'localhost:5000/name/app:latest'],
|
||||
['platforms', 'linux/amd64,linux/arm64'],
|
||||
['secrets', `GIT_AUTH_TOKEN=abcdefghi,jklmno=0123456789
|
||||
MYSECRET=aaaaaaaa
|
||||
bbbbbbb
|
||||
ccccccccc
|
||||
FOO=bar
|
||||
EMPTYLINE=aaaa
|
||||
|
||||
bbbb
|
||||
ccc`],
|
||||
['file', './test/Dockerfile'],
|
||||
['builder', 'builder-git-context-2'],
|
||||
['push', 'true']
|
||||
]),
|
||||
[
|
||||
'buildx',
|
||||
'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',
|
||||
'--secret', 'id=MYSECRET,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',
|
||||
'--file', './test/Dockerfile',
|
||||
'--builder', 'builder-git-context-2',
|
||||
'--push',
|
||||
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
||||
]
|
||||
],
|
||||
[
|
||||
'0.5.1',
|
||||
new Map<string, string>([
|
||||
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
|
||||
['tag', 'localhost:5000/name/app:latest'],
|
||||
['secret-files', `MY_SECRET=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`],
|
||||
['file', './test/Dockerfile'],
|
||||
['builder', 'builder-git-context-2'],
|
||||
['network', 'host'],
|
||||
['push', 'true']
|
||||
]),
|
||||
[
|
||||
'buildx',
|
||||
'build',
|
||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||
'--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
|
||||
'--file', './test/Dockerfile',
|
||||
'--builder', 'builder-git-context-2',
|
||||
'--network', 'host',
|
||||
'--push',
|
||||
'https://github.com/docker/build-push-action.git#refs/heads/master'
|
||||
]
|
||||
],
|
||||
[
|
||||
'0.4.2',
|
||||
new Map<string, string>([
|
||||
['context', '.'],
|
||||
['labels', 'org.opencontainers.image.title=filter_results_top_n\norg.opencontainers.image.description=Reference implementation of operation "filter results (top-n)"'],
|
||||
['outputs', 'type=local,dest=./release-out']
|
||||
]),
|
||||
[
|
||||
'buildx',
|
||||
'build',
|
||||
'--label', 'org.opencontainers.image.title=filter_results_top_n',
|
||||
'--label', 'org.opencontainers.image.description=Reference implementation of operation "filter results (top-n)"',
|
||||
'--output', 'type=local,dest=./release-out',
|
||||
'.'
|
||||
]
|
||||
]
|
||||
])(
|
||||
@ -172,68 +395,167 @@ describe('getArgs', () => {
|
||||
});
|
||||
|
||||
describe('getInputList', () => {
|
||||
it('handles single line correctly', async () => {
|
||||
it('single line correctly', async () => {
|
||||
await setInput('foo', 'bar');
|
||||
const res = await context.getInputList('foo');
|
||||
console.log(res);
|
||||
expect(res).toEqual(['bar']);
|
||||
});
|
||||
|
||||
it('handles multiple lines correctly', async () => {
|
||||
it('multiline correctly', async () => {
|
||||
setInput('foo', 'bar\nbaz');
|
||||
const res = await context.getInputList('foo');
|
||||
console.log(res);
|
||||
expect(res).toEqual(['bar', 'baz']);
|
||||
});
|
||||
|
||||
it('remove empty lines correctly', async () => {
|
||||
it('empty lines correctly', async () => {
|
||||
setInput('foo', 'bar\n\nbaz');
|
||||
const res = await context.getInputList('foo');
|
||||
console.log(res);
|
||||
expect(res).toEqual(['bar', 'baz']);
|
||||
});
|
||||
|
||||
it('handles comma correctly', async () => {
|
||||
it('comma correctly', async () => {
|
||||
setInput('foo', 'bar,baz');
|
||||
const res = await context.getInputList('foo');
|
||||
console.log(res);
|
||||
expect(res).toEqual(['bar', 'baz']);
|
||||
});
|
||||
|
||||
it('remove empty result correctly', async () => {
|
||||
it('empty result correctly', async () => {
|
||||
setInput('foo', 'bar,baz,');
|
||||
const res = await context.getInputList('foo');
|
||||
console.log(res);
|
||||
expect(res).toEqual(['bar', 'baz']);
|
||||
});
|
||||
|
||||
it('handles different new lines correctly', async () => {
|
||||
it('different new lines correctly', async () => {
|
||||
setInput('foo', 'bar\r\nbaz');
|
||||
const res = await context.getInputList('foo');
|
||||
console.log(res);
|
||||
expect(res).toEqual(['bar', 'baz']);
|
||||
});
|
||||
|
||||
it('handles different new lines and comma correctly', async () => {
|
||||
it('different new lines and comma correctly', async () => {
|
||||
setInput('foo', 'bar\r\nbaz,bat');
|
||||
const res = await context.getInputList('foo');
|
||||
console.log(res);
|
||||
expect(res).toEqual(['bar', 'baz', 'bat']);
|
||||
});
|
||||
|
||||
it('handles multiple lines and ignoring comma correctly', async () => {
|
||||
it('multiline and ignoring comma correctly', async () => {
|
||||
setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir');
|
||||
const res = await context.getInputList('cache-from', true);
|
||||
console.log(res);
|
||||
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
||||
});
|
||||
|
||||
it('handles 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');
|
||||
const res = await context.getInputList('cache-from', true);
|
||||
console.log(res);
|
||||
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
||||
});
|
||||
|
||||
it('multiline values', async () => {
|
||||
setInput(
|
||||
'secrets',
|
||||
`GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
|
||||
"MYSECRET=aaaaaaaa
|
||||
bbbbbbb
|
||||
ccccccccc"
|
||||
FOO=bar`
|
||||
);
|
||||
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'
|
||||
]);
|
||||
});
|
||||
|
||||
it('multiline values with empty lines', async () => {
|
||||
setInput(
|
||||
'secrets',
|
||||
`GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
|
||||
"MYSECRET=aaaaaaaa
|
||||
bbbbbbb
|
||||
ccccccccc"
|
||||
FOO=bar
|
||||
"EMPTYLINE=aaaa
|
||||
|
||||
bbbb
|
||||
ccc"`
|
||||
);
|
||||
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',
|
||||
`EMPTYLINE=aaaa
|
||||
|
||||
bbbb
|
||||
ccc`
|
||||
]);
|
||||
});
|
||||
|
||||
it('multiline values without quotes', async () => {
|
||||
setInput(
|
||||
'secrets',
|
||||
`GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
|
||||
MYSECRET=aaaaaaaa
|
||||
bbbbbbb
|
||||
ccccccccc
|
||||
FOO=bar`
|
||||
);
|
||||
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'
|
||||
]);
|
||||
});
|
||||
|
||||
it('large multiline values', async () => {
|
||||
setInput(
|
||||
'secrets',
|
||||
`"GPG_KEY=${pgp}"
|
||||
FOO=bar`
|
||||
);
|
||||
const res = await context.getInputList('secrets', true);
|
||||
console.log(res);
|
||||
expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']);
|
||||
});
|
||||
|
||||
it('multiline values escape quotes', async () => {
|
||||
setInput(
|
||||
'secrets',
|
||||
`GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
|
||||
"MYSECRET=aaaaaaaa
|
||||
bbbb""bbb
|
||||
ccccccccc"
|
||||
FOO=bar`
|
||||
);
|
||||
const res = await context.getInputList('secrets', true);
|
||||
console.log(res);
|
||||
expect(res).toEqual([
|
||||
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
||||
`MYSECRET=aaaaaaaa
|
||||
bbbb\"bbb
|
||||
ccccccccc`,
|
||||
'FOO=bar'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('asyncForEach', () => {
|
||||
@ -249,6 +571,27 @@ describe('asyncForEach', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setOutput', () => {
|
||||
beforeEach(() => {
|
||||
process.stdout.write = jest.fn();
|
||||
});
|
||||
|
||||
it('setOutput produces the correct command', () => {
|
||||
context.setOutput('some output', 'some value');
|
||||
assertWriteCalls([`::set-output name=some output::some value${os.EOL}`]);
|
||||
});
|
||||
|
||||
it('setOutput handles bools', () => {
|
||||
context.setOutput('some output', false);
|
||||
assertWriteCalls([`::set-output name=some output::false${os.EOL}`]);
|
||||
});
|
||||
|
||||
it('setOutput handles numbers', () => {
|
||||
context.setOutput('some output', 1.01);
|
||||
assertWriteCalls([`::set-output name=some output::1.01${os.EOL}`]);
|
||||
});
|
||||
});
|
||||
|
||||
// See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67
|
||||
function getInputName(name: string): string {
|
||||
return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
|
||||
@ -257,3 +600,11 @@ function getInputName(name: string): string {
|
||||
function setInput(name: string, value: string): void {
|
||||
process.env[getInputName(name)] = value;
|
||||
}
|
||||
|
||||
// Assert that process.stdout.write calls called only with the given arguments.
|
||||
function assertWriteCalls(calls: string[]): void {
|
||||
expect(process.stdout.write).toHaveBeenCalledTimes(calls.length);
|
||||
for (let i = 0; i < calls.length; i++) {
|
||||
expect(process.stdout.write).toHaveBeenNthCalledWith(i + 1, calls[i]);
|
||||
}
|
||||
}
|
||||
|
1
__tests__/fixtures/secret.txt
Normal file
1
__tests__/fixtures/secret.txt
Normal file
@ -0,0 +1 @@
|
||||
bar
|
94
action.yml
94
action.yml
@ -7,52 +7,14 @@ branding:
|
||||
color: 'blue'
|
||||
|
||||
inputs:
|
||||
builder:
|
||||
description: "Builder instance"
|
||||
required: false
|
||||
context:
|
||||
description: "Build's context is the set of files located in the specified PATH or URL"
|
||||
required: false
|
||||
file:
|
||||
description: "Path to the Dockerfile"
|
||||
required: false
|
||||
default: './Dockerfile'
|
||||
build-args:
|
||||
description: "List of build-time variables"
|
||||
required: false
|
||||
labels:
|
||||
description: "List of metadata for an image"
|
||||
required: false
|
||||
tags:
|
||||
description: "List of tags"
|
||||
required: false
|
||||
pull:
|
||||
description: "Always attempt to pull a newer version of the image"
|
||||
required: false
|
||||
default: 'false'
|
||||
target:
|
||||
description: "Sets the target stage to build"
|
||||
required: false
|
||||
allow:
|
||||
description: "List of extra privileged entitlement (eg. network.host,security.insecure)"
|
||||
required: false
|
||||
no-cache:
|
||||
description: "Do not use cache when building the image"
|
||||
build-args:
|
||||
description: "List of build-time variables"
|
||||
required: false
|
||||
default: 'false'
|
||||
platforms:
|
||||
description: "List of target platforms for build"
|
||||
required: false
|
||||
load:
|
||||
description: "Load is a shorthand for --output=type=docker"
|
||||
required: false
|
||||
default: 'false'
|
||||
push:
|
||||
description: "Push is a shorthand for --output=type=registry"
|
||||
required: false
|
||||
default: 'false'
|
||||
outputs:
|
||||
description: "List of output destinations (format: type=local,dest=path)"
|
||||
builder:
|
||||
description: "Builder instance"
|
||||
required: false
|
||||
cache-from:
|
||||
description: "List of external cache sources for buildx (eg. user/app:cache, type=local,src=path/to/dir)"
|
||||
@ -60,8 +22,54 @@ inputs:
|
||||
cache-to:
|
||||
description: "List of cache export destinations for buildx (eg. user/app:cache, type=local,dest=path/to/dir)"
|
||||
required: false
|
||||
context:
|
||||
description: "Build's context is the set of files located in the specified PATH or URL"
|
||||
required: false
|
||||
file:
|
||||
description: "Path to the Dockerfile"
|
||||
required: false
|
||||
labels:
|
||||
description: "List of metadata for an image"
|
||||
required: false
|
||||
load:
|
||||
description: "Load is a shorthand for --output=type=docker"
|
||||
required: false
|
||||
default: 'false'
|
||||
network:
|
||||
description: "Set the networking mode for the RUN instructions during build"
|
||||
required: false
|
||||
no-cache:
|
||||
description: "Do not use cache when building the image"
|
||||
required: false
|
||||
default: 'false'
|
||||
outputs:
|
||||
description: "List of output destinations (format: type=local,dest=path)"
|
||||
required: false
|
||||
platforms:
|
||||
description: "List of target platforms for build"
|
||||
required: false
|
||||
pull:
|
||||
description: "Always attempt to pull a newer version of the image"
|
||||
required: false
|
||||
default: 'false'
|
||||
push:
|
||||
description: "Push is a shorthand for --output=type=registry"
|
||||
required: false
|
||||
default: 'false'
|
||||
secrets:
|
||||
description: "List of secrets to expose to the build (eg. key=value, GIT_AUTH_TOKEN=mytoken)"
|
||||
description: "List of secrets to expose to the build (eg. key=string, GIT_AUTH_TOKEN=mytoken)"
|
||||
required: false
|
||||
secret-files:
|
||||
description: "List of secret files to expose to the build (eg. key=filename, MY_SECRET=./secret.txt)"
|
||||
required: false
|
||||
ssh:
|
||||
description: "List of SSH agent socket or keys to expose to the build"
|
||||
required: false
|
||||
tags:
|
||||
description: "List of tags"
|
||||
required: false
|
||||
target:
|
||||
description: "Sets the target stage to build"
|
||||
required: false
|
||||
github-token:
|
||||
description: "GitHub Token used to authenticate against a repository for Git context"
|
||||
|
2668
dist/index.js
generated
vendored
2668
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
@ -1,42 +1,67 @@
|
||||
variable "NODE_VERSION" {
|
||||
default = "12"
|
||||
}
|
||||
|
||||
target "node-version" {
|
||||
args = {
|
||||
NODE_VERSION = NODE_VERSION
|
||||
}
|
||||
}
|
||||
|
||||
group "default" {
|
||||
targets = ["build"]
|
||||
}
|
||||
|
||||
group "pre-checkin" {
|
||||
targets = ["update-yarn", "format", "build"]
|
||||
targets = ["vendor-update", "format", "build"]
|
||||
}
|
||||
|
||||
group "validate" {
|
||||
targets = ["validate-format", "validate-build", "validate-yarn"]
|
||||
}
|
||||
|
||||
target "update-yarn" {
|
||||
target = "update-yarn"
|
||||
output = ["."]
|
||||
targets = ["format-validate", "build-validate", "vendor-validate"]
|
||||
}
|
||||
|
||||
target "build" {
|
||||
target = "dist"
|
||||
inherits = ["node-version"]
|
||||
dockerfile = "./hack/build.Dockerfile"
|
||||
target = "build-update"
|
||||
output = ["."]
|
||||
}
|
||||
|
||||
target "test" {
|
||||
target = "test"
|
||||
target "build-validate" {
|
||||
inherits = ["node-version"]
|
||||
dockerfile = "./hack/build.Dockerfile"
|
||||
target = "build-validate"
|
||||
}
|
||||
|
||||
target "format" {
|
||||
target = "format"
|
||||
inherits = ["node-version"]
|
||||
dockerfile = "./hack/build.Dockerfile"
|
||||
target = "format-update"
|
||||
output = ["."]
|
||||
}
|
||||
|
||||
target "validate-format" {
|
||||
target = "validate-format"
|
||||
target "format-validate" {
|
||||
inherits = ["node-version"]
|
||||
dockerfile = "./hack/build.Dockerfile"
|
||||
target = "format-validate"
|
||||
}
|
||||
|
||||
target "validate-build" {
|
||||
target = "validate-build"
|
||||
target "vendor-update" {
|
||||
inherits = ["node-version"]
|
||||
dockerfile = "./hack/vendor.Dockerfile"
|
||||
target = "update"
|
||||
output = ["."]
|
||||
}
|
||||
|
||||
target "validate-yarn" {
|
||||
target = "validate-yarn"
|
||||
target "vendor-validate" {
|
||||
inherits = ["node-version"]
|
||||
dockerfile = "./hack/vendor.Dockerfile"
|
||||
target = "validate"
|
||||
}
|
||||
|
||||
target "test" {
|
||||
inherits = ["node-version"]
|
||||
dockerfile = "./hack/test.Dockerfile"
|
||||
target = "test-coverage"
|
||||
output = ["./coverage"]
|
||||
}
|
||||
|
107
docs/advanced/cache.md
Normal file
107
docs/advanced/cache.md
Normal file
@ -0,0 +1,107 @@
|
||||
# Cache
|
||||
|
||||
* [Registry cache](#registry-cache)
|
||||
* [GitHub cache](#github-cache)
|
||||
|
||||
> More info about buildx cache: https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from
|
||||
|
||||
## Registry cache
|
||||
|
||||
You can import/export cache from a cache manifest or (special) image configuration on the registry.
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
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:latest
|
||||
cache-to: type=inline
|
||||
```
|
||||
|
||||
## GitHub 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).
|
||||
|
||||
> :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
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
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: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
-
|
||||
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=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new
|
||||
-
|
||||
# Temp fix
|
||||
# https://github.com/docker/build-push-action/issues/252
|
||||
# https://github.com/moby/buildkit/issues/1896
|
||||
name: Move cache
|
||||
run: |
|
||||
rm -rf /tmp/.buildx-cache
|
||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
```
|
73
docs/advanced/copy-between-registries.md
Normal file
73
docs/advanced/copy-between-registries.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Copy images between registries
|
||||
|
||||
Multi-platform images built using buildx can be copied from one registry to another without
|
||||
changing the image SHA using the [tag-push-action](https://github.com/akhilerm/tag-push-action).
|
||||
|
||||
The following workflow will first push the image to dockerhub, run some tests using the images
|
||||
and then push to quay and ghcr
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
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
|
||||
- # quay and ghcr logins for pushing image after testing
|
||||
name: Login to Quay Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_USERNAME }}
|
||||
password: ${{ secrets.QUAY_TOKEN }}
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
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: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
user/app:latest
|
||||
user/app:1.0.0
|
||||
- # run tests using image from docker hub
|
||||
name: Run Tests
|
||||
run: make tests
|
||||
- # copy multiplatform image from dockerhub to quay and ghcr
|
||||
name: Push Image to multiple registries
|
||||
uses: akhilerm/tag-push-action@v1.0.0
|
||||
with:
|
||||
src: docker.io/user/app:1.0.0
|
||||
dst: |
|
||||
quay.io/user/app:latest
|
||||
quay.io/user/app:1.0.0
|
||||
ghcr.io/user/app:latest
|
||||
ghcr.io/user/app:1.0.0
|
||||
```
|
48
docs/advanced/dockerhub-desc.md
Normal file
48
docs/advanced/dockerhub-desc.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Update DockerHub repo description
|
||||
|
||||
You can update the [DockerHub repository description](https://docs.docker.com/docker-hub/repos/) using
|
||||
a third party action called [DockerHub Description](https://github.com/peter-evans/dockerhub-description)
|
||||
with this action:
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
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 push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
-
|
||||
name: Update repo description
|
||||
uses: peter-evans/dockerhub-description@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
repository: user/app
|
||||
```
|
35
docs/advanced/export-docker.md
Normal file
35
docs/advanced/export-docker.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Export image to Docker
|
||||
|
||||
You may want your build result to be available in the Docker client through `docker images` to be able to use it
|
||||
in another step of your workflow:
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
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: Build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
load: true
|
||||
tags: myimage:latest
|
||||
-
|
||||
name: Inspect
|
||||
run: |
|
||||
docker image inspect myimage:latest
|
||||
```
|
44
docs/advanced/isolated-builders.md
Normal file
44
docs/advanced/isolated-builders.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Isolated builders
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
uses: docker/setup-buildx-action@v1
|
||||
id: builder1
|
||||
-
|
||||
uses: docker/setup-buildx-action@v1
|
||||
id: builder2
|
||||
-
|
||||
name: Builder 1 name
|
||||
run: echo ${{ steps.builder1.outputs.name }}
|
||||
-
|
||||
name: Builder 2 name
|
||||
run: echo ${{ steps.builder2.outputs.name }}
|
||||
-
|
||||
name: Build against builder1
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
builder: ${{ steps.builder1.outputs.name }}
|
||||
context: .
|
||||
target: mytarget1
|
||||
-
|
||||
name: Build against builder2
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
builder: ${{ steps.builder2.outputs.name }}
|
||||
context: .
|
||||
target: mytarget2
|
||||
```
|
44
docs/advanced/local-registry.md
Normal file
44
docs/advanced/local-registry.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Local registry
|
||||
|
||||
For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry) to push images into:
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-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:
|
||||
driver-opts: network=host
|
||||
-
|
||||
name: Build and push to local registry
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: localhost:5000/name/app:latest
|
||||
-
|
||||
name: Inspect
|
||||
run: |
|
||||
docker buildx imagetools inspect localhost:5000/name/app:latest
|
||||
```
|
44
docs/advanced/multi-platform.md
Normal file
44
docs/advanced/multi-platform.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Multi-platform image
|
||||
|
||||
You can build multi-platform images using the [`platforms` input](../../README.md#inputs) as described below.
|
||||
|
||||
> :bulb: List of available platforms will be displayed and available through our [setup-buildx](https://github.com/docker/setup-buildx-action#about) action.
|
||||
|
||||
> :bulb: If you want support for more platforms, you can use QEMU with our [setup-qemu](https://github.com/docker/setup-qemu-action) action.
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
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 push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
```
|
57
docs/advanced/push-multi-registries.md
Normal file
57
docs/advanced/push-multi-registries.md
Normal file
@ -0,0 +1,57 @@
|
||||
# Push to multi-registries
|
||||
|
||||
* [Docker Hub and GHCR](#docker-hub-and-ghcr)
|
||||
|
||||
## Docker Hub and GHCR
|
||||
|
||||
The following workflow will connect you to [DockerHub](https://github.com/docker/login-action#dockerhub)
|
||||
and [GitHub Container Registry](https://github.com/docker/login-action#github-container-registry) and push the
|
||||
image to these registries.
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
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: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
user/app:latest
|
||||
user/app:1.0.0
|
||||
ghcr.io/user/app:latest
|
||||
ghcr.io/user/app:1.0.0
|
||||
```
|
84
docs/advanced/secrets.md
Normal file
84
docs/advanced/secrets.md
Normal file
@ -0,0 +1,84 @@
|
||||
# Secrets
|
||||
|
||||
In the following example we will expose and use the [GITHUB_TOKEN secret](https://docs.github.com/en/actions/reference/authentication-in-a-workflow#about-the-github_token-secret)
|
||||
as provided by GitHub in your workflow.
|
||||
|
||||
First let's create our `Dockerfile` to use our secret:
|
||||
|
||||
```Dockerfile
|
||||
#syntax=docker/dockerfile:1.2
|
||||
|
||||
FROM alpine
|
||||
RUN --mount=type=secret,id=github_token \
|
||||
cat /run/secrets/github_token
|
||||
```
|
||||
|
||||
As you can see we have named our secret `github_token`. Here is the workflow you can use to expose this secret using
|
||||
the [`secrets` input](../../README.md#inputs):
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
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: Build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: user/app:latest
|
||||
secrets: |
|
||||
"github_token=${{ secrets.GITHUB_TOKEN }}"
|
||||
```
|
||||
|
||||
> :bulb: You can also expose a secret file to the build with [`secret-files`](../../README.md#inputs) input:
|
||||
> ```yaml
|
||||
> secret-files: |
|
||||
> "MY_SECRET=./secret.txt"
|
||||
> ```
|
||||
|
||||
If you're using [GitHub secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) and need to handle
|
||||
multi-line value, you will need to place the key-value pair between quotes:
|
||||
|
||||
```yaml
|
||||
secrets: |
|
||||
"MYSECRET=${{ secrets.GPG_KEY }}"
|
||||
GIT_AUTH_TOKEN=abcdefghi,jklmno=0123456789
|
||||
"MYSECRET=aaaaaaaa
|
||||
bbbbbbb
|
||||
ccccccccc"
|
||||
FOO=bar
|
||||
"EMPTYLINE=aaaa
|
||||
|
||||
bbbb
|
||||
ccc"
|
||||
"JSON_SECRET={""key1"":""value1"",""key2"":""value2""}"
|
||||
```
|
||||
|
||||
| Key | Value |
|
||||
|--------------------|--------------------------------------------------|
|
||||
| `MYSECRET` | `***********************` |
|
||||
| `GIT_AUTH_TOKEN` | `abcdefghi,jklmno=0123456789` |
|
||||
| `MYSECRET` | `aaaaaaaa\nbbbbbbb\nccccccccc` |
|
||||
| `FOO` | `bar` |
|
||||
| `EMPTYLINE` | `aaaa\n\nbbbb\nccc` |
|
||||
| `JSON_SECRET` | `{"key1":"value1","key2":"value2"}` |
|
||||
|
||||
> :bulb: All quote signs need to be doubled for escaping.
|
58
docs/advanced/share-image-jobs.md
Normal file
58
docs/advanced/share-image-jobs.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Share built image between jobs
|
||||
|
||||
As each job is isolated in its own runner you cannot use your built image between jobs (except for [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners)).
|
||||
However, you can [pass data between jobs in a workflow](https://docs.github.com/en/actions/guides/storing-workflow-data-as-artifacts#passing-data-between-jobs-in-a-workflow)
|
||||
using the [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/download-artifact](https://github.com/actions/download-artifact)
|
||||
actions:
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Build and export
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
tags: myimage:latest
|
||||
outputs: type=docker,dest=/tmp/myimage.tar
|
||||
-
|
||||
name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: myimage
|
||||
path: /tmp/myimage.tar
|
||||
|
||||
use:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Download artifact
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: myimage
|
||||
path: /tmp
|
||||
-
|
||||
name: Load image
|
||||
run: |
|
||||
docker load --input /tmp/myimage.tar
|
||||
docker image ls -a
|
||||
```
|
77
docs/advanced/tags-labels.md
Normal file
77
docs/advanced/tags-labels.md
Normal file
@ -0,0 +1,77 @@
|
||||
# Handle tags and labels
|
||||
|
||||
If you come from [`v1`](https://github.com/docker/build-push-action/tree/releases/v1#readme) and want an
|
||||
"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)
|
||||
to handle tags and labels based on GitHub actions events and Git metadata.
|
||||
|
||||
```yaml
|
||||
name: ci
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # everyday at 10am
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: |
|
||||
name/app
|
||||
ghcr.io/username/app
|
||||
# generate Docker tags based on the following events/attributes
|
||||
tags: |
|
||||
type=schedule
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
-
|
||||
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
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
```
|
42
hack/build.Dockerfile
Normal file
42
hack/build.Dockerfile
Normal file
@ -0,0 +1,42 @@
|
||||
# syntax=docker/dockerfile:1.2
|
||||
ARG NODE_VERSION
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine AS base
|
||||
RUN apk add --no-cache cpio findutils 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 build
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
--mount=type=cache,target=/src/node_modules \
|
||||
yarn run build && mkdir /out && cp -Rf dist /out/
|
||||
|
||||
FROM scratch AS build-update
|
||||
COPY --from=build /out /
|
||||
|
||||
FROM build AS build-validate
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
git add -A && cp -rf /out/* .; \
|
||||
if [ -n "$(git status --porcelain -- dist)" ]; then \
|
||||
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'; \
|
||||
git status --porcelain -- dist; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
FROM deps AS format
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
--mount=type=cache,target=/src/node_modules \
|
||||
yarn run format \
|
||||
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out
|
||||
|
||||
FROM scratch AS format-update
|
||||
COPY --from=format /out /
|
||||
|
||||
FROM deps AS format-validate
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
--mount=type=cache,target=/src/node_modules \
|
||||
yarn run format-check \
|
23
hack/test.Dockerfile
Normal file
23
hack/test.Dockerfile
Normal file
@ -0,0 +1,23 @@
|
||||
# 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 /
|
23
hack/vendor.Dockerfile
Normal file
23
hack/vendor.Dockerfile
Normal file
@ -0,0 +1,23 @@
|
||||
# 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,11 +28,11 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/core": "^1.3.0",
|
||||
"@actions/exec": "^1.0.4",
|
||||
"@actions/github": "^4.0.0",
|
||||
"csv-parse": "^4.12.0",
|
||||
"semver": "^7.3.2",
|
||||
"@actions/github": "^5.0.0",
|
||||
"csv-parse": "^4.15.4",
|
||||
"semver": "^7.3.5",
|
||||
"tmp": "^0.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import csvparse from 'csv-parse/lib/sync';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import csvparse from 'csv-parse/lib/sync';
|
||||
import * as semver from 'semver';
|
||||
|
||||
import * as context from './context';
|
||||
import * as exec from './exec';
|
||||
|
||||
@ -17,14 +18,34 @@ export async function getImageID(): Promise<string | undefined> {
|
||||
return fs.readFileSync(iidFile, {encoding: 'utf-8'});
|
||||
}
|
||||
|
||||
export async function getSecret(kvp: string): Promise<string> {
|
||||
export async function getSecretString(kvp: string): Promise<string> {
|
||||
return getSecret(kvp, false);
|
||||
}
|
||||
|
||||
export async function getSecretFile(kvp: string): Promise<string> {
|
||||
return getSecret(kvp, true);
|
||||
}
|
||||
|
||||
export async function getSecret(kvp: string, file: boolean): Promise<string> {
|
||||
const delimiterIndex = kvp.indexOf('=');
|
||||
const key = kvp.substring(0, delimiterIndex);
|
||||
const value = kvp.substring(delimiterIndex + 1);
|
||||
let value = kvp.substring(delimiterIndex + 1);
|
||||
if (key.length == 0 || value.length == 0) {
|
||||
throw new Error(`${kvp} is not a valid secret`);
|
||||
}
|
||||
|
||||
if (file) {
|
||||
if (!fs.existsSync(value)) {
|
||||
throw new Error(`secret file ${value} not found`);
|
||||
}
|
||||
value = fs.readFileSync(value, {encoding: 'utf-8'});
|
||||
}
|
||||
|
||||
const secretFile = context.tmpNameSync({
|
||||
tmpdir: context.tmpDir()
|
||||
});
|
||||
await fs.writeFileSync(secretFile, value);
|
||||
fs.writeFileSync(secretFile, value);
|
||||
|
||||
return `id=${key},src=${secretFile}`;
|
||||
}
|
||||
|
||||
@ -33,7 +54,7 @@ export function isLocalOrTarExporter(outputs: string[]): Boolean {
|
||||
delimiter: ',',
|
||||
trim: true,
|
||||
columns: false,
|
||||
relax_column_count: true
|
||||
relaxColumnCount: true
|
||||
})) {
|
||||
// Local if no type is defined
|
||||
// https://github.com/docker/buildx/blob/d2bf42f8b4784d83fde17acb3ed84703ddc2156b/build/output.go#L29-L43
|
||||
@ -79,7 +100,7 @@ export async function getVersion(): Promise<string> {
|
||||
export async function parseVersion(stdout: string): Promise<string> {
|
||||
const matches = /\sv?([0-9.]+)/.exec(stdout);
|
||||
if (!matches) {
|
||||
throw new Error(`Cannot parse Buildx version`);
|
||||
throw new Error(`Cannot parse buildx version`);
|
||||
}
|
||||
return semver.clean(matches[1]);
|
||||
}
|
||||
|
126
src/context.ts
126
src/context.ts
@ -1,40 +1,54 @@
|
||||
import csvparse from 'csv-parse/lib/sync';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
import * as tmp from 'tmp';
|
||||
import * as buildx from './buildx';
|
||||
|
||||
import * as core from '@actions/core';
|
||||
import {issueCommand} from '@actions/core/lib/command';
|
||||
import * as github from '@actions/github';
|
||||
|
||||
import * as buildx from './buildx';
|
||||
|
||||
let _defaultContext, _tmpDir: string;
|
||||
|
||||
export interface Inputs {
|
||||
context: string;
|
||||
file: string;
|
||||
buildArgs: string[];
|
||||
labels: string[];
|
||||
tags: string[];
|
||||
pull: boolean;
|
||||
target: string;
|
||||
allow: string[];
|
||||
noCache: boolean;
|
||||
buildArgs: string[];
|
||||
builder: string;
|
||||
platforms: string[];
|
||||
load: boolean;
|
||||
push: boolean;
|
||||
outputs: string[];
|
||||
cacheFrom: string[];
|
||||
cacheTo: string[];
|
||||
context: string;
|
||||
file: string;
|
||||
labels: string[];
|
||||
load: boolean;
|
||||
network: string;
|
||||
noCache: boolean;
|
||||
outputs: string[];
|
||||
platforms: string[];
|
||||
pull: boolean;
|
||||
push: boolean;
|
||||
secrets: string[];
|
||||
secretFiles: string[];
|
||||
ssh: string[];
|
||||
tags: string[];
|
||||
target: string;
|
||||
githubToken: string;
|
||||
}
|
||||
|
||||
export function defaultContext(): string {
|
||||
if (!_defaultContext) {
|
||||
_defaultContext = `https://github.com/${github.context.repo.owner}/${
|
||||
let ref = github.context.ref;
|
||||
if (github.context.sha && ref && !ref.startsWith('refs/')) {
|
||||
ref = `refs/heads/${github.context.ref}`;
|
||||
}
|
||||
if (github.context.sha && !ref.startsWith(`refs/pull/`)) {
|
||||
ref = github.context.sha;
|
||||
}
|
||||
_defaultContext = `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${
|
||||
github.context.repo.repo
|
||||
}.git#${github.context?.ref?.replace(/^refs\//, '')}`;
|
||||
}.git#${ref}`;
|
||||
}
|
||||
return _defaultContext;
|
||||
}
|
||||
@ -52,23 +66,26 @@ export function tmpNameSync(options?: tmp.TmpNameOptions): string {
|
||||
|
||||
export async function getInputs(defaultContext: string): Promise<Inputs> {
|
||||
return {
|
||||
context: core.getInput('context') || defaultContext,
|
||||
file: core.getInput('file') || 'Dockerfile',
|
||||
buildArgs: await getInputList('build-args', true),
|
||||
labels: await getInputList('labels', true),
|
||||
tags: await getInputList('tags'),
|
||||
pull: /true/i.test(core.getInput('pull')),
|
||||
target: core.getInput('target'),
|
||||
allow: await getInputList('allow'),
|
||||
noCache: /true/i.test(core.getInput('no-cache')),
|
||||
buildArgs: await getInputList('build-args', true),
|
||||
builder: core.getInput('builder'),
|
||||
platforms: await getInputList('platforms'),
|
||||
load: /true/i.test(core.getInput('load')),
|
||||
push: /true/i.test(core.getInput('push')),
|
||||
outputs: await getInputList('outputs', true),
|
||||
cacheFrom: await getInputList('cache-from', true),
|
||||
cacheTo: await getInputList('cache-to', true),
|
||||
context: core.getInput('context') || defaultContext,
|
||||
file: core.getInput('file'),
|
||||
labels: await getInputList('labels', true),
|
||||
load: /true/i.test(core.getInput('load')),
|
||||
network: core.getInput('network'),
|
||||
noCache: /true/i.test(core.getInput('no-cache')),
|
||||
outputs: await getInputList('outputs', true),
|
||||
platforms: await getInputList('platforms'),
|
||||
pull: /true/i.test(core.getInput('pull')),
|
||||
push: /true/i.test(core.getInput('push')),
|
||||
secrets: await getInputList('secrets', true),
|
||||
secretFiles: await getInputList('secret-files', true),
|
||||
ssh: await getInputList('ssh'),
|
||||
tags: await getInputList('tags'),
|
||||
target: core.getInput('target'),
|
||||
githubToken: core.getInput('github-token')
|
||||
};
|
||||
}
|
||||
@ -117,11 +134,25 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
|
||||
args.push('--cache-to', cacheTo);
|
||||
});
|
||||
await asyncForEach(inputs.secrets, async secret => {
|
||||
args.push('--secret', await buildx.getSecret(secret));
|
||||
try {
|
||||
args.push('--secret', await buildx.getSecretString(secret));
|
||||
} catch (err) {
|
||||
core.warning(err.message);
|
||||
}
|
||||
});
|
||||
await asyncForEach(inputs.secretFiles, async secretFile => {
|
||||
try {
|
||||
args.push('--secret', await buildx.getSecretFile(secretFile));
|
||||
} catch (err) {
|
||||
core.warning(err.message);
|
||||
}
|
||||
});
|
||||
if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) {
|
||||
args.push('--secret', await buildx.getSecret(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
|
||||
args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
|
||||
}
|
||||
await asyncForEach(inputs.ssh, async ssh => {
|
||||
args.push('--ssh', ssh);
|
||||
});
|
||||
if (inputs.file) {
|
||||
args.push('--file', inputs.file);
|
||||
}
|
||||
@ -142,6 +173,9 @@ async function getCommonArgs(inputs: Inputs): Promise<Array<string>> {
|
||||
if (inputs.load) {
|
||||
args.push('--load');
|
||||
}
|
||||
if (inputs.network) {
|
||||
args.push('--network', inputs.network);
|
||||
}
|
||||
if (inputs.push) {
|
||||
args.push('--push');
|
||||
}
|
||||
@ -149,17 +183,30 @@ async function getCommonArgs(inputs: Inputs): Promise<Array<string>> {
|
||||
}
|
||||
|
||||
export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> {
|
||||
let res: Array<string> = [];
|
||||
|
||||
const items = core.getInput(name);
|
||||
if (items == '') {
|
||||
return [];
|
||||
return res;
|
||||
}
|
||||
return items
|
||||
.split(/\r?\n/)
|
||||
.filter(x => x)
|
||||
.reduce<string[]>(
|
||||
(acc, line) => acc.concat(!ignoreComma ? line.split(',').filter(x => x) : line).map(pat => pat.trim()),
|
||||
[]
|
||||
);
|
||||
|
||||
for (let output of (await csvparse(items, {
|
||||
columns: false,
|
||||
relax: true,
|
||||
relaxColumnCount: true,
|
||||
skipLinesWithEmptyValues: true
|
||||
})) as Array<string[]>) {
|
||||
if (output.length == 1) {
|
||||
res.push(output[0]);
|
||||
continue;
|
||||
} else if (!ignoreComma) {
|
||||
res.push(...output);
|
||||
continue;
|
||||
}
|
||||
res.push(output.join(','));
|
||||
}
|
||||
|
||||
return res.filter(item => item).map(pat => pat.trim());
|
||||
}
|
||||
|
||||
export const asyncForEach = async (array, callback) => {
|
||||
@ -167,3 +214,8 @@ export const asyncForEach = async (array, callback) => {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME: Temp fix https://github.com/actions/toolkit/issues/777
|
||||
export function setOutput(name: string, value: any): void {
|
||||
issueCommand('set-output', {name}, value);
|
||||
}
|
||||
|
22
src/main.ts
22
src/main.ts
@ -1,5 +1,4 @@
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as buildx from './buildx';
|
||||
import * as context from './context';
|
||||
import * as exec from './exec';
|
||||
@ -8,22 +7,21 @@ import * as core from '@actions/core';
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
if (os.platform() !== 'linux') {
|
||||
throw new Error(`Only supported on linux platform`);
|
||||
}
|
||||
core.startGroup(`Docker info`);
|
||||
await exec.exec('docker', ['version']);
|
||||
await exec.exec('docker', ['info']);
|
||||
core.endGroup();
|
||||
|
||||
if (!(await buildx.isAvailable())) {
|
||||
throw new Error(`Buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`);
|
||||
core.setFailed(`Docker buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`);
|
||||
return;
|
||||
}
|
||||
stateHelper.setTmpDir(context.tmpDir());
|
||||
|
||||
const buildxVersion = await buildx.getVersion();
|
||||
core.info(`📣 Buildx version: ${buildxVersion}`);
|
||||
|
||||
const defContext = context.defaultContext();
|
||||
let inputs: context.Inputs = await context.getInputs(defContext);
|
||||
|
||||
core.info(`🏃 Starting build...`);
|
||||
const args: string[] = await context.getArgs(inputs, defContext, buildxVersion);
|
||||
await exec.exec('docker', args).then(res => {
|
||||
if (res.stderr != '' && !res.success) {
|
||||
@ -33,9 +31,10 @@ async function run(): Promise<void> {
|
||||
|
||||
const imageID = await buildx.getImageID();
|
||||
if (imageID) {
|
||||
core.info('🛒 Extracting digest...');
|
||||
core.startGroup(`Extracting digest`);
|
||||
core.info(`${imageID}`);
|
||||
core.setOutput('digest', imageID);
|
||||
context.setOutput('digest', imageID);
|
||||
core.endGroup();
|
||||
}
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
@ -44,8 +43,9 @@ async function run(): Promise<void> {
|
||||
|
||||
async function cleanup(): Promise<void> {
|
||||
if (stateHelper.tmpDir.length > 0) {
|
||||
core.info(`🚿 Removing temp folder ${stateHelper.tmpDir}`);
|
||||
core.startGroup(`Removing temp folder ${stateHelper.tmpDir}`);
|
||||
fs.rmdirSync(stateHelper.tmpDir, {recursive: true});
|
||||
core.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
193
yarn.lock
193
yarn.lock
@ -2,10 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@actions/core@^1.2.6":
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.2.6.tgz#a78d49f41a4def18e88ce47c2cac615d5694bf09"
|
||||
integrity sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==
|
||||
"@actions/core@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.3.0.tgz#f5e4b24c889e7f2e58b466cc8c7481292284eba0"
|
||||
integrity sha512-xxtX0Cwdhb8LcgatfJkokqT8KzPvcIbwL9xpLU09nOwBzaStbfm0dNncsP0M4us+EpoPdWy7vbzU5vSOH7K6pg==
|
||||
|
||||
"@actions/exec@^1.0.4":
|
||||
version "1.0.4"
|
||||
@ -14,20 +14,20 @@
|
||||
dependencies:
|
||||
"@actions/io" "^1.0.1"
|
||||
|
||||
"@actions/github@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@actions/github/-/github-4.0.0.tgz#d520483151a2bf5d2dc9cd0f20f9ac3a2e458816"
|
||||
integrity sha512-Ej/Y2E+VV6sR9X7pWL5F3VgEWrABaT292DRqRU6R4hnQjPtC/zD3nagxVdXWiRQvYDh8kHXo7IDmG42eJ/dOMA==
|
||||
"@actions/github@^5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@actions/github/-/github-5.0.0.tgz#1754127976c50bd88b2e905f10d204d76d1472f8"
|
||||
integrity sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==
|
||||
dependencies:
|
||||
"@actions/http-client" "^1.0.8"
|
||||
"@octokit/core" "^3.0.0"
|
||||
"@octokit/plugin-paginate-rest" "^2.2.3"
|
||||
"@octokit/plugin-rest-endpoint-methods" "^4.0.0"
|
||||
"@actions/http-client" "^1.0.11"
|
||||
"@octokit/core" "^3.4.0"
|
||||
"@octokit/plugin-paginate-rest" "^2.13.3"
|
||||
"@octokit/plugin-rest-endpoint-methods" "^5.1.1"
|
||||
|
||||
"@actions/http-client@^1.0.8":
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-1.0.8.tgz#8bd76e8eca89dc8bcf619aa128eba85f7a39af45"
|
||||
integrity sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==
|
||||
"@actions/http-client@^1.0.11":
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-1.0.11.tgz#c58b12e9aa8b159ee39e7dd6cbd0e91d905633c0"
|
||||
integrity sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==
|
||||
dependencies:
|
||||
tunnel "0.0.6"
|
||||
|
||||
@ -502,23 +502,24 @@
|
||||
"@types/yargs" "^15.0.0"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@octokit/auth-token@^2.4.0":
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.2.tgz#10d0ae979b100fa6b72fa0e8e63e27e6d0dbff8a"
|
||||
integrity sha512-jE/lE/IKIz2v1+/P0u4fJqv0kYwXOTujKemJMFr6FeopsxlIK3+wKDCJGnysg81XID5TgZQbIfuJ5J0lnTiuyQ==
|
||||
"@octokit/auth-token@^2.4.4":
|
||||
version "2.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.5.tgz#568ccfb8cb46f36441fac094ce34f7a875b197f3"
|
||||
integrity sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==
|
||||
dependencies:
|
||||
"@octokit/types" "^5.0.0"
|
||||
"@octokit/types" "^6.0.3"
|
||||
|
||||
"@octokit/core@^3.0.0":
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.1.2.tgz#c937d5f9621b764573068fcd2e5defcc872fd9cc"
|
||||
integrity sha512-AInOFULmwOa7+NFi9F8DlDkm5qtZVmDQayi7TUgChE3yeIGPq0Y+6cAEXPexQ3Ea+uZy66hKEazR7DJyU+4wfw==
|
||||
"@octokit/core@^3.4.0":
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.4.0.tgz#b48aa27d755b339fe7550548b340dcc2b513b742"
|
||||
integrity sha512-6/vlKPP8NF17cgYXqucdshWqmMZGXkuvtcrWCgU5NOI0Pl2GjlmZyWgBMrU8zJ3v2MJlM6++CiB45VKYmhiWWg==
|
||||
dependencies:
|
||||
"@octokit/auth-token" "^2.4.0"
|
||||
"@octokit/graphql" "^4.3.1"
|
||||
"@octokit/request" "^5.4.0"
|
||||
"@octokit/types" "^5.0.0"
|
||||
before-after-hook "^2.1.0"
|
||||
"@octokit/auth-token" "^2.4.4"
|
||||
"@octokit/graphql" "^4.5.8"
|
||||
"@octokit/request" "^5.4.12"
|
||||
"@octokit/request-error" "^2.0.5"
|
||||
"@octokit/types" "^6.0.3"
|
||||
before-after-hook "^2.2.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/endpoint@^6.0.1":
|
||||
@ -530,28 +531,33 @@
|
||||
is-plain-object "^4.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/graphql@^4.3.1":
|
||||
version "4.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.5.4.tgz#c9ef75b0406ebf195bf5f4ed2304a77ed7df27c7"
|
||||
integrity sha512-ITpZ+dQc0cXAW1FmDkHJJM+8Lb6anUnin0VB5hLBilnYVdLC0ICFU/KIvT7OXfW9S81DE3U4Vx2EypDG1OYaPA==
|
||||
"@octokit/graphql@^4.5.8":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.6.1.tgz#f975486a46c94b7dbe58a0ca751935edc7e32cc9"
|
||||
integrity sha512-2lYlvf4YTDgZCTXTW4+OX+9WTLFtEUc6hGm4qM1nlZjzxj+arizM4aHWzBVBCxY9glh7GIs0WEuiSgbVzv8cmA==
|
||||
dependencies:
|
||||
"@octokit/request" "^5.3.0"
|
||||
"@octokit/types" "^5.0.0"
|
||||
"@octokit/types" "^6.0.3"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/plugin-paginate-rest@^2.2.3":
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.3.1.tgz#00f91701dfda26227c3e748d42bc89e2d0d9ce55"
|
||||
integrity sha512-81A+ONLpcSX7vWxnEmVZteQPNsbdeScSVUqjgMYPSk1trzG69iYkhS42wPRWtN0nYw6OEmT48DNeQCjHeyroYw==
|
||||
dependencies:
|
||||
"@octokit/types" "^5.3.0"
|
||||
"@octokit/openapi-types@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-7.0.0.tgz#0f6992db9854af15eca77d71ab0ec7fad2f20411"
|
||||
integrity sha512-gV/8DJhAL/04zjTI95a7FhQwS6jlEE0W/7xeYAzuArD0KVAVWDLP2f3vi98hs3HLTczxXdRK/mF0tRoQPpolEw==
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@^4.0.0":
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.1.3.tgz#44d9af35cd9fef63c7a4cf3b0e6b681886cc8d34"
|
||||
integrity sha512-az3seq9yuc0OXlNLrZ0fWTNbFuL4sN8GN1sLmovELg3+LnpWmOs3GAn2KGa6E7SKMgpCuFvJwvsHEfYasTHUxQ==
|
||||
"@octokit/plugin-paginate-rest@^2.13.3":
|
||||
version "2.13.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.3.tgz#f0f1792230805108762d87906fb02d573b9e070a"
|
||||
integrity sha512-46lptzM9lTeSmIBt/sVP/FLSTPGx6DCzAdSX3PfeJ3mTf4h9sGC26WpaQzMEq/Z44cOcmx8VsOhO+uEgE3cjYg==
|
||||
dependencies:
|
||||
"@octokit/types" "^5.1.1"
|
||||
"@octokit/types" "^6.11.0"
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@^5.1.1":
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.1.1.tgz#1720de3511944ebcca5c391ea82605e13e8f95eb"
|
||||
integrity sha512-u4zy0rVA8darm/AYsIeWkRalhQR99qPL1D/EXHejV2yaECMdHfxXiTXtba8NMBSajOJe8+C9g+EqMKSvysx0dg==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.14.1"
|
||||
deprecation "^2.3.1"
|
||||
|
||||
"@octokit/request-error@^2.0.0":
|
||||
@ -563,7 +569,16 @@
|
||||
deprecation "^2.0.0"
|
||||
once "^1.4.0"
|
||||
|
||||
"@octokit/request@^5.3.0", "@octokit/request@^5.4.0":
|
||||
"@octokit/request-error@^2.0.5":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.0.5.tgz#72cc91edc870281ad583a42619256b380c600143"
|
||||
integrity sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.0.3"
|
||||
deprecation "^2.0.0"
|
||||
once "^1.4.0"
|
||||
|
||||
"@octokit/request@^5.3.0":
|
||||
version "5.4.7"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.7.tgz#fd703ee092e0463ceba49ff7a3e61cb4cf8a0fde"
|
||||
integrity sha512-FN22xUDP0i0uF38YMbOfx6TotpcENP5W8yJM1e/LieGXn6IoRxDMnBf7tx5RKSW4xuUZ/1P04NFZy5iY3Rax1A==
|
||||
@ -577,13 +592,32 @@
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/types@^5.0.0", "@octokit/types@^5.0.1", "@octokit/types@^5.1.1", "@octokit/types@^5.3.0":
|
||||
"@octokit/request@^5.4.12":
|
||||
version "5.4.15"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.15.tgz#829da413dc7dd3aa5e2cdbb1c7d0ebe1f146a128"
|
||||
integrity sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag==
|
||||
dependencies:
|
||||
"@octokit/endpoint" "^6.0.1"
|
||||
"@octokit/request-error" "^2.0.0"
|
||||
"@octokit/types" "^6.7.1"
|
||||
is-plain-object "^5.0.0"
|
||||
node-fetch "^2.6.1"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/types@^5.0.0", "@octokit/types@^5.0.1":
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-5.4.1.tgz#d5d5f2b70ffc0e3f89467c3db749fa87fc3b7031"
|
||||
integrity sha512-OlMlSySBJoJ6uozkr/i03nO5dlYQyE05vmQNZhAh9MyO4DPBP88QlwsDVLmVjIMFssvIZB6WO0ctIGMRG+xsJQ==
|
||||
dependencies:
|
||||
"@types/node" ">= 8"
|
||||
|
||||
"@octokit/types@^6.0.3", "@octokit/types@^6.11.0", "@octokit/types@^6.14.1", "@octokit/types@^6.7.1":
|
||||
version "6.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.14.2.tgz#64c9457f38fb8522bdbba3c8cc814590a2d61bf5"
|
||||
integrity sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA==
|
||||
dependencies:
|
||||
"@octokit/openapi-types" "^7.0.0"
|
||||
|
||||
"@sinonjs/commons@^1.7.0":
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217"
|
||||
@ -957,10 +991,10 @@ bcrypt-pbkdf@^1.0.0:
|
||||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
before-after-hook@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
|
||||
integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==
|
||||
before-after-hook@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.1.tgz#73540563558687586b52ed217dad6a802ab1549c"
|
||||
integrity sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
@ -1236,10 +1270,10 @@ cssstyle@^2.2.0:
|
||||
dependencies:
|
||||
cssom "~0.3.6"
|
||||
|
||||
csv-parse@*, csv-parse@^4.12.0:
|
||||
version "4.12.0"
|
||||
resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.12.0.tgz#fd42d6291bbaadd51d3009f6cadbb3e53b4ce026"
|
||||
integrity sha512-wPQl3H79vWLPI8cgKFcQXl0NBgYYEqVnT1i6/So7OjMpsI540oD7p93r3w6fDSyPvwkTepG05F69/7AViX2lXg==
|
||||
csv-parse@*, csv-parse@^4.15.4:
|
||||
version "4.15.4"
|
||||
resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.15.4.tgz#ad1ec62aaf71a642982dfcb81f1848184d691db5"
|
||||
integrity sha512-OdBbFc0yZhOm17lSxqkirrHlFFVpKRT0wp4DAGoJelsP3LbGzV9LNr7XmM/lrr0uGkCtaqac9UhP8PDHXOAbMg==
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
@ -1752,9 +1786,9 @@ has-values@^1.0.0:
|
||||
kind-of "^4.0.0"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.8"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
||||
version "2.8.9"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
|
||||
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
|
||||
|
||||
html-encoding-sniffer@^2.0.1:
|
||||
version "2.0.1"
|
||||
@ -1934,6 +1968,11 @@ is-plain-object@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-4.1.1.tgz#1a14d6452cbd50790edc7fdaa0aed5a40a35ebb5"
|
||||
integrity sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==
|
||||
|
||||
is-plain-object@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
|
||||
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
|
||||
|
||||
is-potential-custom-element-name@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397"
|
||||
@ -2602,9 +2641,9 @@ lodash.sortby@^4.7.0:
|
||||
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
||||
|
||||
lodash@^4.17.19:
|
||||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
lru-cache@^4.1.5:
|
||||
version "4.1.5"
|
||||
@ -2614,6 +2653,13 @@ lru-cache@^4.1.5:
|
||||
pseudomap "^1.0.2"
|
||||
yallist "^2.1.2"
|
||||
|
||||
lru-cache@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
|
||||
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
make-dir@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
|
||||
@ -2756,7 +2802,7 @@ nice-try@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-fetch@^2.3.0:
|
||||
node-fetch@^2.3.0, node-fetch@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
@ -3236,10 +3282,12 @@ saxes@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
semver@7.x, semver@^7.3.2:
|
||||
version "7.3.2"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
||||
semver@7.x, semver@^7.3.2, semver@^7.3.5:
|
||||
version "7.3.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
semver@^6.0.0, semver@^6.3.0:
|
||||
version "6.3.0"
|
||||
@ -3886,15 +3934,20 @@ xmlchars@^2.2.0:
|
||||
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
|
||||
|
||||
y18n@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
|
||||
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==
|
||||
|
||||
yallist@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
|
||||
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
|
||||
|
||||
yallist@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||
|
||||
yargs-parser@18.x, yargs-parser@^18.1.2:
|
||||
version "18.1.3"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
|
||||
|
Reference in New Issue
Block a user