Compare commits

..

86 Commits
v1 ... v2.4.0

Author SHA1 Message Date
15c905b16b Merge pull request #196 from crazy-max/dl-no-token
don't depend on the GitHub API to check release
2023-01-30 12:02:49 +01:00
a25d6a0130 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-30 11:56:13 +01:00
39322d9057 don't depend on the GitHub API to check release
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-30 11:56:13 +01:00
0648fd6fd6 Merge pull request #195 from crazy-max/fix-readme
fix action version in README
2023-01-28 13:36:35 +00:00
30d8a59ee0 fix action version in README
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-28 14:03:18 +01:00
71320d2e17 Merge pull request #193 from fevrin/update-gh-doc-url
update GH doc URL
2023-01-28 13:37:04 +01:00
272f8b84cf update GH doc URL
Signed-off-by: Fevrin <fevrin@users.noreply.github.com>
2023-01-28 01:46:35 -05:00
5e716dcfd6 Merge pull request #192 from crazy-max/support-ghes
enforce baseUrl to api.github.com if action used on GHES
2023-01-28 03:02:07 +01:00
a83788eef0 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-28 02:47:03 +01:00
d0d9a72195 pass the token input through on GHES
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-28 02:45:17 +01:00
a8165e7b70 enforce baseUrl to api.github.com if action used on GHES
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-28 02:44:08 +01:00
a024221c60 Merge pull request #191 from crazy-max/fix-dl-release
use Octokit client to download buildx
2023-01-28 02:08:06 +01:00
4c3fce4ab2 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-28 01:48:35 +01:00
7c965aebec use Octokit client to download buildx
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-28 01:48:35 +01:00
7932f6210d Merge pull request #189 from docker/version-pinning-docs
docs: add version pinning information to the README
2023-01-25 14:10:54 +01:00
70deadb37a docs: add version pinning information to the README
This should provide an easy reference for users starting to use this
action who want to pin versions, so that they can easily identify the
different versioning pattern used by this action.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-25 13:07:15 +00:00
165fe681b8 Merge pull request #184 from docker/dependabot/npm_and_yarn/json5-2.2.3
Bump json5 from 2.2.0 to 2.2.3
2023-01-08 18:33:12 +01:00
2d305372c4 Bump json5 from 2.2.0 to 2.2.3
Bumps [json5](https://github.com/json5/json5) from 2.2.0 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.0...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-07 04:55:11 +00:00
c252a3bb80 Merge pull request #181 from docker/dependabot/npm_and_yarn/csv-parse-5.3.3
Bump csv-parse from 5.3.1 to 5.3.3
2022-12-19 21:09:29 +01:00
4661366cb8 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-19 21:03:54 +01:00
03d7e8ebf0 Bump csv-parse from 5.3.1 to 5.3.3
Bumps [csv-parse](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-parse) from 5.3.1 to 5.3.3.
- [Release notes](https://github.com/adaltas/node-csv/releases)
- [Changelog](https://github.com/adaltas/node-csv/blob/master/packages/csv-parse/CHANGELOG.md)
- [Commits](https://github.com/adaltas/node-csv/commits/csv-parse@5.3.3/packages/csv-parse)

---
updated-dependencies:
- dependency-name: csv-parse
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 19:37:47 +00:00
22f6533f7c Merge pull request #182 from docker/dependabot/npm_and_yarn/minimatch-3.1.2
Bump minimatch from 3.0.4 to 3.1.2
2022-12-19 20:27:47 +01:00
b30c61b0de readme: fix badges
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-19 20:23:49 +01:00
51cc8966ea update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-19 20:22:54 +01:00
db8b80b0d3 Bump minimatch from 3.0.4 to 3.1.2
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-29 17:55:03 +00:00
39a1a82492 Merge pull request #180 from crazy-max/upd-docs
docs: moved to docs website
2022-11-10 18:25:55 +01:00
c77919d12e docs: add contributing section
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-10 16:02:34 +01:00
341de1b1a5 docs: moved to docs website
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-10 16:01:32 +01:00
8c0edbc76e Merge pull request #175 from crazy-max/input-list-quotes
escape surrounding quotes for platforms input
2022-10-18 11:15:32 +02:00
1fb9cbdb32 escape surrounding quotes for platforms input
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-18 11:06:34 +02:00
693fdd6ca6 Merge pull request #174 from crazy-max/input-quote
preserve quotes surrounding fields in input list
2022-10-18 10:37:08 +02:00
fe4c1ac86d preserve quotes surrounding fields in input list
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-17 20:44:03 +02:00
c74574e6c8 Merge pull request #172 from docker/dependabot/npm_and_yarn/csv-parse-5.3.1
Bump csv-parse from 5.3.0 to 5.3.1
2022-10-17 15:11:27 +02:00
2d0cf98781 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-17 15:08:30 +02:00
5f1d4ea81f Bump csv-parse from 5.3.0 to 5.3.1
Bumps [csv-parse](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-parse) from 5.3.0 to 5.3.1.
- [Release notes](https://github.com/adaltas/node-csv/releases)
- [Changelog](https://github.com/adaltas/node-csv/blob/master/packages/csv-parse/CHANGELOG.md)
- [Commits](https://github.com/adaltas/node-csv/commits/csv-parse@5.3.1/packages/csv-parse)

---
updated-dependencies:
- dependency-name: csv-parse
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-17 04:04:47 +00:00
59b5ed6124 Merge pull request #165 from crazy-max/append
append nodes to builder support
2022-10-14 11:30:50 -07:00
bd61d52837 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-14 11:47:46 +02:00
f6efb5fcbb platforms input
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-14 11:47:46 +02:00
2dfca373f3 append nodes to builder support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-14 11:46:19 +02:00
95cb08cb26 Merge pull request #171 from crazy-max/rmsync
Fix deprecated fs.rmdir
2022-10-12 12:09:19 +02:00
eb5c2a6eea Fix deprecated fs.rmdir
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-12 12:05:06 +02:00
83612bea36 Merge pull request #170 from crazy-max/setOutput
Remove workaround for setOutput
2022-10-12 11:51:02 +02:00
40fefd8a58 Remove workaround for setOutput
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-12 11:44:21 +02:00
90a1e4619e Merge pull request #169 from crazy-max/context-module
move args logic to context module and add tests
2022-10-12 11:43:19 +02:00
5a9fc40575 move args logic to context module and add tests
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-12 11:38:58 +02:00
6c48dad5f0 Merge pull request #159 from docker/dependabot/npm_and_yarn/uuid-9.0.0
Bump uuid from 8.3.2 to 9.0.0
2022-10-12 11:15:57 +02:00
16c2ddbfa7 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-12 11:04:04 +02:00
0fe8589bf4 Bump uuid from 8.3.2 to 9.0.0
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.3.2 to 9.0.0.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.3.2...v9.0.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-12 09:03:26 +00:00
f3692cbe43 Merge pull request #167 from docker/dependabot/npm_and_yarn/actions/core-1.10.0
Bump @actions/core from 1.9.1 to 1.10.0
2022-10-12 10:53:12 +02:00
51ce2e7281 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-12 10:50:51 +02:00
1759384a3b Bump @actions/core from 1.9.1 to 1.10.0
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.9.1 to 1.10.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-30 04:10:30 +00:00
d5234d6605 Merge pull request #162 from crazy-max/nodes-output
nodes metadata JSON ouput
2022-09-22 11:05:09 +02:00
ec8fe6a2ec update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-22 03:02:22 +02:00
c6ec880f34 add tests for inspect parsing
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-22 03:01:46 +02:00
69d3837448 return driver opts and buildkit version from nodes metadata
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-22 03:01:46 +02:00
aa0df6f73a nodes metadata JSON ouput
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-22 03:01:45 +02:00
f0ad70c1de Merge pull request #164 from crazy-max/node-auth
auth support for tls endpoint
2022-09-21 17:59:10 -07:00
1a6cf9b6d7 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-22 02:48:42 +02:00
1c2ad20e10 auth support for tls endpoint
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-22 02:48:36 +02:00
f5bc16b105 Merge pull request #163 from crazy-max/update-docs
update and split docs
2022-09-19 16:18:24 -07:00
86f43c11f1 update and split docs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-18 02:34:19 +02:00
f385c9ed95 Merge pull request #161 from crazy-max/fix-remote
skip setting buildkitd flags and config for remote driver
2022-09-16 18:35:19 +02:00
798ed00eea skip setting buildkitd flags and config for remote driver
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-16 18:12:29 +02:00
bea6a01aa4 Merge pull request #157 from docker/dependabot/npm_and_yarn/actions/core-1.9.1
Bump @actions/core from 1.8.2 to 1.9.1
2022-08-24 13:15:56 +02:00
3a2cc9a001 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-24 12:34:51 +02:00
7a18bafc06 Bump @actions/core from 1.8.2 to 1.9.1
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.8.2 to 1.9.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-09 04:03:44 +00:00
312f67c662 Merge pull request #149 from docker/dependabot/npm_and_yarn/actions/http-client-2.0.1
Bump @actions/http-client from 1.0.11 to 2.0.1
2022-06-07 12:07:38 +02:00
b8ba4729df Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-07 12:05:02 +02:00
afe5b71b31 Bump @actions/http-client from 1.0.11 to 2.0.1
Bumps [@actions/http-client](https://github.com/actions/toolkit/tree/HEAD/packages/http-client) from 1.0.11 to 2.0.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/http-client/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/http-client)

---
updated-dependencies:
- dependency-name: "@actions/http-client"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-07 10:00:02 +00:00
6f5431bef1 Merge pull request #150 from docker/dependabot/npm_and_yarn/actions/tool-cache-2.0.1
Bump @actions/tool-cache from 1.7.2 to 2.0.1
2022-06-07 11:58:06 +02:00
da30c94fcd Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-07 11:51:26 +02:00
718cf00a00 Bump @actions/tool-cache from 1.7.2 to 2.0.1
Bumps [@actions/tool-cache](https://github.com/actions/toolkit/tree/HEAD/packages/tool-cache) from 1.7.2 to 2.0.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/tool-cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/tool-cache)

---
updated-dependencies:
- dependency-name: "@actions/tool-cache"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-07 09:49:41 +00:00
c4fbfe3f62 Merge pull request #151 from docker/dependabot/npm_and_yarn/actions/core-1.8.2
Bump @actions/core from 1.6.0 to 1.8.2
2022-06-07 11:48:17 +02:00
449215757a Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-07 11:46:00 +02:00
cafcc1d31f Merge pull request #152 from rodrigc/readme-clarify-install
Clarify install option in example
2022-05-28 11:26:39 +02:00
7560281ec7 Merge pull request #145 from Firefishy/patch-1
Minor README.md update - use newer action versions
2022-05-28 11:26:08 +02:00
9102fb725f Minor README.md update - use newer action versions
Signed-off-by: Grant Slater <git@firefishy.com>
2022-05-27 00:52:01 +01:00
43262924e3 Clarify description for install option
"docker build" is actually aliased to "docker build buildx"

Signed-off-by: Craig Rodrigues <rodrigc@crodrigues.org>
2022-05-26 18:23:16 -04:00
455b065be4 Clarify install option in example
Co-authored-by: CrazyMax <github@crazymax.dev>
Signed-off-by: Craig Rodrigues <rodrigc@crodrigues.org>
2022-05-26 17:59:37 -04:00
26f93d2e65 Bump @actions/core from 1.6.0 to 1.8.2
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.6.0 to 1.8.2.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 04:04:08 +00:00
91cb32d715 Merge pull request #142 from crazy-max/update-refs
Bump all Docker actions to latest major
2022-05-05 19:46:51 +02:00
7085ac52c5 Bump all Docker actions to latest major
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-05 19:43:45 +02:00
dc7b9719a9 Merge pull request #131 from crazy-max/node16
Node 16 as default runtime
2022-05-05 18:44:52 +02:00
f55bc08278 Merge pull request #141 from crazy-max/fix-test
ci: fix standalone test
2022-05-05 18:38:22 +02:00
aa877a9d36 ci: fix standalone test
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-05 18:33:06 +02:00
130c56f342 Node 16 as default runtime
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-21 13:50:20 +01:00
33 changed files with 1146 additions and 495 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -30,9 +30,16 @@ jobs:
uses: actions/checkout@v3
-
name: Set up Docker Buildx
id: buildx
uses: ./
with:
version: ${{ matrix.buildx-version }}
-
name: Nodes output
run: |
cat << EOF
${{ steps.buildx.outputs.nodes }}
EOF
multi:
runs-on: ubuntu-latest
@ -90,7 +97,7 @@ jobs:
EOL
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: ./
@ -98,7 +105,7 @@ jobs:
buildkitd-flags: --debug
-
name: Build
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64,linux/ppc64le
@ -244,7 +251,7 @@ jobs:
config: /tmp/buildkitd.toml
-
name: Build
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
context: .
@ -271,7 +278,7 @@ jobs:
mirrors = ["mirror.gcr.io"]
-
name: Build
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
context: .
@ -293,14 +300,18 @@ jobs:
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
with:
platforms: ${{ matrix.qemu-platforms }}
-
name: Set up Docker Buildx
id: buildx
uses: ./
with:
version: ${{ matrix.buildx-version }}
-
name: List builder platforms
run: echo ${{ steps.buildx.outputs.platforms }}
build-ref:
runs-on: ubuntu-latest
@ -333,14 +344,32 @@ jobs:
with:
context: .
standalone:
standalone-cmd:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Uninstall docker cli
run: |
sudo apt-get purge -y moby-cli moby-buildx
-
name: Set up Docker Buildx
uses: ./
-
name: Create Dockerfile
run: |
cat > ./Dockerfile <<EOL
FROM alpine
EOL
-
name: Build
run: |
buildx build .
standalone-action:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
buildx-version:
- latest
- ""
steps:
-
name: Checkout
@ -355,10 +384,16 @@ jobs:
with:
version: ${{ matrix.buildx-version }}
-
name: Check available in path
if: matrix.standalone
name: Create Dockerfile
run: |
buildx version
cat > ./Dockerfile <<EOL
FROM alpine
EOL
-
name: Build
uses: docker/build-push-action@master
with:
context: .
standalone-install-error:
runs-on: ubuntu-latest
@ -386,46 +421,46 @@ jobs:
exit 1
fi
standalone-kubernetes:
append:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Uninstall moby
name: Create dummy contexts
run: |
sudo apt-get purge -y moby-engine moby-cli moby-buildx
docker context create ctxbuilder2
docker context create ctxbuilder3
-
name: Setup k8s cluster
run: |
set -x
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo swapoff -a
sudo kubeadm init --cri-socket /run/containerd/containerd.sock
mkdir -p $HOME/.kube/
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $USER $HOME/.kube/config
kubectl taint nodes --all node-role.kubernetes.io/master-
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
kubectl wait --for=condition=ready --timeout=30s node --all
kubectl get nodes -o wide
name: Set up Docker Buildx
id: buildx
uses: ./
with:
append: |
- name: builder2
endpoint: ctxbuilder2
platforms: linux/amd64
driver-opts:
- image=moby/buildkit:master
- network=host
- endpoint: ctxbuilder3
platforms: linux/arm64
-
name: Create Dockerfile
run: |
cat > ./Dockerfile <<EOL
FROM alpine
RUN echo hello
EOL
name: List builder platforms
run: echo ${{ steps.buildx.outputs.platforms }}
platforms:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: ./
with:
driver: kubernetes
-
name: Build
run: |
buildx build .
platforms: linux/amd64

View File

@ -19,7 +19,7 @@ jobs:
uses: actions/checkout@v3
-
name: Validate
uses: docker/bake-action@v1
uses: docker/bake-action@v2
with:
targets: validate
-
@ -27,7 +27,7 @@ jobs:
uses: ./
-
name: Test
uses: docker/bake-action@v1
uses: docker/bake-action@v2
with:
targets: test
-

323
README.md
View File

@ -1,42 +1,37 @@
[![GitHub release](https://img.shields.io/github/release/docker/setup-buildx-action.svg?style=flat-square)](https://github.com/docker/setup-buildx-action/releases/latest)
[![GitHub marketplace](https://img.shields.io/badge/marketplace-docker--setup--buildx-blue?logo=github&style=flat-square)](https://github.com/marketplace/actions/docker-setup-buildx)
[![CI workflow](https://img.shields.io/github/workflow/status/docker/setup-buildx-action/ci?label=ci&logo=github&style=flat-square)](https://github.com/docker/setup-buildx-action/actions?workflow=ci)
[![Test workflow](https://img.shields.io/github/workflow/status/docker/setup-buildx-action/test?label=test&logo=github&style=flat-square)](https://github.com/docker/setup-buildx-action/actions?workflow=test)
[![CI workflow](https://img.shields.io/github/actions/workflow/status/docker/setup-buildx-action/ci.yml?branch=master&label=ci&logo=github&style=flat-square)](https://github.com/docker/setup-buildx-action/actions?workflow=ci)
[![Test workflow](https://img.shields.io/github/actions/workflow/status/docker/setup-buildx-action/test.yml?branch=master&label=test&logo=github&style=flat-square)](https://github.com/docker/setup-buildx-action/actions?workflow=test)
[![Codecov](https://img.shields.io/codecov/c/github/docker/setup-buildx-action?logo=codecov&style=flat-square)](https://codecov.io/gh/docker/setup-buildx-action)
## About
GitHub Action to set up Docker [Buildx](https://github.com/docker/buildx).
This action will create and boot a builder that can be used in the following steps of your workflow if you're using
[buildx](https://github.com/docker/buildx). By default, the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver)
will be used to be able to build multi-platform images and export cache thanks to the [BuildKit](https://github.com/moby/buildkit)
container.
This action will create and boot a builder that can be used in the following
steps of your workflow if you're using Buildx or the [`build-push` action](https://github.com/docker/build-push-action/).
By default, the [`docker-container` driver](https://docs.docker.com/build/building/drivers/docker-container/)
will be used to be able to build multi-platform images and export cache using
a [BuildKit](https://github.com/moby/buildkit) container.
![Screenshot](.github/setup-buildx-action.png)
___
* [Usage](#usage)
* [Quick start](#quick-start)
* [With QEMU](#with-qemu)
* [Install by default](#install-by-default)
* [BuildKit daemon configuration](#buildkit-daemon-configuration)
* [Registry mirror](#registry-mirror)
* [Max parallelism](#max-parallelism)
* [Standalone mode](#standalone-mode)
* [Configuring your builder](#configuring-your-builder)
* [Version pinning](#version-pinning)
* [Customizing](#customizing)
* [inputs](#inputs)
* [outputs](#outputs)
* [environment variables](#environment-variables)
* [Notes](#notes)
* [`nodes` output](#nodes-output)
* [BuildKit container logs](#buildkit-container-logs)
* [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot)
* [Contributing](#contributing)
## Usage
### Quick start
```yaml
name: ci
@ -49,247 +44,137 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
-
name: Inspect builder
run: |
echo "Name: ${{ steps.buildx.outputs.name }}"
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
echo "Status: ${{ steps.buildx.outputs.status }}"
echo "Flags: ${{ steps.buildx.outputs.flags }}"
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
```
### With QEMU
If you want support for more platforms you can use our [setup-qemu](https://github.com/docker/setup-qemu-action) action:
```yaml
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
-
# Add support for more platforms with QEMU (optional)
# https://github.com/docker/setup-qemu-action
name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
-
name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }}
uses: docker/setup-buildx-action@v2
```
### Install by default
## Configuring your builder
See https://docs.docker.com/build/ci/github-actions/configure-builder/
## Version pinning
This action builds images using [Buildx](https://github.com/docker/buildx) and
[BuildKit](https://github.com/moby/buildkit). By default, the action will
attempt to use the latest version of Buildx available on the GitHub Runner
(the build client) and the latest release of BuildKit (the build server).
To pin to a specific version of Buildx, use the `version` input. For example,
to pin to Buildx v0.10.0:
```yaml
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
uses: docker/setup-buildx-action@v1
id: buildx
with:
install: true
-
name: Build
run: |
docker build . # will run buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: v0.10.0
```
### BuildKit daemon configuration
You can provide a [BuildKit configuration](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md)
to your builder if you're using the [`docker-container` driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver)
(default) with the `config` or `config-inline` inputs:
#### Registry mirror
You can configure a registry mirror using an inline block directly in your
workflow with the `config-inline` input:
To pin to a specific version of BuildKit, use the `image` option in the
`driver-opts` input. For example, to pin to BuildKit v0.11.0:
```yaml
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
config-inline: |
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
```
#### Max parallelism
You can limit the parallelism of the BuildKit solver which is particularly
useful for low-powered machines.
You can use the `config-inline` input like the
previous example, or you can use a dedicated BuildKit config file from your
repo if you want with the `config` input:
```toml
# .github/buildkitd.toml
[worker.oci]
max-parallelism = 4
```
```yaml
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
config: .github/buildkitd.toml
```
### Standalone mode
If you don't have the Docker CLI installed on the GitHub Runner, buildx binary
is invoked directly, instead of calling it as a docker plugin. This can be
useful if you want to use the `kubernetes` driver in your self-hosted runner:
```yaml
name: ci
on:
push:
jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
driver: kubernetes
-
name: Build
run: |
buildx build .
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: image=moby/buildkit:v0.11.0
```
## Customizing
### inputs
Following inputs can be used as `step.with` keys
Following inputs can be used as `step.with` keys:
| Name | Type | Description |
|--------------------|---------|-----------------------------------|
| `version` | String | [buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`, `https://github.com/docker/buildx.git#master`) |
| `driver` | String | Sets the [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver) to be used (default `docker-container`) |
| `driver-opts` | CSV | List of additional [driver-specific options](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver-opt) (eg. `image=moby/buildkit:master`) |
| `buildkitd-flags` | String | [Flags for buildkitd](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) daemon (since [buildx v0.3.0](https://github.com/docker/buildx/releases/tag/v0.3.0)) |
| `install` | Bool | Sets up `docker build` command as an alias to `docker buildx` (default `false`) |
| `use` | Bool | Switch to this builder instance (default `true`) |
| `endpoint` | String | [Optional address for docker socket](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#description) or context from `docker context ls` |
| `config`¹ | String | [BuildKit config file](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#config) |
| `config-inline`¹ | String | Same as `config` but inline |
> * ¹ `config` and `config-inline` are mutually exclusive
> `CSV` type must be a newline-delimited string
> ```yaml
> driver-opts: image=moby/buildkit:master
> ```
> `List` type is a newline-delimited string
> ```yaml
> driver-opts: |
> image=moby/buildkit:master
> network=host
> ```
> `CSV` type must be a newline-delimited string
> ```yaml
> platforms: linux/amd64,linux/arm64
> ```
| Name | Type | Description |
|-------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `version` | String | [Buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`, `https://github.com/docker/buildx.git#master`) |
| `driver` | String | Sets the [builder driver](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver) to be used (default `docker-container`) |
| `driver-opts` | List | List of additional [driver-specific options](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver-opt) (eg. `image=moby/buildkit:master`) |
| `buildkitd-flags` | String | [Flags for buildkitd](https://docs.docker.com/engine/reference/commandline/buildx_create/#buildkitd-flags) daemon (since [buildx v0.3.0](https://github.com/docker/buildx/releases/tag/v0.3.0)) |
| `install` | Bool | Sets up `docker build` command as an alias to `docker buildx` (default `false`) |
| `use` | Bool | Switch to this builder instance (default `true`) |
| `endpoint` | String | [Optional address for docker socket](https://docs.docker.com/engine/reference/commandline/buildx_create/#description) or context from `docker context ls` |
| `platforms` | List/CSV | Fixed [platforms](https://docs.docker.com/engine/reference/commandline/buildx_create/#platform) for current node. If not empty, values take priority over the detected ones. |
| `config`¹ | String | [BuildKit config file](https://docs.docker.com/engine/reference/commandline/buildx_create/#config) |
| `config-inline`¹ | String | Same as `config` but inline |
| `append` | YAML | [Append additional nodes](docs/advanced/append-nodes.md) to the builder |
> * ¹ `config` and `config-inline` are mutually exclusive
### outputs
Following outputs are available
| Name | Type | Description |
|---------------|---------|---------------------------------------|
| `name` | String | Builder name |
| `driver` | String | Builder driver |
| `endpoint` | String | Builder node endpoint |
| `status` | String | Builder node status |
| `flags` | String | Builder node flags (if applicable) |
| `platforms` | String | Builder node platforms available (comma separated) |
| Name | Type | Description |
|-------------|--------|-------------------------------------------------|
| `name` | String | Builder name |
| `driver` | String | Builder driver |
| `platforms` | String | Builder node platforms (preferred or available) |
| `nodes` | JSON | Builder [nodes metadata](#nodes-output) |
### environment variables
The following [official docker environment variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) are supported:
| Name | Type | Default | Description |
|-----------------|---------|-------------|-------------------------------------------------|
| `DOCKER_CONFIG` | String | `~/.docker` | The location of your client configuration files |
| Name | Type | Default | Description |
|-----------------|--------|-------------|-------------------------------------------------|
| `DOCKER_CONFIG` | String | `~/.docker` | The location of your client configuration files |
## Notes
### `nodes` output
```json
[
{
"name": "builder-3820d274-502c-4498-ae24-d4c32b3023d90",
"endpoint": "unix:///var/run/docker.sock",
"driver-opts": [
"network=host",
"image=moby/buildkit:master"
],
"status": "running",
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
"buildkit": "3fab389",
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386"
}
]
```
| Name | Type | Description |
|-------------------|--------|----------------------------|
| `name` | String | Node name |
| `endpoint` | String | Node endpoint |
| `driver-opts` | List | Options for the driver |
| `status` | String | Node status |
| `buildkitd-flags` | String | Flags for buildkitd daemon |
| `buildkit` | String | BuildKit version |
| `platforms` | String | Platforms available |
### BuildKit container logs
To display BuildKit container logs (when `docker-container` driver is used) you have to [enable step debug logging](https://docs.github.com/en/actions/managing-workflow-runs/enabling-debug-logging#enabling-step-debug-logging)
or you can also enable debugging in the [setup-buildx action step](https://github.com/docker/setup-buildx-action):
See https://docs.docker.com/build/ci/github-actions/configure-builder/#buildkit-container-logs
```yaml
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
buildkitd-flags: --debug
```
## Contributing
Logs will be available at the end of a job:
![BuildKit container logs](.github/buildkit-container-logs.png)
## Keep up-to-date with GitHub Dependabot
Since [Dependabot](https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-github-dependabot)
has [native GitHub Actions support](https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#package-ecosystem),
to enable it on your GitHub repo all you need to do is add the `.github/dependabot.yml` file:
```yaml
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
```
Want to contribute? Awesome! You can find information about contributing to
this project in the [CONTRIBUTING.md](/.github/CONTRIBUTING.md)

88
__tests__/auth.test.ts Normal file
View File

@ -0,0 +1,88 @@
import {describe, expect, test, beforeEach} from '@jest/globals';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as auth from '../src/auth';
const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-jest')).split(path.sep).join(path.posix.sep);
const dockerConfigHome = path.join(tmpdir, '.docker');
const credsdir = path.join(dockerConfigHome, 'buildx', 'creds');
describe('setCredentials', () => {
beforeEach(() => {
process.env = Object.keys(process.env).reduce((object, key) => {
if (!key.startsWith(auth.envPrefix)) {
object[key] = process.env[key];
}
return object;
}, {});
});
// prettier-ignore
test.each([
[
'mycontext',
'docker-container',
{},
[],
[]
],
[
'docker-container://mycontainer',
'docker-container',
{},
[],
[]
],
[
'tcp://graviton2:1234',
'remote',
{},
[],
[]
],
[
'tcp://graviton2:1234',
'remote',
{
'BUILDER_NODE_0_AUTH_TLS_CACERT': 'foo',
'BUILDER_NODE_0_AUTH_TLS_CERT': 'foo',
'BUILDER_NODE_0_AUTH_TLS_KEY': 'foo'
},
[
path.join(credsdir, 'cacert_graviton2-1234.pem'),
path.join(credsdir, 'cert_graviton2-1234.pem'),
path.join(credsdir, 'key_graviton2-1234.pem')
],
[
`cacert=${path.join(credsdir, 'cacert_graviton2-1234.pem')}`,
`cert=${path.join(credsdir, 'cert_graviton2-1234.pem')}`,
`key=${path.join(credsdir, 'key_graviton2-1234.pem')}`
]
],
[
'tcp://graviton2:1234',
'docker-container',
{
'BUILDER_NODE_0_AUTH_TLS_CACERT': 'foo',
'BUILDER_NODE_0_AUTH_TLS_CERT': 'foo',
'BUILDER_NODE_0_AUTH_TLS_KEY': 'foo'
},
[
path.join(credsdir, 'cacert_graviton2-1234.pem'),
path.join(credsdir, 'cert_graviton2-1234.pem'),
path.join(credsdir, 'key_graviton2-1234.pem')
],
[]
],
])('given %p endpoint', async (endpoint: string, driver: string, envs: Record<string, string>, expectedFiles: Array<string>, expectedOpts: Array<string>) => {
fs.mkdirSync(credsdir, {recursive: true});
for (const [key, value] of Object.entries(envs)) {
process.env[key] = value;
}
expect(auth.setCredentials(credsdir, 0, driver, endpoint)).toEqual(expectedOpts);
expectedFiles.forEach( (file) => {
expect(fs.existsSync(file)).toBe(true);
});
});
});

View File

@ -7,18 +7,14 @@ import * as context from '../src/context';
import * as semver from 'semver';
import * as exec from '@actions/exec';
const tmpNameSync = path.join('/tmp/.docker-setup-buildx-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-')).split(path.sep).join(path.posix.sep);
jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
const tmpDir = path.join('/tmp/.docker-setup-buildx-jest').split(path.sep).join(path.posix.sep);
if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir, {recursive: true});
}
return tmpDir;
return tmpdir;
});
const tmpname = path.join(tmpdir, '.tmpname').split(path.sep).join(path.posix.sep);
jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
return tmpNameSync;
return tmpname;
});
describe('isAvailable', () => {
@ -32,6 +28,34 @@ describe('isAvailable', () => {
});
});
describe('getRelease', () => {
it('returns latest buildx GitHub release', async () => {
const release = await buildx.getRelease('latest');
expect(release).not.toBeNull();
expect(release?.tag_name).not.toEqual('');
});
it('returns v0.10.1 buildx GitHub release', async () => {
const release = await buildx.getRelease('v0.10.1');
expect(release).not.toBeNull();
expect(release?.id).toEqual(90346950);
expect(release?.tag_name).toEqual('v0.10.1');
expect(release?.html_url).toEqual('https://github.com/docker/buildx/releases/tag/v0.10.1');
});
it('returns v0.2.2 buildx GitHub release', async () => {
const release = await buildx.getRelease('v0.2.2');
expect(release).not.toBeNull();
expect(release?.id).toEqual(17671545);
expect(release?.tag_name).toEqual('v0.2.2');
expect(release?.html_url).toEqual('https://github.com/docker/buildx/releases/tag/v0.2.2');
});
it('unknown release', async () => {
await expect(buildx.getRelease('foo')).rejects.toThrowError(new Error('Cannot find Buildx release foo in https://raw.githubusercontent.com/docker/buildx/master/.github/releases.json'));
});
});
describe('isAvailable standalone', () => {
const execSpy = jest.spyOn(exec, 'getExecOutput');
buildx.isAvailable(true);
@ -77,10 +101,128 @@ describe('inspect', () => {
expect(builder).not.toBeUndefined();
expect(builder.name).not.toEqual('');
expect(builder.driver).not.toEqual('');
expect(builder.node_platforms).not.toEqual('');
expect(builder.nodes).not.toEqual({});
}, 100000);
});
describe('parseInspect', () => {
// prettier-ignore
test.each([
[
'inspect1.txt',
{
"nodes": [
{
"name": "builder-5cb467f7-0940-47e1-b94b-d51f54054d620",
"endpoint": "unix:///var/run/docker.sock",
"status": "running",
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
"buildkit": "v0.10.4",
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/arm64,linux/riscv64,linux/386,linux/arm/v7,linux/arm/v6"
}
],
"name": "builder-5cb467f7-0940-47e1-b94b-d51f54054d62",
"driver": "docker-container"
}
],
[
'inspect2.txt',
{
"nodes": [
{
"name": "builder-5f449644-ff29-48af-8344-abb0292d06730",
"endpoint": "unix:///var/run/docker.sock",
"driver-opts": [
"image=moby/buildkit:latest"
],
"status": "running",
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
"buildkit": "v0.10.4",
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386"
}
],
"name": "builder-5f449644-ff29-48af-8344-abb0292d0673",
"driver": "docker-container"
}
],
[
'inspect3.txt',
{
"nodes": [
{
"name": "builder-9929e463-7954-4dc3-89cd-514cca29ff800",
"endpoint": "unix:///var/run/docker.sock",
"driver-opts": [
"image=moby/buildkit:master",
"network=host"
],
"status": "running",
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
"buildkit": "3fab389",
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386"
}
],
"name": "builder-9929e463-7954-4dc3-89cd-514cca29ff80",
"driver": "docker-container"
}
],
[
'inspect4.txt',
{
"nodes": [
{
"name": "default",
"endpoint": "default",
"status": "running",
"buildkit": "20.10.17",
"platforms": "linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6"
}
],
"name": "default",
"driver": "docker"
}
],
[
'inspect5.txt',
{
"nodes": [
{
"name": "aws_graviton2",
"endpoint": "tcp://1.23.45.67:1234",
"driver-opts": [
"cert=/home/user/.certs/aws_graviton2/cert.pem",
"key=/home/user/.certs/aws_graviton2/key.pem",
"cacert=/home/user/.certs/aws_graviton2/ca.pem"
],
"status": "running",
"platforms": "darwin/arm64,linux/arm64,linux/arm/v5,linux/arm/v6,linux/arm/v7,windows/arm64"
}
],
"name": "remote-builder",
"driver": "remote"
}
],
[
'inspect6.txt',
{
"nodes": [
{
"name": "builder-17cfff01-48d9-4c3d-9332-9992e308a5100",
"endpoint": "unix:///var/run/docker.sock",
"status": "running",
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/386"
}
],
"name": "builder-17cfff01-48d9-4c3d-9332-9992e308a510",
"driver": "docker-container"
}
],
])('given %p', async (inspectFile, expected) => {
expect(await buildx.parseInspect(fs.readFileSync(path.join(__dirname, 'fixtures', inspectFile)).toString())).toEqual(expected);
});
});
describe('build', () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-'));
@ -136,8 +278,8 @@ describe('getConfig', () => {
config = await buildx.getConfigInline(val);
}
expect(true).toBe(!invalid);
expect(config).toEqual(`${tmpNameSync}`);
const configValue = fs.readFileSync(tmpNameSync, 'utf-8');
expect(config).toEqual(tmpname);
const configValue = fs.readFileSync(tmpname, 'utf-8');
expect(configValue).toEqual(exValue);
} catch (err) {
// eslint-disable-next-line jest/no-conditional-expect

View File

@ -1,19 +1,206 @@
import {beforeEach, describe, expect, it, jest} from '@jest/globals';
import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as uuid from 'uuid';
import * as context from '../src/context';
import * as nodes from '../src/nodes';
const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-')).split(path.sep).join(path.posix.sep);
jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
const tmpDir = path.join('/tmp/.docker-setup-buildx-jest').split(path.sep).join(path.posix.sep);
if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir, {recursive: true});
}
return tmpDir;
return tmpdir;
});
jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
return path.join('/tmp/.docker-setup-buildx-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
return path.join(tmpdir, '.tmpname').split(path.sep).join(path.posix.sep);
});
jest.mock('uuid');
jest.spyOn(uuid, 'v4').mockReturnValue('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d');
describe('getCreateArgs', () => {
beforeEach(() => {
process.env = Object.keys(process.env).reduce((object, key) => {
if (!key.startsWith('INPUT_')) {
object[key] = process.env[key];
}
return object;
}, {});
});
// prettier-ignore
test.each([
[
0,
new Map<string, string>([
['install', 'false'],
['use', 'true'],
]),
[
'create',
'--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
'--driver', 'docker-container',
'--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
'--use'
]
],
[
1,
new Map<string, string>([
['driver', 'docker'],
['install', 'false'],
['use', 'true'],
]),
[
'create',
'--name', 'default',
'--driver', 'docker',
'--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
'--use'
]
],
[
2,
new Map<string, string>([
['install', 'false'],
['use', 'false'],
['driver-opts', 'image=moby/buildkit:master\nnetwork=host'],
]),
[
'create',
'--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
'--driver', 'docker-container',
'--driver-opt', 'image=moby/buildkit:master',
'--driver-opt', 'network=host',
'--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host'
]
],
[
3,
new Map<string, string>([
['driver', 'remote'],
['endpoint', 'tls://foo:1234'],
['install', 'false'],
['use', 'true'],
]),
[
'create',
'--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
'--driver', 'remote',
'--use',
'tls://foo:1234'
]
],
[
4,
new Map<string, string>([
['driver', 'remote'],
['platforms', 'linux/arm64,linux/arm/v7'],
['endpoint', 'tls://foo:1234'],
['install', 'false'],
['use', 'true'],
]),
[
'create',
'--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
'--driver', 'remote',
'--platform', 'linux/arm64,linux/arm/v7',
'--use',
'tls://foo:1234'
]
],
[
5,
new Map<string, string>([
['install', 'false'],
['use', 'false'],
['driver-opts', `"env.no_proxy=localhost,127.0.0.1,.mydomain"`],
]),
[
'create',
'--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
'--driver', 'docker-container',
'--driver-opt', '"env.no_proxy=localhost,127.0.0.1,.mydomain"',
'--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host'
]
],
[
6,
new Map<string, string>([
['install', 'false'],
['use', 'false'],
['platforms', 'linux/amd64\n"linux/arm64,linux/arm/v7"'],
]),
[
'create',
'--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
'--driver', 'docker-container',
'--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
'--platform', 'linux/amd64,linux/arm64,linux/arm/v7'
]
],
])(
'[%d] given %p as inputs, returns %p',
async (num: number, inputs: Map<string, string>, expected: Array<string>) => {
inputs.forEach((value: string, name: string) => {
setInput(name, value);
});
const inp = await context.getInputs();
const res = await context.getCreateArgs(inp, '0.9.0');
expect(res).toEqual(expected);
}
);
});
describe('getAppendArgs', () => {
beforeEach(() => {
process.env = Object.keys(process.env).reduce((object, key) => {
if (!key.startsWith('INPUT_')) {
object[key] = process.env[key];
}
return object;
}, {});
});
// prettier-ignore
test.each([
[
0,
new Map<string, string>([
['install', 'false'],
['use', 'true'],
]),
{
"name": "aws_graviton2",
"endpoint": "ssh://me@graviton2",
"driver-opts": [
"image=moby/buildkit:latest"
],
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
"platforms": "linux/arm64"
},
[
'create',
'--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
'--append',
'--node', 'aws_graviton2',
'--driver-opt', 'image=moby/buildkit:latest',
'--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
'--platform', 'linux/arm64',
'ssh://me@graviton2'
]
]
])(
'[%d] given %p as inputs, returns %p',
async (num: number, inputs: Map<string, string>, node: nodes.Node, expected: Array<string>) => {
inputs.forEach((value: string, name: string) => {
setInput(name, value);
});
const inp = await context.getInputs();
const res = await context.getAppendArgs(inp, node, '0.9.0');
expect(res).toEqual(expected);
}
);
});
describe('getInputList', () => {
@ -85,30 +272,6 @@ describe('asyncForEach', () => {
});
});
describe('setOutput', () => {
beforeEach(() => {
process.stdout.write = jest.fn() as typeof process.stdout.write;
});
// eslint-disable-next-line jest/expect-expect
it('setOutput produces the correct command', () => {
context.setOutput('some output', 'some value');
assertWriteCalls([`::set-output name=some output::some value${os.EOL}`]);
});
// eslint-disable-next-line jest/expect-expect
it('setOutput handles bools', () => {
context.setOutput('some output', false);
assertWriteCalls([`::set-output name=some output::false${os.EOL}`]);
});
// eslint-disable-next-line jest/expect-expect
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()}`;
@ -117,11 +280,3 @@ 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]);
}
}

View File

@ -0,0 +1,10 @@
Name: builder-5cb467f7-0940-47e1-b94b-d51f54054d62
Driver: docker-container
Nodes:
Name: builder-5cb467f7-0940-47e1-b94b-d51f54054d620
Endpoint: unix:///var/run/docker.sock
Status: running
Flags: --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
Buildkit: v0.10.4
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/arm64, linux/riscv64, linux/386, linux/arm/v7, linux/arm/v6

View File

@ -0,0 +1,11 @@
Name: builder-5f449644-ff29-48af-8344-abb0292d0673
Driver: docker-container
Nodes:
Name: builder-5f449644-ff29-48af-8344-abb0292d06730
Endpoint: unix:///var/run/docker.sock
Driver Options: image="moby/buildkit:latest"
Status: running
Flags: --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
Buildkit: v0.10.4
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386

View File

@ -0,0 +1,11 @@
Name: builder-9929e463-7954-4dc3-89cd-514cca29ff80
Driver: docker-container
Nodes:
Name: builder-9929e463-7954-4dc3-89cd-514cca29ff800
Endpoint: unix:///var/run/docker.sock
Driver Options: image="moby/buildkit:master" network="host"
Status: running
Flags: --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
Buildkit: 3fab389
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386

View File

@ -0,0 +1,9 @@
Name: default
Driver: docker
Nodes:
Name: default
Endpoint: default
Status: running
Buildkit: 20.10.17
Platforms: linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

View File

@ -0,0 +1,9 @@
Name: remote-builder
Driver: remote
Nodes:
Name: aws_graviton2
Endpoint: tcp://1.23.45.67:1234
Driver Options: cert="/home/user/.certs/aws_graviton2/cert.pem" key="/home/user/.certs/aws_graviton2/key.pem" cacert="/home/user/.certs/aws_graviton2/ca.pem"
Status: running
Platforms: darwin/arm64*, linux/arm64*, linux/arm/v5*, linux/arm/v6*, linux/arm/v7*, windows/arm64*, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/mips64le, linux/mips64

View File

@ -0,0 +1,9 @@
Name: builder-17cfff01-48d9-4c3d-9332-9992e308a510
Driver: docker-container
Nodes:
Name: builder-17cfff01-48d9-4c3d-9332-9992e308a5100
Endpoint: unix:///var/run/docker.sock
Status: running
Flags: --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386

View File

@ -1,16 +0,0 @@
import {describe, expect, it} from '@jest/globals';
import * as github from '../src/github';
describe('github', () => {
it('returns latest buildx GitHub release', async () => {
const release = await github.getRelease('latest');
expect(release).not.toBeNull();
expect(release?.tag_name).not.toEqual('');
});
it('returns v0.2.2 buildx GitHub release', async () => {
const release = await github.getRelease('v0.2.2');
expect(release).not.toBeNull();
expect(release?.tag_name).toEqual('v0.2.2');
});
});

View File

@ -22,7 +22,7 @@ inputs:
default: '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host'
required: false
install:
description: 'Sets up docker build command as an alias to docker buildx'
description: 'Sets up docker build command as an alias to docker buildx build'
default: 'false'
required: false
use:
@ -32,28 +32,36 @@ inputs:
endpoint:
description: 'Optional address for docker socket or context from `docker context ls`'
required: false
platforms:
description: 'Fixed platforms for current node. If not empty, values take priority over the detected ones'
required: false
config:
description: 'BuildKit config file'
required: false
config-inline:
description: 'Inline BuildKit config'
required: false
append:
description: 'Append additional nodes to the builder'
required: false
outputs:
name:
description: 'Builder name'
driver:
description: 'Builder driver'
endpoint:
description: 'Builder node endpoint'
status:
description: 'Builder node status'
flags:
description: 'Builder node flags (if applicable)'
platforms:
description: 'Builder node platforms available (comma separated)'
description: 'Builder node platforms (preferred or available)'
nodes:
description: 'Builder nodes metadata'
endpoint:
description: 'Builder node endpoint (deprecated, use nodes output instead)'
status:
description: 'Builder node status (deprecated, use nodes output instead)'
flags:
description: 'Builder node flags (deprecated, use nodes output instead)'
runs:
using: 'node12'
using: 'node16'
main: 'dist/index.js'
post: 'dist/index.js'

View File

@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG NODE_VERSION=12
ARG NODE_VERSION=16
ARG DOCKER_VERSION=20.10.13
ARG BUILDX_VERSION=0.8.1

4
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

50
dist/licenses.txt generated vendored
View File

@ -143,6 +143,31 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
csv-parse
MIT
The MIT License (MIT)
Copyright (c) 2010 Adaltas
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
fs.realpath
ISC
The ISC License
@ -254,6 +279,31 @@ PERFORMANCE OF THIS SOFTWARE.
js-yaml
MIT
(The MIT License)
Copyright (C) 2011-2015 by Vitaly Puzrin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
lru-cache
ISC
The ISC License

View File

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

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

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

View File

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

View File

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

View File

@ -1,10 +1,13 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
setupFiles: ["dotenv/config"],
setupFiles: ['dotenv/config'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.ts$': 'ts-jest'
},
moduleNameMapper: {
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
},
verbose: true
}
};

View File

@ -27,13 +27,15 @@
],
"license": "Apache-2.0",
"dependencies": {
"@actions/core": "^1.6.0",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/http-client": "^1.0.11",
"@actions/tool-cache": "^1.7.2",
"@actions/http-client": "^2.0.1",
"@actions/tool-cache": "^2.0.1",
"csv-parse": "^5.3.3",
"js-yaml": "^4.1.0",
"semver": "^7.3.7",
"tmp": "^0.2.1",
"uuid": "^8.3.2"
"uuid": "^9.0.0"
},
"devDependencies": {
"@types/node": "^16.11.26",

51
src/auth.ts Normal file
View File

@ -0,0 +1,51 @@
import * as fs from 'fs';
export const envPrefix = 'BUILDER_NODE';
export function setCredentials(credsdir: string, index: number, driver: string, endpoint: string): Array<string> {
let url: URL;
try {
url = new URL(endpoint);
} catch (e) {
return [];
}
switch (url.protocol) {
case 'tcp:': {
return setBuildKitClientCerts(credsdir, index, driver, url);
}
}
return [];
}
function setBuildKitClientCerts(credsdir: string, index: number, driver: string, endpoint: URL): Array<string> {
const driverOpts: Array<string> = [];
const buildkitCacert = process.env[`${envPrefix}_${index}_AUTH_TLS_CACERT`] || '';
const buildkitCert = process.env[`${envPrefix}_${index}_AUTH_TLS_CERT`] || '';
const buildkitKey = process.env[`${envPrefix}_${index}_AUTH_TLS_KEY`] || '';
if (buildkitCacert.length == 0 && buildkitCert.length == 0 && buildkitKey.length == 0) {
return driverOpts;
}
let host = endpoint.hostname;
if (endpoint.port.length > 0) {
host += `-${endpoint.port}`;
}
if (buildkitCacert.length > 0) {
const cacertpath = `${credsdir}/cacert_${host}.pem`;
fs.writeFileSync(cacertpath, buildkitCacert);
driverOpts.push(`cacert=${cacertpath}`);
}
if (buildkitCert.length > 0) {
const certpath = `${credsdir}/cert_${host}.pem`;
fs.writeFileSync(certpath, buildkitCert);
driverOpts.push(`cert=${certpath}`);
}
if (buildkitKey.length > 0) {
const keypath = `${credsdir}/key_${host}.pem`;
fs.writeFileSync(keypath, buildkitKey);
driverOpts.push(`key=${keypath}`);
}
if (driver != 'remote') {
return [];
}
return driverOpts;
}

View File

@ -4,19 +4,48 @@ import * as semver from 'semver';
import * as util from 'util';
import * as context from './context';
import * as git from './git';
import * as github from './github';
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as httpm from '@actions/http-client';
import * as tc from '@actions/tool-cache';
export type Builder = {
name?: string;
driver?: string;
node_name?: string;
node_endpoint?: string;
node_status?: string;
node_flags?: string;
node_platforms?: string;
nodes: Node[];
};
export type Node = {
name?: string;
endpoint?: string;
'driver-opts'?: Array<string>;
status?: string;
'buildkitd-flags'?: string;
buildkit?: string;
platforms?: string;
};
export interface GitHubRelease {
id: number;
tag_name: string;
html_url: string;
assets: Array<string>;
}
export const getRelease = async (version: string): Promise<GitHubRelease> => {
const url = `https://raw.githubusercontent.com/docker/buildx/master/.github/releases.json`;
const http: httpm.HttpClient = new httpm.HttpClient('setup-buildx');
const resp: httpm.HttpClientResponse = await http.get(url);
const body = await resp.readBody();
const statusCode = resp.message.statusCode || 500;
if (statusCode >= 400) {
throw new Error(`Failed to get Buildx release ${version} from ${url} with status code ${statusCode}: ${body}`);
}
const releases = <Record<string, GitHubRelease>>JSON.parse(body);
if (!releases[version]) {
throw new Error(`Cannot find Buildx release ${version} in ${url}`);
}
return releases[version];
};
export async function getConfigInline(s: string): Promise<string> {
@ -98,48 +127,83 @@ export async function inspect(name: string, standalone?: boolean): Promise<Build
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
const builder: Builder = {};
itlines: for (const line of res.stdout.trim().split(`\n`)) {
const [key, ...rest] = line.split(':');
const value = rest.map(v => v.trim()).join(':');
if (key.length == 0 || value.length == 0) {
continue;
}
switch (key) {
case 'Name': {
if (builder.name == undefined) {
builder.name = value;
} else {
builder.node_name = value;
}
break;
}
case 'Driver': {
builder.driver = value;
break;
}
case 'Endpoint': {
builder.node_endpoint = value;
break;
}
case 'Status': {
builder.node_status = value;
break;
}
case 'Flags': {
builder.node_flags = value;
break;
}
case 'Platforms': {
builder.node_platforms = value.replace(/\s/g, '');
break itlines;
}
}
}
return builder;
return parseInspect(res.stdout);
});
}
export async function parseInspect(data: string): Promise<Builder> {
const builder: Builder = {
nodes: []
};
let node: Node = {};
for (const line of data.trim().split(`\n`)) {
const [key, ...rest] = line.split(':');
const value = rest.map(v => v.trim()).join(':');
if (key.length == 0 || value.length == 0) {
continue;
}
switch (key.toLowerCase()) {
case 'name': {
if (builder.name == undefined) {
builder.name = value;
} else {
if (Object.keys(node).length > 0) {
builder.nodes.push(node);
node = {};
}
node.name = value;
}
break;
}
case 'driver': {
builder.driver = value;
break;
}
case 'endpoint': {
node.endpoint = value;
break;
}
case 'driver options': {
node['driver-opts'] = (value.match(/(\w+)="([^"]*)"/g) || []).map(v => v.replace(/^(.*)="(.*)"$/g, '$1=$2'));
break;
}
case 'status': {
node.status = value;
break;
}
case 'flags': {
node['buildkitd-flags'] = value;
break;
}
case 'buildkit': {
node.buildkit = value;
break;
}
case 'platforms': {
let platforms: Array<string> = [];
// if a preferred platform is being set then use only these
// https://docs.docker.com/engine/reference/commandline/buildx_inspect/#get-information-about-a-builder-instance
if (value.includes('*')) {
for (const platform of value.split(', ')) {
if (platform.includes('*')) {
platforms.push(platform.replace('*', ''));
}
}
} else {
// otherwise set all platforms available
platforms = value.split(', ');
}
node.platforms = platforms.join(',');
break;
}
}
}
if (Object.keys(node).length > 0) {
builder.nodes.push(node);
}
return builder;
}
export async function build(inputBuildRef: string, dest: string, standalone: boolean): Promise<string> {
// eslint-disable-next-line prefer-const
let [repo, ref] = inputBuildRef.split('#');
@ -197,10 +261,7 @@ export async function build(inputBuildRef: string, dest: string, standalone: boo
}
export async function install(inputVersion: string, dest: string, standalone: boolean): Promise<string> {
const release: github.GitHubRelease | null = await github.getRelease(inputVersion);
if (!release) {
throw new Error(`Cannot find buildx ${inputVersion} release`);
}
const release: GitHubRelease = await getRelease(inputVersion);
core.debug(`Release ${release.tag_name} found`);
const version = release.tag_name.replace(/^v+|v+$/g, '');

View File

@ -2,8 +2,11 @@ import fs from 'fs';
import * as os from 'os';
import path from 'path';
import * as tmp from 'tmp';
import * as uuid from 'uuid';
import {parse} from 'csv-parse/sync';
import * as buildx from './buildx';
import * as nodes from './nodes';
import * as core from '@actions/core';
import {issueCommand} from '@actions/core/lib/command';
let _tmpDir: string;
export const osPlat: string = os.platform();
@ -22,39 +25,128 @@ export function tmpNameSync(options?: tmp.TmpNameOptions): string {
export interface Inputs {
version: string;
name: string;
driver: string;
driverOpts: string[];
buildkitdFlags: string;
platforms: string[];
install: boolean;
use: boolean;
endpoint: string;
config: string;
configInline: string;
append: string;
}
export async function getInputs(): Promise<Inputs> {
return {
version: core.getInput('version'),
name: getBuilderName(core.getInput('driver') || 'docker-container'),
driver: core.getInput('driver') || 'docker-container',
driverOpts: await getInputList('driver-opts', true),
buildkitdFlags: core.getInput('buildkitd-flags') || '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
platforms: await getInputList('platforms', false, true),
install: core.getBooleanInput('install'),
use: core.getBooleanInput('use'),
endpoint: core.getInput('endpoint'),
config: core.getInput('config'),
configInline: core.getInput('config-inline')
configInline: core.getInput('config-inline'),
append: core.getInput('append')
};
}
export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> {
export function getBuilderName(driver: string): string {
return driver == 'docker' ? 'default' : `builder-${uuid.v4()}`;
}
export async function getCreateArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> {
const args: Array<string> = ['create', '--name', inputs.name, '--driver', inputs.driver];
if (buildx.satisfies(buildxVersion, '>=0.3.0')) {
await asyncForEach(inputs.driverOpts, async driverOpt => {
args.push('--driver-opt', driverOpt);
});
if (inputs.driver != 'remote' && inputs.buildkitdFlags) {
args.push('--buildkitd-flags', inputs.buildkitdFlags);
}
}
if (inputs.platforms.length > 0) {
args.push('--platform', inputs.platforms.join(','));
}
if (inputs.use) {
args.push('--use');
}
if (inputs.driver != 'remote') {
if (inputs.config) {
args.push('--config', await buildx.getConfigFile(inputs.config));
} else if (inputs.configInline) {
args.push('--config', await buildx.getConfigInline(inputs.configInline));
}
}
if (inputs.endpoint) {
args.push(inputs.endpoint);
}
return args;
}
export async function getAppendArgs(inputs: Inputs, node: nodes.Node, buildxVersion: string): Promise<Array<string>> {
const args: Array<string> = ['create', '--name', inputs.name, '--append'];
if (node.name) {
args.push('--node', node.name);
}
if (node['driver-opts'] && buildx.satisfies(buildxVersion, '>=0.3.0')) {
await asyncForEach(node['driver-opts'], async driverOpt => {
args.push('--driver-opt', driverOpt);
});
if (inputs.driver != 'remote' && node['buildkitd-flags']) {
args.push('--buildkitd-flags', node['buildkitd-flags']);
}
}
if (node.platforms) {
args.push('--platform', node.platforms);
}
if (node.endpoint) {
args.push(node.endpoint);
}
return args;
}
export async function getInspectArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> {
const args: Array<string> = ['inspect', '--bootstrap'];
if (buildx.satisfies(buildxVersion, '>=0.4.0')) {
args.push('--builder', inputs.name);
}
return args;
}
export async function getInputList(name: string, ignoreComma?: boolean, escapeQuotes?: boolean): Promise<string[]> {
const 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()), []);
const records = parse(items, {
columns: false,
relaxQuotes: true,
comment: '#',
relaxColumnCount: true,
skipEmptyLines: true,
quote: escapeQuotes ? `"` : false
});
for (const record of records as Array<string[]>) {
if (record.length == 1) {
res.push(record[0]);
continue;
} else if (!ignoreComma) {
res.push(...record);
continue;
}
res.push(record.join(','));
}
return res.filter(item => item).map(pat => pat.trim());
}
export const asyncForEach = async (array, callback) => {
@ -62,8 +154,3 @@ 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: unknown): void {
issueCommand('set-output', {name}, value);
}

View File

@ -1,12 +0,0 @@
import * as httpm from '@actions/http-client';
export interface GitHubRelease {
id: number;
tag_name: string;
}
export const getRelease = async (version: string): Promise<GitHubRelease | null> => {
const url = `https://github.com/docker/buildx/releases/${version}`;
const http: httpm.HttpClient = new httpm.HttpClient('setup-buildx');
return (await http.getJson<GitHubRelease>(url)).result;
};

View File

@ -1,9 +1,11 @@
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as uuid from 'uuid';
import * as auth from './auth';
import * as buildx from './buildx';
import * as context from './context';
import * as docker from './docker';
import * as nodes from './nodes';
import * as stateHelper from './state-helper';
import * as util from './util';
import * as core from '@actions/core';
@ -52,46 +54,44 @@ async function run(): Promise<void> {
});
});
const builderName: string = inputs.driver == 'docker' ? 'default' : `builder-${uuid.v4()}`;
context.setOutput('name', builderName);
stateHelper.setBuilderName(builderName);
core.setOutput('name', inputs.name);
stateHelper.setBuilderName(inputs.name);
const credsdir = path.join(dockerConfigHome, 'buildx', 'creds', inputs.name);
fs.mkdirSync(credsdir, {recursive: true});
stateHelper.setCredsDir(credsdir);
if (inputs.driver !== 'docker') {
core.startGroup(`Creating a new builder instance`);
const createArgs: Array<string> = ['create', '--name', builderName, '--driver', inputs.driver];
if (buildx.satisfies(buildxVersion, '>=0.3.0')) {
await context.asyncForEach(inputs.driverOpts, async driverOpt => {
createArgs.push('--driver-opt', driverOpt);
});
if (inputs.buildkitdFlags) {
createArgs.push('--buildkitd-flags', inputs.buildkitdFlags);
}
const authOpts = auth.setCredentials(credsdir, 0, inputs.driver, inputs.endpoint);
if (authOpts.length > 0) {
inputs.driverOpts = [...inputs.driverOpts, ...authOpts];
}
if (inputs.use) {
createArgs.push('--use');
}
if (inputs.endpoint) {
createArgs.push(inputs.endpoint);
}
if (inputs.config) {
createArgs.push('--config', await buildx.getConfigFile(inputs.config));
} else if (inputs.configInline) {
createArgs.push('--config', await buildx.getConfigInline(inputs.configInline));
}
const createCmd = buildx.getCommand(createArgs, standalone);
const createCmd = buildx.getCommand(await context.getCreateArgs(inputs, buildxVersion), standalone);
await exec.exec(createCmd.commandLine, createCmd.args);
core.endGroup();
}
core.startGroup(`Booting builder`);
const bootstrapArgs: Array<string> = ['inspect', '--bootstrap'];
if (buildx.satisfies(buildxVersion, '>=0.4.0')) {
bootstrapArgs.push('--builder', builderName);
if (inputs.append) {
core.startGroup(`Appending node(s) to builder`);
let nodeIndex = 1;
for (const node of nodes.Parse(inputs.append)) {
const authOpts = auth.setCredentials(credsdir, nodeIndex, inputs.driver, node.endpoint || '');
if (authOpts.length > 0) {
node['driver-opts'] = [...(node['driver-opts'] || []), ...authOpts];
}
const appendCmd = buildx.getCommand(await context.getAppendArgs(inputs, node, buildxVersion), standalone);
await exec.exec(appendCmd.commandLine, appendCmd.args);
nodeIndex++;
}
const bootstrapCmd = buildx.getCommand(bootstrapArgs, standalone);
await exec.exec(bootstrapCmd.commandLine, bootstrapCmd.args);
core.endGroup();
}
core.startGroup(`Booting builder`);
const inspectCmd = buildx.getCommand(await context.getInspectArgs(inputs, buildxVersion), standalone);
await exec.exec(inspectCmd.commandLine, inspectCmd.args);
core.endGroup();
if (inputs.install) {
if (standalone) {
throw new Error(`Cannot set buildx as default builder without the Docker CLI`);
@ -102,22 +102,36 @@ async function run(): Promise<void> {
}
core.startGroup(`Inspect builder`);
const builder = await buildx.inspect(builderName, standalone);
const builder = await buildx.inspect(inputs.name, standalone);
const firstNode = builder.nodes[0];
const reducedPlatforms: Array<string> = [];
for (const node of builder.nodes) {
for (const platform of node.platforms?.split(',') || []) {
if (reducedPlatforms.indexOf(platform) > -1) {
continue;
}
reducedPlatforms.push(platform);
}
}
core.info(JSON.stringify(builder, undefined, 2));
context.setOutput('driver', builder.driver);
context.setOutput('endpoint', builder.node_endpoint);
context.setOutput('status', builder.node_status);
context.setOutput('flags', builder.node_flags);
context.setOutput('platforms', builder.node_platforms);
core.setOutput('driver', builder.driver);
core.setOutput('platforms', reducedPlatforms.join(','));
core.setOutput('nodes', JSON.stringify(builder.nodes, undefined, 2));
core.setOutput('endpoint', firstNode.endpoint); // TODO: deprecated, to be removed in a later version
core.setOutput('status', firstNode.status); // TODO: deprecated, to be removed in a later version
core.setOutput('flags', firstNode['buildkitd-flags']); // TODO: deprecated, to be removed in a later version
core.endGroup();
if (!standalone && inputs.driver == 'docker-container') {
stateHelper.setContainerName(`buildx_buildkit_${builder.node_name}`);
if (!standalone && builder.driver == 'docker-container') {
stateHelper.setContainerName(`buildx_buildkit_${firstNode.name}`);
core.startGroup(`BuildKit version`);
core.info(await buildx.getBuildKitVersion(`buildx_buildkit_${builder.node_name}`));
for (const node of builder.nodes) {
const bkvers = await buildx.getBuildKitVersion(`buildx_buildkit_${node.name}`);
core.info(`${node.name}: ${bkvers}`);
}
core.endGroup();
}
if (core.isDebug() || builder.node_flags?.includes('--debug')) {
if (core.isDebug() || firstNode['buildkitd-flags']?.includes('--debug')) {
stateHelper.setDebug('true');
}
} catch (error) {
@ -154,6 +168,11 @@ async function cleanup(): Promise<void> {
});
core.endGroup();
}
if (stateHelper.credsDir.length > 0 && fs.existsSync(stateHelper.credsDir)) {
core.info(`Cleaning up credentials`);
fs.rmSync(stateHelper.credsDir, {recursive: true});
}
}
if (!stateHelper.IsPost) {

13
src/nodes.ts Normal file
View File

@ -0,0 +1,13 @@
import * as yaml from 'js-yaml';
export type Node = {
name?: string;
endpoint?: string;
'driver-opts'?: Array<string>;
'buildkitd-flags'?: string;
platforms?: string;
};
export function Parse(data: string): Node[] {
return yaml.load(data) as Node[];
}

View File

@ -5,6 +5,7 @@ export const IsDebug = !!process.env['STATE_isDebug'];
export const standalone = process.env['STATE_standalone'] || '';
export const builderName = process.env['STATE_builderName'] || '';
export const containerName = process.env['STATE_containerName'] || '';
export const credsDir = process.env['STATE_credsDir'] || '';
export function setDebug(debug: string) {
core.saveState('isDebug', debug);
@ -22,6 +23,10 @@ export function setContainerName(containerName: string) {
core.saveState('containerName', containerName);
}
export function setCredsDir(credsDir: string) {
core.saveState('credsDir', credsDir);
}
if (!IsPost) {
core.saveState('isPost', 'true');
}

View File

@ -2,12 +2,13 @@
# yarn lockfile v1
"@actions/core@^1.2.6", "@actions/core@^1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.6.0.tgz#0568e47039bfb6a9170393a73f3b7eb3b22462cb"
integrity sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==
"@actions/core@^1.10.0", "@actions/core@^1.2.6":
version "1.10.0"
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.10.0.tgz#44551c3c71163949a2f06e94d9ca2157a0cfac4f"
integrity sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==
dependencies:
"@actions/http-client" "^1.0.11"
"@actions/http-client" "^2.0.1"
uuid "^8.3.2"
"@actions/exec@^1.0.0", "@actions/exec@^1.1.1":
version "1.1.1"
@ -16,26 +17,26 @@
dependencies:
"@actions/io" "^1.0.1"
"@actions/http-client@^1.0.11", "@actions/http-client@^1.0.8":
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==
"@actions/http-client@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.0.1.tgz#873f4ca98fe32f6839462a6f046332677322f99c"
integrity sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==
dependencies:
tunnel "0.0.6"
tunnel "^0.0.6"
"@actions/io@^1.0.1", "@actions/io@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@actions/io/-/io-1.1.1.tgz#4a157406309e212ab27ed3ae30e8c1d641686a66"
integrity sha512-Qi4JoKXjmE0O67wAOH6y0n26QXhMKMFo7GD/4IXNVcrtLjUlGjGuVys6pQgwF3ArfGTQu0XpqaNr0YhED2RaRA==
"@actions/tool-cache@^1.7.2":
version "1.7.2"
resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-1.7.2.tgz#389ad15916f91999959c6b2865144839ecc571a9"
integrity sha512-GYlcgg/PK2RWBrGG2sFg6s7im3S94LMKuqAv8UPDq/pGTZbuEvmN4a95Fn1Z19OE+vt7UbUHeewOD5tEBT+4TQ==
"@actions/tool-cache@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-2.0.1.tgz#8a649b9c07838d9d750c9864814e66a7660ab720"
integrity sha512-iPU+mNwrbA8jodY8eyo/0S/QqCKDajiR8OxWTnSk/SnYg0sj8Hp4QcUEVC1YFpHWXtrfbQrE13Jz4k4HXJQKcA==
dependencies:
"@actions/core" "^1.2.6"
"@actions/exec" "^1.0.0"
"@actions/http-client" "^1.0.8"
"@actions/http-client" "^2.0.1"
"@actions/io" "^1.1.1"
semver "^6.1.0"
uuid "^3.3.2"
@ -1409,7 +1410,7 @@ combined-stream@^1.0.8:
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.8.0"
@ -1449,6 +1450,11 @@ cssstyle@^2.3.0:
dependencies:
cssom "~0.3.6"
csv-parse@^5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-5.3.3.tgz#3b75d2279e2edb550cbc54c65b25cbbf3d0033ad"
integrity sha512-kEWkAPleNEdhFNkHQpFHu9RYPogsFj3dx6bCxL847fsiLgidzWg0z/O0B1kVWMJUc5ky64zGp18LX2T3DQrOfw==
data-urls@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
@ -2639,11 +2645,9 @@ json-stable-stringify-without-jsonify@^1.0.1:
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
json5@2.x, json5@^2.1.2:
version "2.2.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
dependencies:
minimist "^1.2.5"
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
kleur@^3.0.3:
version "3.0.3"
@ -2760,17 +2764,12 @@ mimic-fn@^2.1.0:
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.5:
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
@ -3351,7 +3350,7 @@ tsutils@^3.21.0:
dependencies:
tslib "^1.8.1"
tunnel@0.0.6:
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
@ -3419,6 +3418,11 @@ uuid@^8.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
uuid@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
v8-compile-cache-lib@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8"