Compare commits

...

74 Commits

Author SHA1 Message Date
885d1462b8 Merge pull request #258 from crazy-max/update-toolkit
bump @docker/actions-toolkit from 0.7.1 to 0.10.0
2023-08-27 18:39:52 -07:00
e5fad018d0 ci: check lab releases
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-08-26 14:03:23 +02:00
45161fd92a update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-08-26 14:03:22 +02:00
a4d51f53dd bump @docker/actions-toolkit from 0.7.1 to 0.10.0
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-08-26 14:03:22 +02:00
93b8ecaa2c ci: docker-ce packages are now installed on GitHub Runners
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-08-26 14:03:22 +02:00
7703e82fbc Merge pull request #253 from docker/dependabot/npm_and_yarn/word-wrap-1.2.5
Bump word-wrap from 1.2.3 to 1.2.5
2023-08-08 13:17:08 +02:00
0005881963 Merge pull request #254 from crazy-max/rm-codeowners
chore: remove CODEOWNERS
2023-08-08 12:55:44 +02:00
b699069f49 chore: remove CODEOWNERS
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-08-08 12:53:26 +02:00
9bfc5497b8 Bump word-wrap from 1.2.3 to 1.2.5
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.5.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.5)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-08 10:46:55 +00:00
b92d4d8769 Merge pull request #252 from crazy-max/dependabot-update
chore: set increase as versioning strategy
2023-08-08 09:53:55 +03:00
285be6c835 chore: set increase as versioning strategy
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-08-08 05:57:51 +02:00
4c0219f9ac Merge pull request #248 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.7.1
Bump @docker/actions-toolkit from 0.7.0 to 0.7.1
2023-07-12 14:31:49 +02:00
0db41bf51b update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-07-12 14:30:00 +02:00
62fc1a1dd6 Bump @docker/actions-toolkit from 0.7.0 to 0.7.1
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.7.0 to 0.7.1.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.7.0...v0.7.1)

---
updated-dependencies:
- dependency-name: "@docker/actions-toolkit"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 12:28:25 +00:00
2a1a44ac4a Merge pull request #246 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.7.0
Bump @docker/actions-toolkit from 0.6.0 to 0.7.0
2023-07-07 10:03:01 +02:00
a6c26a99ef update ci workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-07-06 23:24:05 +02:00
a5a7f565d9 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-07-06 23:17:35 +02:00
7d7611f95b Bump @docker/actions-toolkit from 0.6.0 to 0.7.0
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.6.0...v0.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-06 19:49:53 +00:00
16c0bc4a6e Merge pull request #242 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.6.0
Bump @docker/actions-toolkit from 0.5.0 to 0.6.0
2023-06-28 17:24:42 +02:00
ebcacb9c21 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-28 17:22:25 +02:00
496a823b8b Bump @docker/actions-toolkit from 0.5.0 to 0.6.0
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.5.0...v0.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-28 15:16:58 +00:00
a56031a493 Merge pull request #241 from nicks/nicks/driver
context: only append flags if we know the driver supports them
2023-06-28 15:46:28 +02:00
922550f064 context: only append flags if we know the driver supports them
Background: before this change, if i tried to use GHA with an experimental
driver, it would automatically append the flags

``
--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
```

even if the underlying driver did not support them.

Signed-off-by: Nick Santos <nick.santos@docker.com>
2023-06-28 09:30:10 -04:00
ecf95283f0 Merge pull request #238 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.5.0
Bump @docker/actions-toolkit from 0.4.0 to 0.5.0
2023-06-13 11:55:02 +02:00
b2a38ee0c6 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-13 11:51:23 +02:00
7f79690cac Bump @docker/actions-toolkit from 0.4.0 to 0.5.0
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.4.0...v0.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-13 09:45:06 +00:00
bdd549bec0 Merge pull request #237 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.4.0
Bump @docker/actions-toolkit from 0.3.0 to 0.4.0
2023-06-10 02:08:25 +02:00
be4a3855af update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-10 02:05:18 +02:00
6c4dbb29f6 Bump @docker/actions-toolkit from 0.3.0 to 0.4.0
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.3.0...v0.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-10 00:03:39 +00:00
6a58db7e0d Merge pull request #236 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.3.0
Bump @docker/actions-toolkit from 0.2.0 to 0.3.0
2023-06-07 15:29:48 +02:00
d56292e348 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-07 15:26:35 +02:00
790eb2db47 Bump @docker/actions-toolkit from 0.2.0 to 0.3.0
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.2.0...v0.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-07 13:25:22 +00:00
2a81c53912 Merge pull request #231 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.2.0
Bump @docker/actions-toolkit from 0.1.0 to 0.2.0
2023-06-06 14:20:23 +02:00
00b2400aad update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-06 14:13:56 +02:00
484614d7a1 Bump @docker/actions-toolkit from 0.1.0 to 0.2.0
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.1.0 to 0.2.0.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.1.0...v0.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-06 12:05:07 +00:00
d95759405f Merge pull request #219 from crazy-max/ci-k3s-append
set node name for k8s driver when appending nodes
2023-06-06 13:38:48 +02:00
5bb6d36be0 ci: set up and build with k3s
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-02 14:27:38 +02:00
a99c5e53ef update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-02 14:03:28 +02:00
fc1a41d2e5 set node name for k8s driver when appending nodes
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-02 14:03:26 +02:00
95cefc3c57 Merge pull request #230 from docker/dependabot/github_actions/docker/bake-action-3
Bump docker/bake-action from 2 to 3
2023-06-02 13:50:38 +02:00
8ec3610541 Bump docker/bake-action from 2 to 3
Bumps [docker/bake-action](https://github.com/docker/bake-action) from 2 to 3.
- [Release notes](https://github.com/docker/bake-action/releases)
- [Commits](https://github.com/docker/bake-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/bake-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-19 04:57:04 +00:00
a946f06b5d Merge pull request #229 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.1.0
Bump @docker/actions-toolkit from 0.1.0-beta.19 to 0.1.0
2023-04-17 06:43:00 +02:00
ce223e774e update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-04-17 02:59:38 +02:00
d267e74486 use new implementation from toolkit
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-04-17 02:59:25 +02:00
d350de3bba update dev dependencies
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-04-17 02:56:56 +02:00
45a8690f10 Bump @docker/actions-toolkit from 0.1.0-beta.19 to 0.1.0
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.1.0-beta.19 to 0.1.0.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.1.0-beta.19...v0.1.0)

---
updated-dependencies:
- dependency-name: "@docker/actions-toolkit"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-12 04:57:20 +00:00
b167a89702 Merge pull request #221 from crazy-max/update-workflows
ci: split validate and test workflow
2023-03-15 15:20:34 +00:00
81d4866861 ci: split validate and test workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-12 13:58:14 +01:00
07aea5fc9c Merge pull request #220 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.1.0-beta.19
Bump @docker/actions-toolkit from 0.1.0-beta.18 to 0.1.0-beta.19
2023-03-11 21:09:01 +00:00
1d91983c26 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-11 22:04:18 +01:00
496312bcb8 Bump @docker/actions-toolkit from 0.1.0-beta.18 to 0.1.0-beta.19
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.1.0-beta.18 to 0.1.0-beta.19.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.1.0-beta.18...v0.1.0-beta.19)

---
updated-dependencies:
- dependency-name: "@docker/actions-toolkit"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-11 21:02:49 +00:00
4b4e9c3e2d Merge pull request #216 from awendland/patch-1
nit typo in README.md, csv is comma-delimited
2023-03-10 09:29:49 +00:00
eb27bcbef3 Merge pull request #218 from crazy-max/fix-builder-removal
do not remove builder using the docker driver
2023-03-10 09:28:46 +00:00
b7471d4240 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-10 00:06:27 +01:00
e2df91e851 check builder exists before removal
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-10 00:05:22 +01:00
85ce96bcbc do not remove builder using the docker driver
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-09 10:08:41 +01:00
f549413411 Merge pull request #217 from docker/dependabot/npm_and_yarn/docker/actions-toolkit-0.1.0-beta.18
Bump @docker/actions-toolkit from 0.1.0-beta.16 to 0.1.0-beta.18
2023-03-09 08:47:13 +00:00
99988698a5 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-09 09:42:37 +01:00
e30725c029 Bump @docker/actions-toolkit from 0.1.0-beta.16 to 0.1.0-beta.18
Bumps [@docker/actions-toolkit](https://github.com/docker/actions-toolkit) from 0.1.0-beta.16 to 0.1.0-beta.18.
- [Release notes](https://github.com/docker/actions-toolkit/releases)
- [Commits](https://github.com/docker/actions-toolkit/compare/v0.1.0-beta.16...v0.1.0-beta.18)

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>

---
updated-dependencies:
- dependency-name: "@docker/actions-toolkit"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-08 19:13:39 +01:00
f1dc97ee10 Merge pull request #213 from crazy-max/cleanup-input
cleanup input to remove builder and temp files
2023-03-08 17:53:19 +00:00
51ecd0a47f nit typo in README.md, csv is comma-delimited
Signed-off-by: Alex Wendland <me@alexwendland.com>
2023-03-07 11:09:55 -05:00
830f01a409 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-03 12:08:20 +01:00
8b13d483f2 cleanup input to remove builder and temp files
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-03 12:08:20 +01:00
03a7a3d9fb Merge pull request #209 from crazy-max/docker-context
fix current context as builder name for docker driver
2023-03-03 10:51:02 +01:00
30389db034 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-02 19:49:22 +01:00
05ca2e6f5e fix current context as builder name for docker driver
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-02 19:49:22 +01:00
774ea5c2f1 Merge pull request #204 from crazy-max/switch-toolkit
switch to actions-toolkit implementation
2023-03-02 19:47:30 +01:00
534bd3c5e6 readme: update screenshot
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-02-25 13:27:17 +01:00
0f5a2d6712 update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-02-25 13:27:17 +01:00
987520896f switch to actions-toolkit implementation
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-02-25 13:27:17 +01:00
a19c171088 Merge pull request #208 from crazy-max/fix-docs-links
docs: updates
2023-02-24 14:47:01 +01:00
347dac9901 docs: updates
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-02-24 03:22:30 +01:00
2dd22fa31c Merge pull request #203 from docker/dependabot/github_actions/crazy-max/ghaction-dump-context-2
Bump crazy-max/ghaction-dump-context from 1 to 2
2023-02-13 11:36:01 +01:00
dd904132a2 Bump crazy-max/ghaction-dump-context from 1 to 2
Bumps [crazy-max/ghaction-dump-context](https://github.com/crazy-max/ghaction-dump-context) from 1 to 2.
- [Release notes](https://github.com/crazy-max/ghaction-dump-context/releases)
- [Changelog](https://github.com/crazy-max/ghaction-dump-context/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crazy-max/ghaction-dump-context/compare/v1...v2)

---
updated-dependencies:
- dependency-name: crazy-max/ghaction-dump-context
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 04:56:50 +00:00
41 changed files with 3134 additions and 2576 deletions

View File

@ -2,7 +2,7 @@
"env": { "env": {
"node": true, "node": true,
"es2021": true, "es2021": true,
"jest/globals": true "jest": true
}, },
"extends": [ "extends": [
"eslint:recommended", "eslint:recommended",

1
.github/CODEOWNERS vendored
View File

@ -1 +0,0 @@
* @crazy-max

View File

@ -11,6 +11,7 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
versioning-strategy: "increase"
allow: allow:
- dependency-type: "production" - dependency-type: "production"
labels: labels:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -2,7 +2,7 @@ name: ci
on: on:
schedule: schedule:
- cron: '0 10 * * *' # everyday at 10am - cron: '0 10 * * *'
push: push:
branches: branches:
- 'master' - 'master'
@ -10,9 +10,6 @@ on:
tags: tags:
- 'v*' - 'v*'
pull_request: pull_request:
branches:
- 'master'
- 'releases/v*'
jobs: jobs:
main: main:
@ -21,9 +18,11 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
buildx-version: buildx-version:
- latest
- v0.4.1
- "" - ""
- "latest"
- "v0.4.1"
- "lab:latest"
- "lab:v0.11.2-desktop.2"
steps: steps:
- -
name: Checkout name: Checkout
@ -63,7 +62,7 @@ jobs:
- -
name: Stop docker name: Stop docker
run: | run: |
sudo systemctl stop docker sudo systemctl stop docker docker.socket
- -
name: Set up Docker Buildx name: Set up Docker Buildx
id: buildx id: buildx
@ -80,7 +79,7 @@ jobs:
- -
name: Dump context name: Dump context
if: always() if: always()
uses: crazy-max/ghaction-dump-context@v1 uses: crazy-max/ghaction-dump-context@v2
debug: debug:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -288,8 +287,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
buildx-version: buildx-version:
- latest - v0.9.1
- v0.4.1
- "" - ""
qemu-platforms: qemu-platforms:
- all - all
@ -353,7 +351,11 @@ jobs:
- -
name: Uninstall docker cli name: Uninstall docker cli
run: | run: |
sudo apt-get purge -y moby-cli moby-buildx if dpkg -s "docker-ce" >/dev/null 2>&1; then
sudo dpkg -r --force-depends docker-ce-cli docker-buildx-plugin
else
sudo apt-get purge -y moby-cli moby-buildx
fi
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: ./ uses: ./
@ -377,7 +379,11 @@ jobs:
- -
name: Uninstall docker cli name: Uninstall docker cli
run: | run: |
sudo apt-get purge -y moby-cli moby-buildx if dpkg -s "docker-ce" >/dev/null 2>&1; then
sudo dpkg -r --force-depends docker-ce-cli docker-buildx-plugin
else
sudo apt-get purge -y moby-cli moby-buildx
fi
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: ./ uses: ./
@ -404,7 +410,11 @@ jobs:
- -
name: Uninstall docker cli name: Uninstall docker cli
run: | run: |
sudo apt-get purge -y moby-cli moby-buildx if dpkg -s "docker-ce" >/dev/null 2>&1; then
sudo dpkg -r --force-depends docker-ce-cli docker-buildx-plugin
else
sudo apt-get purge -y moby-cli moby-buildx
fi
- -
name: Set up Docker Buildx name: Set up Docker Buildx
id: buildx id: buildx
@ -464,3 +474,88 @@ jobs:
uses: ./ uses: ./
with: with:
platforms: linux/amd64 platforms: linux/amd64
docker-context:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Create Docker context
run: |
docker context create foo
docker context use foo
-
name: Set up Docker Buildx
uses: ./
with:
driver: docker
cleanup:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
cleanup:
- true
- false
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: ./
with:
cleanup: ${{ matrix.cleanup }}
k3s:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
version:
- v0.11.0
- v0.10.5
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Install k3s
uses: crazy-max/.github/.github/actions/install-k3s@605d30d5ae97f6680578ace4b56645af79343e60
with:
version: "v1.21.2-k3s1"
-
name: Set up Docker Buildx
id: buildx
uses: ./
with:
version: ${{ matrix.version }}
driver: kubernetes
platforms: linux/amd64
driver-opts: |
image=moby/buildkit:buildx-stable-1
qemu.install=true
append: |
- platforms: linux/arm64
driver-opts:
- image=moby/buildkit:buildx-stable-1
- qemu.install=true
- platforms: linux/s390x
driver-opts:
- image=moby/buildkit:buildx-stable-1
- qemu.install=true
-
name: Create Dockerfile
run: |
cat > ./Dockerfile <<EOL
FROM alpine
RUN uname -a
EOL
-
name: Build
uses: docker/build-push-action@master
with:
context: .

View File

@ -6,9 +6,6 @@ on:
- 'master' - 'master'
- 'releases/v*' - 'releases/v*'
pull_request: pull_request:
branches:
- 'master'
- 'releases/v*'
jobs: jobs:
test: test:
@ -17,17 +14,12 @@ jobs:
- -
name: Checkout name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
-
name: Validate
uses: docker/bake-action@v2
with:
targets: validate
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: ./ uses: ./
- -
name: Test name: Test
uses: docker/bake-action@v2 uses: docker/bake-action@v3
with: with:
targets: test targets: test
- -

41
.github/workflows/validate.yml vendored Normal file
View File

@ -0,0 +1,41 @@
name: validate
on:
push:
branches:
- 'master'
- 'releases/v*'
pull_request:
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
targets: ${{ steps.targets.outputs.matrix }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Targets matrix
id: targets
run: |
echo "matrix=$(docker buildx bake validate --print | jq -cr '.group.validate.targets')" >> $GITHUB_OUTPUT
validate:
runs-on: ubuntu-latest
needs:
- prepare
strategy:
fail-fast: false
matrix:
target: ${{ fromJson(needs.prepare.outputs.targets) }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Validate
uses: docker/bake-action@v3
with:
targets: ${{ matrix.target }}

View File

@ -20,14 +20,12 @@ ___
* [Usage](#usage) * [Usage](#usage)
* [Configuring your builder](#configuring-your-builder) * [Configuring your builder](#configuring-your-builder)
* [Version pinning](#version-pinning)
* [Customizing](#customizing) * [Customizing](#customizing)
* [inputs](#inputs) * [inputs](#inputs)
* [outputs](#outputs) * [outputs](#outputs)
* [environment variables](#environment-variables) * [environment variables](#environment-variables)
* [Notes](#notes) * [Notes](#notes)
* [`nodes` output](#nodes-output) * [`nodes` output](#nodes-output)
* [BuildKit container logs](#buildkit-container-logs)
* [Contributing](#contributing) * [Contributing](#contributing)
## Usage ## Usage
@ -57,34 +55,17 @@ jobs:
## Configuring your builder ## Configuring your builder
See https://docs.docker.com/build/ci/github-actions/configure-builder/ * [Version pinning](https://docs.docker.com/build/ci/github-actions/configure-builder/#version-pinning): Pin to a specific Buildx or BuildKit version
* [BuildKit container logs](https://docs.docker.com/build/ci/github-actions/configure-builder/#buildkit-container-logs): Enable BuildKit container logs for debugging purposes
## Version pinning * [BuildKit Daemon configuration](https://docs.docker.com/build/ci/github-actions/configure-builder/#buildkit-daemon-configuration)
* [Registry mirror](https://docs.docker.com/build/ci/github-actions/configure-builder/#registry-mirror): Configure a registry mirror for your builds
This action builds images using [Buildx](https://github.com/docker/buildx) and * [Max parallelism](https://docs.docker.com/build/ci/github-actions/configure-builder/#max-parallelism): Configure the maximum parallelism for your builds
[BuildKit](https://github.com/moby/buildkit). By default, the action will * [Append additional nodes to the builder](https://docs.docker.com/build/ci/github-actions/configure-builder/#append-additional-nodes-to-the-builder): Create additional nodes for your builder
attempt to use the latest version of Buildx available on the GitHub Runner * [Authentication for remote builders](https://docs.docker.com/build/ci/github-actions/configure-builder/#authentication-for-remote-builders)
(the build client) and the latest release of BuildKit (the build server). * [SSH authentication](https://docs.docker.com/build/ci/github-actions/configure-builder/#ssh-authentication): Authenticate to a remote builder using SSH
* [TLS authentication](https://docs.docker.com/build/ci/github-actions/configure-builder/#tls-authentication): Authenticate to a remote builder using TLS
To pin to a specific version of Buildx, use the `version` input. For example, * [Standalone mode](https://docs.docker.com/build/ci/github-actions/configure-builder/#standalone-mode): Use Buildx as a standalone binary (without the Docker CLI)
to pin to Buildx v0.10.0: * [Isolated builders](https://docs.docker.com/build/ci/github-actions/configure-builder/#isolated-builders): Create isolated builders for your builds
```yaml
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: v0.10.0
```
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: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: image=moby/buildkit:v0.11.0
```
## Customizing ## Customizing
@ -99,24 +80,25 @@ Following inputs can be used as `step.with` keys:
> network=host > network=host
> ``` > ```
> `CSV` type must be a newline-delimited string > `CSV` type must be a comma-delimited string
> ```yaml > ```yaml
> platforms: linux/amd64,linux/arm64 > platforms: linux/amd64,linux/arm64
> ``` > ```
| Name | Type | Description | | Name | Type | Default | Description |
|-------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |-------------------|----------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `version` | String | [Buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`, `https://github.com/docker/buildx.git#master`) | | `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` | String | `docker-container` | Sets the [builder driver](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver) to be used |
| `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`) | | `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)) | | `buildkitd-flags` | String | | [Flags for buildkitd](https://docs.docker.com/engine/reference/commandline/buildx_create/#buildkitd-flags) daemon |
| `install` | Bool | Sets up `docker build` command as an alias to `docker buildx` (default `false`) | | `install` | Bool | `false` | Sets up `docker build` command as an alias to `docker buildx` |
| `use` | Bool | Switch to this builder instance (default `true`) | | `use` | Bool | `true` | Switch to this builder instance |
| `endpoint` | String | [Optional address for docker socket](https://docs.docker.com/engine/reference/commandline/buildx_create/#description) or context from `docker context ls` | | `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. | | `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`¹ | String | | [BuildKit config file](https://docs.docker.com/engine/reference/commandline/buildx_create/#config) |
| `config-inline`¹ | String | Same as `config` but inline | | `config-inline`¹ | String | | Same as `config` but inline |
| `append` | YAML | [Append additional nodes](docs/advanced/append-nodes.md) to the builder | | `append` | YAML | | [Append additional nodes](docs/advanced/append-nodes.md) to the builder |
| `cleanup` | Bool | `true` | Cleanup temp files and remove builder at the end of a job |
> * ¹ `config` and `config-inline` are mutually exclusive > * ¹ `config` and `config-inline` are mutually exclusive
@ -170,10 +152,6 @@ The following [official docker environment variables](https://docs.docker.com/en
| `buildkit` | String | BuildKit version | | `buildkit` | String | BuildKit version |
| `platforms` | String | Platforms available | | `platforms` | String | Platforms available |
### BuildKit container logs
See https://docs.docker.com/build/ci/github-actions/configure-builder/#buildkit-container-logs
## Contributing ## Contributing
Want to contribute? Awesome! You can find information about contributing to Want to contribute? Awesome! You can find information about contributing to

View File

@ -1,88 +0,0 @@
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

@ -1,261 +0,0 @@
import {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 buildx from '../src/buildx';
import * as context from '../src/context';
import * as semver from 'semver';
import * as exec from '@actions/exec';
const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-')).split(path.sep).join(path.posix.sep);
jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
return tmpdir;
});
const tmpname = path.join(tmpdir, '.tmpname').split(path.sep).join(path.posix.sep);
jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
return tmpname;
});
describe('isAvailable', () => {
const execSpy = jest.spyOn(exec, 'getExecOutput');
buildx.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], {
silent: true,
ignoreReturnCode: true
});
});
describe('isAvailable standalone', () => {
const execSpy = jest.spyOn(exec, 'getExecOutput');
buildx.isAvailable(true);
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`buildx`, [], {
silent: true,
ignoreReturnCode: true
});
});
describe('getVersion', () => {
it('valid', async () => {
const version = await buildx.getVersion();
expect(semver.valid(version)).not.toBeNull();
});
});
describe('parseVersion', () => {
test.each([
['github.com/docker/buildx 0.4.1+azure bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'],
['github.com/docker/buildx f117971 f11797113e5a9b86bd976329c5dbb8a8bfdfadfa', 'f117971']
])('given %p', async (stdout, expected) => {
expect(buildx.parseVersion(stdout)).toEqual(expected);
});
});
describe('satisfies', () => {
test.each([
['0.4.1', '>=0.3.2', true],
['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false],
['f117971', '>0.6.0', true]
])('given %p', async (version, range, expected) => {
expect(buildx.satisfies(version, range)).toBe(expected);
});
});
describe('inspect', () => {
it('valid', async () => {
const builder = await buildx.inspect('');
expect(builder).not.toBeUndefined();
expect(builder.name).not.toEqual('');
expect(builder.driver).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-'));
// eslint-disable-next-line jest/no-disabled-tests
it.skip('builds refs/pull/648/head', async () => {
const buildxBin = await buildx.build('https://github.com/docker/buildx.git#refs/pull/648/head', tmpDir, false);
expect(fs.existsSync(buildxBin)).toBe(true);
}, 100000);
// eslint-disable-next-line jest/no-disabled-tests
it.skip('builds 67bd6f4dc82a9cd96f34133dab3f6f7af803bb14', async () => {
const buildxBin = await buildx.build('https://github.com/docker/buildx.git#67bd6f4dc82a9cd96f34133dab3f6f7af803bb14', tmpDir, false);
expect(fs.existsSync(buildxBin)).toBe(true);
}, 100000);
});
describe('install', () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-'));
test.each([
['v0.4.1', false],
['latest', false],
['v0.4.1', true],
['latest', true]
])(
'acquires %p of buildx (standalone: %p)',
async (version, standalone) => {
const buildxBin = await buildx.install(version, tmpDir, standalone);
expect(fs.existsSync(buildxBin)).toBe(true);
},
100000
);
});
describe('getConfig', () => {
test.each([
['debug = true', false, 'debug = true', false],
[`notfound.toml`, true, '', true],
[
`${path.join(__dirname, 'fixtures', 'buildkitd.toml').split(path.sep).join(path.posix.sep)}`,
true,
`debug = true
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
`,
false
]
])('given %p config', async (val, file, exValue, invalid) => {
try {
let config: string;
if (file) {
config = await buildx.getConfigFile(val);
} else {
config = await buildx.getConfigInline(val);
}
expect(true).toBe(!invalid);
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
expect(true).toBe(invalid);
}
});
});

View File

@ -1,23 +1,19 @@
import {beforeEach, describe, expect, it, jest, test} from '@jest/globals'; import {beforeEach, describe, expect, 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 uuid from 'uuid';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Node} from '@docker/actions-toolkit/lib/types/builder';
import * as context from '../src/context'; 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 => {
return tmpdir;
});
jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
return path.join(tmpdir, '.tmpname').split(path.sep).join(path.posix.sep);
});
jest.mock('uuid'); jest.mock('uuid');
jest.spyOn(uuid, 'v4').mockReturnValue('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'); jest.spyOn(uuid, 'v4').mockReturnValue('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d');
jest.spyOn(Docker, 'context').mockImplementation((): Promise<string> => {
return Promise.resolve('default');
});
describe('getCreateArgs', () => { describe('getCreateArgs', () => {
beforeEach(() => { beforeEach(() => {
process.env = Object.keys(process.env).reduce((object, key) => { process.env = Object.keys(process.env).reduce((object, key) => {
@ -32,9 +28,11 @@ describe('getCreateArgs', () => {
test.each([ test.each([
[ [
0, 0,
'v0.10.3',
new Map<string, string>([ new Map<string, string>([
['install', 'false'], ['install', 'false'],
['use', 'true'], ['use', 'true'],
['cleanup', 'true'],
]), ]),
[ [
'create', 'create',
@ -46,10 +44,12 @@ describe('getCreateArgs', () => {
], ],
[ [
1, 1,
'v0.10.3',
new Map<string, string>([ new Map<string, string>([
['driver', 'docker'], ['driver', 'docker'],
['install', 'false'], ['install', 'false'],
['use', 'true'], ['use', 'true'],
['cleanup', 'true'],
]), ]),
[ [
'create', 'create',
@ -61,10 +61,12 @@ describe('getCreateArgs', () => {
], ],
[ [
2, 2,
'v0.10.3',
new Map<string, string>([ new Map<string, string>([
['install', 'false'], ['install', 'false'],
['use', 'false'], ['use', 'false'],
['driver-opts', 'image=moby/buildkit:master\nnetwork=host'], ['driver-opts', 'image=moby/buildkit:master\nnetwork=host'],
['cleanup', 'true'],
]), ]),
[ [
'create', 'create',
@ -77,11 +79,13 @@ describe('getCreateArgs', () => {
], ],
[ [
3, 3,
'v0.10.3',
new Map<string, string>([ new Map<string, string>([
['driver', 'remote'], ['driver', 'remote'],
['endpoint', 'tls://foo:1234'], ['endpoint', 'tls://foo:1234'],
['install', 'false'], ['install', 'false'],
['use', 'true'], ['use', 'true'],
['cleanup', 'true'],
]), ]),
[ [
'create', 'create',
@ -93,12 +97,14 @@ describe('getCreateArgs', () => {
], ],
[ [
4, 4,
'v0.10.3',
new Map<string, string>([ new Map<string, string>([
['driver', 'remote'], ['driver', 'remote'],
['platforms', 'linux/arm64,linux/arm/v7'], ['platforms', 'linux/arm64,linux/arm/v7'],
['endpoint', 'tls://foo:1234'], ['endpoint', 'tls://foo:1234'],
['install', 'false'], ['install', 'false'],
['use', 'true'], ['use', 'true'],
['cleanup', 'true'],
]), ]),
[ [
'create', 'create',
@ -111,10 +117,12 @@ describe('getCreateArgs', () => {
], ],
[ [
5, 5,
'v0.10.3',
new Map<string, string>([ new Map<string, string>([
['install', 'false'], ['install', 'false'],
['use', 'false'], ['use', 'false'],
['driver-opts', `"env.no_proxy=localhost,127.0.0.1,.mydomain"`], ['driver-opts', `"env.no_proxy=localhost,127.0.0.1,.mydomain"`],
['cleanup', 'true'],
]), ]),
[ [
'create', 'create',
@ -126,10 +134,12 @@ describe('getCreateArgs', () => {
], ],
[ [
6, 6,
'v0.10.3',
new Map<string, string>([ new Map<string, string>([
['install', 'false'], ['install', 'false'],
['use', 'false'], ['use', 'false'],
['platforms', 'linux/amd64\n"linux/arm64,linux/arm/v7"'], ['platforms', 'linux/amd64\n"linux/arm64,linux/arm/v7"'],
['cleanup', 'true'],
]), ]),
[ [
'create', 'create',
@ -139,14 +149,33 @@ describe('getCreateArgs', () => {
'--platform', 'linux/amd64,linux/arm64,linux/arm/v7' '--platform', 'linux/amd64,linux/arm64,linux/arm/v7'
] ]
], ],
[
7,
'v0.10.3',
new Map<string, string>([
['install', 'false'],
['use', 'false'],
['driver', 'unknown'],
['cleanup', 'true'],
]),
[
'create',
'--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
'--driver', 'unknown',
]
]
])( ])(
'[%d] given %p as inputs, returns %p', '[%d] given buildx %s and %p as inputs, returns %p',
async (num: number, inputs: Map<string, string>, expected: Array<string>) => { async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {
inputs.forEach((value: string, name: string) => { inputs.forEach((value: string, name: string) => {
setInput(name, value); setInput(name, value);
}); });
const toolkit = new Toolkit();
jest.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => {
return buildxVersion;
});
const inp = await context.getInputs(); const inp = await context.getInputs();
const res = await context.getCreateArgs(inp, '0.9.0'); const res = await context.getCreateArgs(inp, toolkit);
expect(res).toEqual(expected); expect(res).toEqual(expected);
} }
); );
@ -166,9 +195,11 @@ describe('getAppendArgs', () => {
test.each([ test.each([
[ [
0, 0,
'v0.10.3',
new Map<string, string>([ new Map<string, string>([
['install', 'false'], ['install', 'false'],
['use', 'true'], ['use', 'true'],
['cleanup', 'true'],
]), ]),
{ {
"name": "aws_graviton2", "name": "aws_graviton2",
@ -191,87 +222,22 @@ describe('getAppendArgs', () => {
] ]
] ]
])( ])(
'[%d] given %p as inputs, returns %p', '[%d] given buildx %s and %p as inputs, returns %p',
async (num: number, inputs: Map<string, string>, node: nodes.Node, expected: Array<string>) => { async (num: number, buildxVersion: string, inputs: Map<string, string>, node: Node, expected: Array<string>) => {
inputs.forEach((value: string, name: string) => { inputs.forEach((value: string, name: string) => {
setInput(name, value); setInput(name, value);
}); });
const toolkit = new Toolkit();
jest.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => {
return buildxVersion;
});
const inp = await context.getInputs(); const inp = await context.getInputs();
const res = await context.getAppendArgs(inp, node, '0.9.0'); const res = await context.getAppendArgs(inp, node, toolkit);
expect(res).toEqual(expected); expect(res).toEqual(expected);
} }
); );
}); });
describe('getInputList', () => {
it('handles single line correctly', async () => {
await setInput('foo', 'bar');
const res = await context.getInputList('foo');
expect(res).toEqual(['bar']);
});
it('handles multiple lines correctly', async () => {
setInput('foo', 'bar\nbaz');
const res = await context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});
it('remove empty lines correctly', async () => {
setInput('foo', 'bar\n\nbaz');
const res = await context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});
it('handles comma correctly', async () => {
setInput('foo', 'bar,baz');
const res = await context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});
it('remove empty result correctly', async () => {
setInput('foo', 'bar,baz,');
const res = await context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});
it('handles different new lines correctly', async () => {
setInput('foo', 'bar\r\nbaz');
const res = await context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});
it('handles different new lines and comma correctly', async () => {
setInput('foo', 'bar\r\nbaz,bat');
const res = await context.getInputList('foo');
expect(res).toEqual(['bar', 'baz', 'bat']);
});
it('handles multiple lines and ignoring comma correctly', async () => {
setInput('driver-opts', 'image=moby/buildkit:master\nnetwork=host');
const res = await context.getInputList('driver-opts', true);
expect(res).toEqual(['image=moby/buildkit:master', 'network=host']);
});
it('handles different new lines and ignoring comma correctly', async () => {
setInput('driver-opts', 'image=moby/buildkit:master\r\nnetwork=host');
const res = await context.getInputList('driver-opts', true);
expect(res).toEqual(['image=moby/buildkit:master', 'network=host']);
});
});
describe('asyncForEach', () => {
it('executes async tasks sequentially', async () => {
const testValues = [1, 2, 3, 4, 5];
const results: number[] = [];
await context.asyncForEach(testValues, async value => {
results.push(value);
});
expect(results).toEqual(testValues);
});
});
// See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67 // See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67
function getInputName(name: string): string { function getInputName(name: string): string {
return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`; return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;

View File

@ -1,16 +0,0 @@
import {describe, expect, it, jest} from '@jest/globals';
import * as docker from '../src/docker';
import * as exec from '@actions/exec';
describe('isAvailable', () => {
it('cli', () => {
const execSpy = jest.spyOn(exec, 'getExecOutput');
docker.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`docker`, undefined, {
silent: true,
ignoreReturnCode: true
});
});
});

View File

@ -1,3 +0,0 @@
debug = true
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]

View File

@ -1,10 +0,0 @@
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

@ -1,11 +0,0 @@
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

@ -1,11 +0,0 @@
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

@ -1,9 +0,0 @@
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

@ -1,9 +0,0 @@
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

@ -1,9 +0,0 @@
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,9 +0,0 @@
import {describe, expect, it} from '@jest/globals';
import * as git from '../src/git';
describe('git', () => {
it('returns git remote ref', async () => {
const ref: string = await git.getRemoteSha('https://github.com/docker/buildx.git', 'refs/pull/648/head');
expect(ref).toEqual('f11797113e5a9b86bd976329c5dbb8a8bfdfadfa');
});
});

View File

@ -1,12 +0,0 @@
import {describe, expect, test} from '@jest/globals';
import * as util from '../src/util';
describe('isValidUrl', () => {
test.each([
['https://github.com/docker/buildx.git', true],
['https://github.com/docker/buildx.git#refs/pull/648/head', true],
['v0.4.1', false]
])('given %p', async (url, expected) => {
expect(util.isValidUrl(url)).toEqual(expected);
});
});

View File

@ -44,6 +44,10 @@ inputs:
append: append:
description: 'Append additional nodes to the builder' description: 'Append additional nodes to the builder'
required: false required: false
cleanup:
description: 'Cleanup temp files and remove builder at the end of a job'
default: 'true'
required: false
outputs: outputs:
name: name:

View File

@ -71,6 +71,7 @@ ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
RUN --mount=type=bind,target=.,rw \ RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \ --mount=type=cache,target=/src/node_modules \
--mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \ --mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
--mount=type=bind,from=buildx,source=/buildx,target=/usr/bin/buildx \
--mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \ --mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \
yarn run test --coverageDirectory=/tmp/coverage yarn run test --coverageDirectory=/tmp/coverage

24
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

1259
dist/licenses.txt generated vendored

File diff suppressed because it is too large Load Diff

2
dist/sourcemap-register.js generated vendored

File diff suppressed because one or more lines are too long

View File

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

View File

@ -1,7 +1,21 @@
import fs from 'fs';
import os from 'os';
import path from 'path';
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-action-')).split(path.sep).join(path.posix.sep);
process.env = Object.assign({}, process.env, {
TEMP: tmpDir,
GITHUB_REPOSITORY: 'docker/setup-buildx-action',
RUNNER_TEMP: path.join(tmpDir, 'runner-temp').split(path.sep).join(path.posix.sep),
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache').split(path.sep).join(path.posix.sep)
}) as {
[key: string]: string;
};
module.exports = { module.exports = {
clearMocks: true, clearMocks: true,
moduleFileExtensions: ['js', 'ts'], moduleFileExtensions: ['js', 'ts'],
setupFiles: ['dotenv/config'],
testMatch: ['**/*.test.ts'], testMatch: ['**/*.test.ts'],
transform: { transform: {
'^.+\\.ts$': 'ts-jest' '^.+\\.ts$': 'ts-jest'
@ -9,5 +23,7 @@ module.exports = {
moduleNameMapper: { moduleNameMapper: {
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs' '^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
}, },
collectCoverageFrom: ['src/**/{!(main.ts),}.ts'],
coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__tests__/'],
verbose: true verbose: true
}; };

View File

@ -29,30 +29,23 @@
"dependencies": { "dependencies": {
"@actions/core": "^1.10.0", "@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1", "@actions/exec": "^1.1.1",
"@actions/tool-cache": "^2.0.1", "@docker/actions-toolkit": "^0.10.0",
"@docker/actions-toolkit": "^0.1.0-beta.4",
"csv-parse": "^5.3.4",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"semver": "^7.3.7",
"tmp": "^0.2.1",
"uuid": "^9.0.0" "uuid": "^9.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^16.11.26", "@types/node": "^16.18.21",
"@types/semver": "^7.3.9", "@typescript-eslint/eslint-plugin": "^5.56.0",
"@types/tmp": "^0.2.3", "@typescript-eslint/parser": "^5.56.0",
"@typescript-eslint/eslint-plugin": "^5.14.0", "@vercel/ncc": "^0.36.1",
"@typescript-eslint/parser": "^5.14.0", "eslint": "^8.36.0",
"@vercel/ncc": "^0.33.3", "eslint-config-prettier": "^8.8.0",
"dotenv": "^16.0.0", "eslint-plugin-jest": "^27.2.1",
"eslint": "^8.11.0", "eslint-plugin-prettier": "^4.2.1",
"eslint-config-prettier": "^8.5.0", "jest": "^29.5.0",
"eslint-plugin-jest": "^26.1.1", "prettier": "^2.8.7",
"eslint-plugin-prettier": "^4.0.0", "ts-jest": "^29.0.5",
"jest": "^27.2.5", "ts-node": "^10.9.1",
"prettier": "^2.3.1", "typescript": "^4.9.5"
"ts-jest": "^27.1.2",
"ts-node": "^10.7.0",
"typescript": "^4.4.4"
} }
} }

View File

@ -1,51 +0,0 @@
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

@ -1,376 +0,0 @@
import * as fs from 'fs';
import * as path from 'path';
import * as semver from 'semver';
import * as util from 'util';
import * as context from './context';
import * as git from './git';
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as tc from '@actions/tool-cache';
import {Install as BuildxInstall} from '@docker/actions-toolkit/lib/buildx/install';
import {GitHubRelease} from '@docker/actions-toolkit/lib/types/github';
export type Builder = {
name?: string;
driver?: string;
nodes: Node[];
};
export type Node = {
name?: string;
endpoint?: string;
'driver-opts'?: Array<string>;
status?: string;
'buildkitd-flags'?: string;
buildkit?: string;
platforms?: string;
};
export async function getConfigInline(s: string): Promise<string> {
return getConfig(s, false);
}
export async function getConfigFile(s: string): Promise<string> {
return getConfig(s, true);
}
export async function getConfig(s: string, file: boolean): Promise<string> {
if (file) {
if (!fs.existsSync(s)) {
throw new Error(`config file ${s} not found`);
}
s = fs.readFileSync(s, {encoding: 'utf-8'});
}
const configFile = context.tmpNameSync({
tmpdir: context.tmpDir()
});
fs.writeFileSync(configFile, s);
return configFile;
}
export async function isAvailable(standalone?: boolean): Promise<boolean> {
const cmd = getCommand([], standalone);
return await exec
.getExecOutput(cmd.commandLine, cmd.args, {
ignoreReturnCode: true,
silent: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
return false;
}
return res.exitCode == 0;
})
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.catch(error => {
return false;
});
}
export async function getVersion(standalone?: boolean): Promise<string> {
const cmd = getCommand(['version'], standalone);
return await exec
.getExecOutput(cmd.commandLine, cmd.args, {
ignoreReturnCode: true,
silent: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
return parseVersion(res.stdout.trim());
});
}
export function parseVersion(stdout: string): string {
const matches = /\sv?([0-9a-f]{7}|[0-9.]+)/.exec(stdout);
if (!matches) {
throw new Error(`Cannot parse buildx version`);
}
return matches[1];
}
export function satisfies(version: string, range: string): boolean {
return semver.satisfies(version, range) || /^[0-9a-f]{7}$/.exec(version) !== null;
}
export async function inspect(name: string, standalone?: boolean): Promise<Builder> {
const cmd = getCommand(['inspect', name], standalone);
return await exec
.getExecOutput(cmd.commandLine, cmd.args, {
ignoreReturnCode: true,
silent: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
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('#');
if (ref.length == 0) {
ref = 'master';
}
let vspec: string;
if (ref.match(/^[0-9a-fA-F]{40}$/)) {
vspec = ref;
} else {
vspec = await git.getRemoteSha(repo, ref);
}
core.debug(`Tool version spec ${vspec}`);
let toolPath: string;
toolPath = tc.find('buildx', vspec);
if (!toolPath) {
const outFolder = path.join(context.tmpDir(), 'out').split(path.sep).join(path.posix.sep);
let buildWithStandalone = false;
const standaloneFound = await isAvailable(true);
const pluginFound = await isAvailable(false);
if (standalone && standaloneFound) {
core.debug(`Buildx standalone found, build with it`);
buildWithStandalone = true;
} else if (!standalone && pluginFound) {
core.debug(`Buildx plugin found, build with it`);
buildWithStandalone = false;
} else if (standaloneFound) {
core.debug(`Buildx plugin not found, but standalone found so trying to build with it`);
buildWithStandalone = true;
} else if (pluginFound) {
core.debug(`Buildx standalone not found, but plugin found so trying to build with it`);
buildWithStandalone = false;
} else {
throw new Error(`Neither buildx standalone or plugin have been found to build from ref`);
}
const buildCmd = getCommand(['build', '--target', 'binaries', '--build-arg', 'BUILDKIT_CONTEXT_KEEP_GIT_DIR=1', '--output', `type=local,dest=${outFolder}`, inputBuildRef], buildWithStandalone);
toolPath = await exec
.getExecOutput(buildCmd.commandLine, buildCmd.args, {
ignoreReturnCode: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
core.warning(res.stderr.trim());
}
return tc.cacheFile(`${outFolder}/buildx`, context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx', 'buildx', vspec);
});
}
if (standalone) {
return setStandalone(toolPath, dest);
}
return setPlugin(toolPath, dest);
}
export async function install(inputVersion: string, dest: string, standalone: boolean): Promise<string> {
const release: GitHubRelease = await BuildxInstall.getRelease(inputVersion);
core.debug(`Release ${release.tag_name} found`);
const version = release.tag_name.replace(/^v+|v+$/g, '');
let toolPath: string;
toolPath = tc.find('buildx', version);
if (!toolPath) {
const c = semver.clean(version) || '';
if (!semver.valid(c)) {
throw new Error(`Invalid Buildx version "${version}".`);
}
toolPath = await download(version);
}
if (standalone) {
return setStandalone(toolPath, dest);
}
return setPlugin(toolPath, dest);
}
async function setStandalone(toolPath: string, dest: string): Promise<string> {
core.info('Standalone mode');
const toolBinPath = path.join(toolPath, context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx');
const binDir = path.join(dest, 'bin');
core.debug(`Bin dir is ${binDir}`);
if (!fs.existsSync(binDir)) {
fs.mkdirSync(binDir, {recursive: true});
}
const filename: string = context.osPlat == 'win32' ? 'buildx.exe' : 'buildx';
const buildxPath: string = path.join(binDir, filename);
core.debug(`Bin path is ${buildxPath}`);
fs.copyFileSync(toolBinPath, buildxPath);
core.info('Fixing perms');
fs.chmodSync(buildxPath, '0755');
core.addPath(binDir);
core.info('Added buildx to the path');
return buildxPath;
}
async function setPlugin(toolPath: string, dockerConfigHome: string): Promise<string> {
core.info('Docker plugin mode');
const toolBinPath = path.join(toolPath, context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx');
const pluginsDir: string = path.join(dockerConfigHome, 'cli-plugins');
core.debug(`Plugins dir is ${pluginsDir}`);
if (!fs.existsSync(pluginsDir)) {
fs.mkdirSync(pluginsDir, {recursive: true});
}
const filename: string = context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx';
const pluginPath: string = path.join(pluginsDir, filename);
core.debug(`Plugin path is ${pluginPath}`);
fs.copyFileSync(toolBinPath, pluginPath);
core.info('Fixing perms');
fs.chmodSync(pluginPath, '0755');
return pluginPath;
}
async function download(version: string): Promise<string> {
const targetFile: string = context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx';
const downloadUrl = util.format('https://github.com/docker/buildx/releases/download/v%s/%s', version, await filename(version));
core.info(`Downloading ${downloadUrl}`);
const downloadPath = await tc.downloadTool(downloadUrl);
core.debug(`Downloaded to ${downloadPath}`);
return await tc.cacheFile(downloadPath, targetFile, 'buildx', version);
}
async function filename(version: string): Promise<string> {
let arch: string;
switch (context.osArch) {
case 'x64': {
arch = 'amd64';
break;
}
case 'ppc64': {
arch = 'ppc64le';
break;
}
case 'arm': {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const arm_version = (process.config.variables as any).arm_version;
arch = arm_version ? 'arm-v' + arm_version : 'arm';
break;
}
default: {
arch = context.osArch;
break;
}
}
const platform: string = context.osPlat == 'win32' ? 'windows' : context.osPlat;
const ext: string = context.osPlat == 'win32' ? '.exe' : '';
return util.format('buildx-v%s.%s-%s%s', version, platform, arch, ext);
}
export async function getBuildKitVersion(containerID: string): Promise<string> {
return exec
.getExecOutput(`docker`, ['inspect', '--format', '{{.Config.Image}}', containerID], {
ignoreReturnCode: true,
silent: true
})
.then(bkitimage => {
if (bkitimage.exitCode == 0 && bkitimage.stdout.length > 0) {
return exec
.getExecOutput(`docker`, ['run', '--rm', bkitimage.stdout.trim(), '--version'], {
ignoreReturnCode: true,
silent: true
})
.then(bkitversion => {
if (bkitversion.exitCode == 0 && bkitversion.stdout.length > 0) {
return `${bkitimage.stdout.trim()} => ${bkitversion.stdout.trim()}`;
} else if (bkitversion.stderr.length > 0) {
core.warning(bkitversion.stderr.trim());
}
return bkitversion.stdout.trim();
});
} else if (bkitimage.stderr.length > 0) {
core.warning(bkitimage.stderr.trim());
}
return bkitimage.stdout.trim();
});
}
export function getCommand(args: Array<string>, standalone?: boolean) {
return {
commandLine: standalone ? 'buildx' : 'docker',
args: standalone ? args : ['buildx', ...args]
};
}

View File

@ -1,27 +1,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 * 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 * as core from '@actions/core';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Util} from '@docker/actions-toolkit/lib/util';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Node} from '@docker/actions-toolkit/lib/types/builder';
let _tmpDir: string; export const builderNodeEnvPrefix = 'BUILDER_NODE';
export const osPlat: string = os.platform();
export const osArch: string = os.arch();
export function tmpDir(): string {
if (!_tmpDir) {
_tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-')).split(path.sep).join(path.posix.sep);
}
return _tmpDir;
}
export function tmpNameSync(options?: tmp.TmpNameOptions): string {
return tmp.tmpNameSync(options);
}
export interface Inputs { export interface Inputs {
version: string; version: string;
@ -36,36 +20,38 @@ export interface Inputs {
config: string; config: string;
configInline: string; configInline: string;
append: string; append: string;
cleanup: boolean;
} }
export async function getInputs(): Promise<Inputs> { export async function getInputs(): Promise<Inputs> {
return { return {
version: core.getInput('version'), version: core.getInput('version'),
name: getBuilderName(core.getInput('driver') || 'docker-container'), name: await getBuilderName(core.getInput('driver') || 'docker-container'),
driver: core.getInput('driver') || 'docker-container', driver: core.getInput('driver') || 'docker-container',
driverOpts: await getInputList('driver-opts', true), driverOpts: Util.getInputList('driver-opts', {ignoreComma: true, quote: false}),
buildkitdFlags: core.getInput('buildkitd-flags') || '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', buildkitdFlags: core.getInput('buildkitd-flags') || '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
platforms: await getInputList('platforms', false, true), platforms: Util.getInputList('platforms'),
install: core.getBooleanInput('install'), install: core.getBooleanInput('install'),
use: core.getBooleanInput('use'), use: core.getBooleanInput('use'),
endpoint: core.getInput('endpoint'), endpoint: core.getInput('endpoint'),
config: core.getInput('config'), config: core.getInput('config'),
configInline: core.getInput('config-inline'), configInline: core.getInput('config-inline'),
append: core.getInput('append') append: core.getInput('append'),
cleanup: core.getBooleanInput('cleanup')
}; };
} }
export function getBuilderName(driver: string): string { export async function getBuilderName(driver: string): Promise<string> {
return driver == 'docker' ? 'default' : `builder-${uuid.v4()}`; return driver == 'docker' ? await Docker.context() : `builder-${uuid.v4()}`;
} }
export async function getCreateArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> { export async function getCreateArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
const args: Array<string> = ['create', '--name', inputs.name, '--driver', inputs.driver]; const args: Array<string> = ['create', '--name', inputs.name, '--driver', inputs.driver];
if (buildx.satisfies(buildxVersion, '>=0.3.0')) { if (await toolkit.buildx.versionSatisfies('>=0.3.0')) {
await asyncForEach(inputs.driverOpts, async driverOpt => { await Util.asyncForEach(inputs.driverOpts, async driverOpt => {
args.push('--driver-opt', driverOpt); args.push('--driver-opt', driverOpt);
}); });
if (inputs.driver != 'remote' && inputs.buildkitdFlags) { if (driverSupportsFlags(inputs.driver) && inputs.buildkitdFlags) {
args.push('--buildkitd-flags', inputs.buildkitdFlags); args.push('--buildkitd-flags', inputs.buildkitdFlags);
} }
} }
@ -75,11 +61,11 @@ export async function getCreateArgs(inputs: Inputs, buildxVersion: string): Prom
if (inputs.use) { if (inputs.use) {
args.push('--use'); args.push('--use');
} }
if (inputs.driver != 'remote') { if (driverSupportsFlags(inputs.driver)) {
if (inputs.config) { if (inputs.config) {
args.push('--config', await buildx.getConfigFile(inputs.config)); args.push('--config', toolkit.buildkit.config.resolveFromFile(inputs.config));
} else if (inputs.configInline) { } else if (inputs.configInline) {
args.push('--config', await buildx.getConfigInline(inputs.configInline)); args.push('--config', toolkit.buildkit.config.resolveFromString(inputs.configInline));
} }
} }
if (inputs.endpoint) { if (inputs.endpoint) {
@ -88,16 +74,18 @@ export async function getCreateArgs(inputs: Inputs, buildxVersion: string): Prom
return args; return args;
} }
export async function getAppendArgs(inputs: Inputs, node: nodes.Node, buildxVersion: string): Promise<Array<string>> { export async function getAppendArgs(inputs: Inputs, node: Node, toolkit: Toolkit): Promise<Array<string>> {
const args: Array<string> = ['create', '--name', inputs.name, '--append']; const args: Array<string> = ['create', '--name', inputs.name, '--append'];
if (node.name) { if (node.name) {
args.push('--node', node.name); args.push('--node', node.name);
} else if (inputs.driver == 'kubernetes' && (await toolkit.buildx.versionSatisfies('<0.11.0'))) {
args.push('--node', `node-${uuid.v4()}`);
} }
if (node['driver-opts'] && buildx.satisfies(buildxVersion, '>=0.3.0')) { if (node['driver-opts'] && (await toolkit.buildx.versionSatisfies('>=0.3.0'))) {
await asyncForEach(node['driver-opts'], async driverOpt => { await Util.asyncForEach(node['driver-opts'], async driverOpt => {
args.push('--driver-opt', driverOpt); args.push('--driver-opt', driverOpt);
}); });
if (inputs.driver != 'remote' && node['buildkitd-flags']) { if (driverSupportsFlags(inputs.driver) && node['buildkitd-flags']) {
args.push('--buildkitd-flags', node['buildkitd-flags']); args.push('--buildkitd-flags', node['buildkitd-flags']);
} }
} }
@ -110,47 +98,14 @@ export async function getAppendArgs(inputs: Inputs, node: nodes.Node, buildxVers
return args; return args;
} }
export async function getInspectArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> { export async function getInspectArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
const args: Array<string> = ['inspect', '--bootstrap']; const args: Array<string> = ['inspect', '--bootstrap'];
if (buildx.satisfies(buildxVersion, '>=0.4.0')) { if (await toolkit.buildx.versionSatisfies('>=0.4.0')) {
args.push('--builder', inputs.name); args.push('--builder', inputs.name);
} }
return args; return args;
} }
export async function getInputList(name: string, ignoreComma?: boolean, escapeQuotes?: boolean): Promise<string[]> { function driverSupportsFlags(driver: string): boolean {
const res: Array<string> = []; return driver == '' || driver == 'docker-container' || driver == 'docker' || driver == 'kubernetes';
const items = core.getInput(name);
if (items == '') {
return res;
}
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) => {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
};

View File

@ -1,19 +0,0 @@
import * as exec from '@actions/exec';
export async function isAvailable(): Promise<boolean> {
return await exec
.getExecOutput('docker', undefined, {
ignoreReturnCode: true,
silent: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
return false;
}
return res.exitCode == 0;
})
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.catch(error => {
return false;
});
}

View File

@ -1,19 +0,0 @@
import * as exec from '@actions/exec';
export async function getRemoteSha(repo: string, ref: string): Promise<string> {
return await exec
.getExecOutput(`git`, ['ls-remote', repo, ref], {
ignoreReturnCode: true,
silent: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr);
}
const [rsha] = res.stdout.trim().split(/[\s\t]/);
if (rsha.length == 0) {
throw new Error(`Cannot find remote ref for ${repo}#${ref}`);
}
return rsha;
});
}

View File

@ -1,182 +1,201 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as os from 'os'; import * as yaml from 'js-yaml';
import * as path from 'path';
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'; import * as core from '@actions/core';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import * as actionsToolkit from '@docker/actions-toolkit';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
import {Builder} from '@docker/actions-toolkit/lib/buildx/builder';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Util} from '@docker/actions-toolkit/lib/util';
import {Node} from '@docker/actions-toolkit/lib/types/builder';
async function run(): Promise<void> { import * as context from './context';
try { import * as stateHelper from './state-helper';
actionsToolkit.run(
// main
async () => {
const inputs: context.Inputs = await context.getInputs(); const inputs: context.Inputs = await context.getInputs();
const dockerConfigHome: string = process.env.DOCKER_CONFIG || path.join(os.homedir(), '.docker'); stateHelper.setCleanup(inputs.cleanup);
// standalone if docker cli not available const toolkit = new Toolkit();
const standalone = !(await docker.isAvailable()); const standalone = await toolkit.buildx.isStandalone();
stateHelper.setStandalone(standalone); stateHelper.setStandalone(standalone);
core.startGroup(`Docker info`); await core.group(`Docker info`, async () => {
if (standalone) { try {
core.info(`Docker info skipped in standalone mode`); await Docker.printVersion();
} else { await Docker.printInfo();
await exec.exec('docker', ['version'], { } catch (e) {
failOnStdErr: false core.info(e.message);
}); }
await exec.exec('docker', ['info'], { });
failOnStdErr: false
});
}
core.endGroup();
if (util.isValidUrl(inputs.version)) { let toolPath;
if (Util.isValidRef(inputs.version)) {
if (standalone) { if (standalone) {
throw new Error(`Cannot build from source without the Docker CLI`); throw new Error(`Cannot build from source without the Docker CLI`);
} }
core.startGroup(`Build and install buildx`); await core.group(`Build buildx from source`, async () => {
await buildx.build(inputs.version, dockerConfigHome, standalone); toolPath = await toolkit.buildxInstall.build(inputs.version);
core.endGroup(); });
} else if (!(await buildx.isAvailable(standalone)) || inputs.version) { } else if (!(await toolkit.buildx.isAvailable()) || inputs.version) {
core.startGroup(`Download and install buildx`); await core.group(`Download buildx from GitHub Releases`, async () => {
await buildx.install(inputs.version || 'latest', standalone ? context.tmpDir() : dockerConfigHome, standalone); toolPath = await toolkit.buildxInstall.download(inputs.version || 'latest');
core.endGroup(); });
}
if (toolPath) {
await core.group(`Install buildx`, async () => {
if (standalone) {
await toolkit.buildxInstall.installStandalone(toolPath);
} else {
await toolkit.buildxInstall.installPlugin(toolPath);
}
});
} }
const buildxVersion = await buildx.getVersion(standalone);
await core.group(`Buildx version`, async () => { await core.group(`Buildx version`, async () => {
const versionCmd = buildx.getCommand(['version'], standalone); await toolkit.buildx.printVersion();
await exec.exec(versionCmd.commandLine, versionCmd.args, {
failOnStdErr: false
});
}); });
core.setOutput('name', inputs.name); core.setOutput('name', inputs.name);
stateHelper.setBuilderName(inputs.name); stateHelper.setBuilderName(inputs.name);
stateHelper.setBuilderDriver(inputs.driver);
const credsdir = path.join(dockerConfigHome, 'buildx', 'creds', inputs.name); fs.mkdirSync(Buildx.certsDir, {recursive: true});
fs.mkdirSync(credsdir, {recursive: true}); stateHelper.setCertsDir(Buildx.certsDir);
stateHelper.setCredsDir(credsdir);
if (inputs.driver !== 'docker') { if (inputs.driver !== 'docker') {
core.startGroup(`Creating a new builder instance`); await core.group(`Creating a new builder instance`, async () => {
const authOpts = auth.setCredentials(credsdir, 0, inputs.driver, inputs.endpoint); const certsDriverOpts = Buildx.resolveCertsDriverOpts(inputs.driver, inputs.endpoint, {
if (authOpts.length > 0) { cacert: process.env[`${context.builderNodeEnvPrefix}_0_AUTH_TLS_CACERT`],
inputs.driverOpts = [...inputs.driverOpts, ...authOpts]; cert: process.env[`${context.builderNodeEnvPrefix}_0_AUTH_TLS_CERT`],
} key: process.env[`${context.builderNodeEnvPrefix}_0_AUTH_TLS_KEY`]
const createCmd = buildx.getCommand(await context.getCreateArgs(inputs, buildxVersion), standalone); });
await exec.exec(createCmd.commandLine, createCmd.args); if (certsDriverOpts.length > 0) {
core.endGroup(); inputs.driverOpts = [...inputs.driverOpts, ...certsDriverOpts];
}
const createCmd = await toolkit.buildx.getCommand(await context.getCreateArgs(inputs, toolkit));
await exec.exec(createCmd.command, createCmd.args);
});
} }
if (inputs.append) { if (inputs.append) {
core.startGroup(`Appending node(s) to builder`); await core.group(`Appending node(s) to builder`, async () => {
let nodeIndex = 1; let nodeIndex = 1;
for (const node of nodes.Parse(inputs.append)) { const nodes = yaml.load(inputs.append) as Node[];
const authOpts = auth.setCredentials(credsdir, nodeIndex, inputs.driver, node.endpoint || ''); for (const node of nodes) {
if (authOpts.length > 0) { const certsDriverOpts = Buildx.resolveCertsDriverOpts(inputs.driver, `${node.endpoint}`, {
node['driver-opts'] = [...(node['driver-opts'] || []), ...authOpts]; cacert: process.env[`${context.builderNodeEnvPrefix}_${nodeIndex}_AUTH_TLS_CACERT`],
cert: process.env[`${context.builderNodeEnvPrefix}_${nodeIndex}_AUTH_TLS_CERT`],
key: process.env[`${context.builderNodeEnvPrefix}_${nodeIndex}_AUTH_TLS_KEY`]
});
if (certsDriverOpts.length > 0) {
node['driver-opts'] = [...(node['driver-opts'] || []), ...certsDriverOpts];
}
const appendCmd = await toolkit.buildx.getCommand(await context.getAppendArgs(inputs, node, toolkit));
await exec.exec(appendCmd.command, appendCmd.args);
nodeIndex++;
} }
const appendCmd = buildx.getCommand(await context.getAppendArgs(inputs, node, buildxVersion), standalone); });
await exec.exec(appendCmd.commandLine, appendCmd.args);
nodeIndex++;
}
core.endGroup();
} }
core.startGroup(`Booting builder`); await core.group(`Booting builder`, async () => {
const inspectCmd = buildx.getCommand(await context.getInspectArgs(inputs, buildxVersion), standalone); const inspectCmd = await toolkit.buildx.getCommand(await context.getInspectArgs(inputs, toolkit));
await exec.exec(inspectCmd.commandLine, inspectCmd.args); await exec.exec(inspectCmd.command, inspectCmd.args);
core.endGroup(); });
if (inputs.install) { if (inputs.install) {
if (standalone) { if (standalone) {
throw new Error(`Cannot set buildx as default builder without the Docker CLI`); throw new Error(`Cannot set buildx as default builder without the Docker CLI`);
} }
core.startGroup(`Setting buildx as default builder`); await core.group(`Setting buildx as default builder`, async () => {
await exec.exec('docker', ['buildx', 'install']); const installCmd = await toolkit.buildx.getCommand(['install']);
core.endGroup(); await exec.exec(installCmd.command, installCmd.args);
});
} }
core.startGroup(`Inspect builder`); const builderInspect = await toolkit.builder.inspect(inputs.name);
const builder = await buildx.inspect(inputs.name, standalone); const firstNode = builderInspect.nodes[0];
const firstNode = builder.nodes[0];
const reducedPlatforms: Array<string> = []; await core.group(`Inspect builder`, async () => {
for (const node of builder.nodes) { const reducedPlatforms: Array<string> = [];
for (const platform of node.platforms?.split(',') || []) { for (const node of builderInspect.nodes) {
if (reducedPlatforms.indexOf(platform) > -1) { for (const platform of node.platforms?.split(',') || []) {
continue; if (reducedPlatforms.indexOf(platform) > -1) {
continue;
}
reducedPlatforms.push(platform);
} }
reducedPlatforms.push(platform);
} }
} core.info(JSON.stringify(builderInspect, undefined, 2));
core.info(JSON.stringify(builder, undefined, 2)); core.setOutput('driver', builderInspect.driver);
core.setOutput('driver', builder.driver); core.setOutput('platforms', reducedPlatforms.join(','));
core.setOutput('platforms', reducedPlatforms.join(',')); core.setOutput('nodes', JSON.stringify(builderInspect.nodes, undefined, 2));
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('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('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.setOutput('flags', firstNode['buildkitd-flags']); // TODO: deprecated, to be removed in a later version });
core.endGroup();
if (!standalone && builder.driver == 'docker-container') { if (!standalone && builderInspect.driver == 'docker-container') {
stateHelper.setContainerName(`buildx_buildkit_${firstNode.name}`); stateHelper.setContainerName(`${Buildx.containerNamePrefix}${firstNode.name}`);
core.startGroup(`BuildKit version`); await core.group(`BuildKit version`, async () => {
for (const node of builder.nodes) { for (const node of builderInspect.nodes) {
const bkvers = await buildx.getBuildKitVersion(`buildx_buildkit_${node.name}`); const buildkitVersion = await toolkit.buildkit.getVersion(node);
core.info(`${node.name}: ${bkvers}`); core.info(`${node.name}: ${buildkitVersion}`);
} }
core.endGroup(); });
} }
if (core.isDebug() || firstNode['buildkitd-flags']?.includes('--debug')) { if (core.isDebug() || firstNode['buildkitd-flags']?.includes('--debug')) {
stateHelper.setDebug('true'); stateHelper.setDebug('true');
} }
} catch (error) { },
core.setFailed(error.message); // post
} async () => {
} if (stateHelper.IsDebug && stateHelper.containerName.length > 0) {
await core.group(`BuildKit container logs`, async () => {
await exec
.getExecOutput('docker', ['logs', `${stateHelper.containerName}`], {
ignoreReturnCode: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
core.warning(res.stderr.trim());
}
});
});
}
async function cleanup(): Promise<void> { if (!stateHelper.cleanup) {
if (stateHelper.IsDebug && stateHelper.containerName.length > 0) { return;
core.startGroup(`BuildKit container logs`); }
await exec
.getExecOutput('docker', ['logs', `${stateHelper.containerName}`], { if (stateHelper.builderDriver != 'docker' && stateHelper.builderName.length > 0) {
ignoreReturnCode: true await core.group(`Removing builder`, async () => {
}) const buildx = new Buildx({standalone: stateHelper.standalone});
.then(res => { const builder = new Builder({buildx: buildx});
if (res.stderr.length > 0 && res.exitCode != 0) { if (await builder.exists(stateHelper.builderName)) {
core.warning(res.stderr.trim()); const rmCmd = await buildx.getCommand(['rm', stateHelper.builderName]);
await exec
.getExecOutput(rmCmd.command, rmCmd.args, {
ignoreReturnCode: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
core.warning(res.stderr.trim());
}
});
} else {
core.info(`${stateHelper.builderName} does not exist`);
} }
}); });
core.endGroup(); }
}
if (stateHelper.builderName.length > 0) { if (stateHelper.certsDir.length > 0 && fs.existsSync(stateHelper.certsDir)) {
core.startGroup(`Removing builder`); await core.group(`Cleaning up certificates`, async () => {
const rmCmd = buildx.getCommand(['rm', stateHelper.builderName], /true/i.test(stateHelper.standalone)); fs.rmSync(stateHelper.certsDir, {recursive: true});
await exec
.getExecOutput(rmCmd.commandLine, rmCmd.args, {
ignoreReturnCode: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
core.warning(res.stderr.trim());
}
}); });
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) {
run();
} else {
cleanup();
}

View File

@ -1,13 +0,0 @@
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

@ -1,11 +1,12 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
export const IsPost = !!process.env['STATE_isPost'];
export const IsDebug = !!process.env['STATE_isDebug']; export const IsDebug = !!process.env['STATE_isDebug'];
export const standalone = process.env['STATE_standalone'] || ''; export const standalone = /true/i.test(process.env['STATE_standalone'] || '');
export const builderName = process.env['STATE_builderName'] || ''; export const builderName = process.env['STATE_builderName'] || '';
export const builderDriver = process.env['STATE_builderDriver'] || '';
export const containerName = process.env['STATE_containerName'] || ''; export const containerName = process.env['STATE_containerName'] || '';
export const credsDir = process.env['STATE_credsDir'] || ''; export const certsDir = process.env['STATE_certsDir'] || '';
export const cleanup = /true/i.test(process.env['STATE_cleanup'] || '');
export function setDebug(debug: string) { export function setDebug(debug: string) {
core.saveState('isDebug', debug); core.saveState('isDebug', debug);
@ -19,14 +20,18 @@ export function setBuilderName(builderName: string) {
core.saveState('builderName', builderName); core.saveState('builderName', builderName);
} }
export function setBuilderDriver(builderDriver: string) {
core.saveState('builderDriver', builderDriver);
}
export function setContainerName(containerName: string) { export function setContainerName(containerName: string) {
core.saveState('containerName', containerName); core.saveState('containerName', containerName);
} }
export function setCredsDir(credsDir: string) { export function setCertsDir(certsDir: string) {
core.saveState('credsDir', credsDir); core.saveState('certsDir', certsDir);
} }
if (!IsPost) { export function setCleanup(cleanup: boolean) {
core.saveState('isPost', 'true'); core.saveState('cleanup', cleanup);
} }

View File

@ -1,8 +0,0 @@
export function isValidUrl(url: string): boolean {
try {
new URL(url);
} catch (e) {
return false;
}
return true;
}

View File

@ -1,19 +1,21 @@
{ {
"compilerOptions": { "compilerOptions": {
"esModuleInterop": true,
"target": "es6", "target": "es6",
"module": "commonjs", "module": "commonjs",
"strict": true,
"newLine": "lf", "newLine": "lf",
"outDir": "./lib", "outDir": "./lib",
"rootDir": "./src", "rootDir": "./src",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": false, "noImplicitAny": false,
"resolveJsonModule": true,
"useUnknownInCatchVariables": false, "useUnknownInCatchVariables": false,
}, },
"exclude": [ "exclude": [
"./__tests__/**/*",
"./lib/**/*",
"node_modules", "node_modules",
"**/*.test.ts",
"jest.config.ts" "jest.config.ts"
] ]
} }

2616
yarn.lock

File diff suppressed because it is too large Load Diff