Compare commits
	
		
			58 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 8c0edbc76e | ||
|   | 1fb9cbdb32 | ||
|   | 693fdd6ca6 | ||
|   | fe4c1ac86d | ||
|   | c74574e6c8 | ||
|   | 2d0cf98781 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 5f1d4ea81f | ||
|   | 59b5ed6124 | ||
|   | bd61d52837 | ||
|   | f6efb5fcbb | ||
|   | 2dfca373f3 | ||
|   | 95cb08cb26 | ||
|   | eb5c2a6eea | ||
|   | 83612bea36 | ||
|   | 40fefd8a58 | ||
|   | 90a1e4619e | ||
|   | 5a9fc40575 | ||
|   | 6c48dad5f0 | ||
|   | 16c2ddbfa7 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 0fe8589bf4 | ||
|   | f3692cbe43 | ||
|   | 51ce2e7281 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 1759384a3b | ||
|   | d5234d6605 | ||
|   | ec8fe6a2ec | ||
|   | c6ec880f34 | ||
|   | 69d3837448 | ||
|   | aa0df6f73a | ||
|   | f0ad70c1de | ||
|   | 1a6cf9b6d7 | ||
|   | 1c2ad20e10 | ||
|   | f5bc16b105 | ||
|   | 86f43c11f1 | ||
|   | f385c9ed95 | ||
|   | 798ed00eea | ||
|   | bea6a01aa4 | ||
|   | 3a2cc9a001 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 7a18bafc06 | ||
|   | 312f67c662 | ||
|   | b8ba4729df | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | afe5b71b31 | ||
|   | 6f5431bef1 | ||
|   | da30c94fcd | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 718cf00a00 | ||
|   | c4fbfe3f62 | ||
|   | 449215757a | ||
|   | cafcc1d31f | ||
|   | 7560281ec7 | ||
|   | 9102fb725f | ||
|   | 43262924e3 | ||
|   | 455b065be4 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 26f93d2e65 | ||
|   | 91cb32d715 | ||
|   | 7085ac52c5 | ||
|   | dc7b9719a9 | ||
|   | f55bc08278 | ||
|   | aa877a9d36 | ||
|   | 130c56f342 | 
							
								
								
									
										125
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										125
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -30,9 +30,16 @@ jobs: | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: ./ | ||||
|         with: | ||||
|           version: ${{ matrix.buildx-version }} | ||||
|       - | ||||
|         name: Nodes output | ||||
|         run: | | ||||
|           cat << EOF | ||||
|           ${{ steps.buildx.outputs.nodes }} | ||||
|           EOF | ||||
|  | ||||
|   multi: | ||||
|     runs-on: ubuntu-latest | ||||
| @@ -90,7 +97,7 @@ jobs: | ||||
|           EOL | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v1 | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: ./ | ||||
| @@ -98,7 +105,7 @@ jobs: | ||||
|           buildkitd-flags: --debug | ||||
|       - | ||||
|         name: Build | ||||
|         uses: docker/build-push-action@v2 | ||||
|         uses: docker/build-push-action@v3 | ||||
|         with: | ||||
|           context: . | ||||
|           platforms: linux/amd64,linux/arm64,linux/ppc64le | ||||
| @@ -244,7 +251,7 @@ jobs: | ||||
|           config: /tmp/buildkitd.toml | ||||
|       - | ||||
|         name: Build | ||||
|         uses: docker/build-push-action@v2 | ||||
|         uses: docker/build-push-action@v3 | ||||
|         with: | ||||
|           context: . | ||||
|  | ||||
| @@ -271,7 +278,7 @@ jobs: | ||||
|               mirrors = ["mirror.gcr.io"] | ||||
|       - | ||||
|         name: Build | ||||
|         uses: docker/build-push-action@v2 | ||||
|         uses: docker/build-push-action@v3 | ||||
|         with: | ||||
|           context: . | ||||
|  | ||||
| @@ -293,14 +300,18 @@ jobs: | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v1 | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         with: | ||||
|           platforms: ${{ matrix.qemu-platforms }} | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: ./ | ||||
|         with: | ||||
|           version: ${{ matrix.buildx-version }} | ||||
|       - | ||||
|         name: List builder platforms | ||||
|         run: echo ${{ steps.buildx.outputs.platforms }} | ||||
|  | ||||
|   build-ref: | ||||
|     runs-on: ubuntu-latest | ||||
| @@ -333,14 +344,32 @@ jobs: | ||||
|         with: | ||||
|           context: . | ||||
|  | ||||
|   standalone: | ||||
|   standalone-cmd: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Uninstall docker cli | ||||
|         run: | | ||||
|           sudo apt-get purge -y moby-cli moby-buildx | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: ./ | ||||
|       - | ||||
|         name: Create Dockerfile | ||||
|         run: | | ||||
|           cat > ./Dockerfile <<EOL | ||||
|           FROM alpine | ||||
|           EOL | ||||
|       - | ||||
|         name: Build | ||||
|         run: | | ||||
|           buildx build . | ||||
|  | ||||
|   standalone-action: | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         buildx-version: | ||||
|           - latest | ||||
|           - "" | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
| @@ -355,10 +384,16 @@ jobs: | ||||
|         with: | ||||
|           version: ${{ matrix.buildx-version }} | ||||
|       - | ||||
|         name: Check available in path | ||||
|         if: matrix.standalone | ||||
|         name: Create Dockerfile | ||||
|         run: | | ||||
|           buildx version | ||||
|           cat > ./Dockerfile <<EOL | ||||
|           FROM alpine | ||||
|           EOL | ||||
|       - | ||||
|         name: Build | ||||
|         uses: docker/build-push-action@master | ||||
|         with: | ||||
|           context: . | ||||
|  | ||||
|   standalone-install-error: | ||||
|     runs-on: ubuntu-latest | ||||
| @@ -386,46 +421,46 @@ jobs: | ||||
|             exit 1 | ||||
|           fi | ||||
|  | ||||
|   standalone-kubernetes: | ||||
|   append: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Uninstall moby | ||||
|         name: Create dummy contexts | ||||
|         run: | | ||||
|           sudo apt-get purge -y moby-engine moby-cli moby-buildx | ||||
|           docker context create ctxbuilder2 | ||||
|           docker context create ctxbuilder3 | ||||
|       - | ||||
|         name: Setup k8s cluster | ||||
|         run: | | ||||
|           set -x | ||||
|           sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg | ||||
|           echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list | ||||
|           sudo apt-get update | ||||
|           sudo apt-get install -y kubelet kubeadm kubectl | ||||
|           sudo swapoff -a | ||||
|           sudo kubeadm init --cri-socket /run/containerd/containerd.sock | ||||
|           mkdir -p $HOME/.kube/ | ||||
|           sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config | ||||
|           sudo chown $USER $HOME/.kube/config | ||||
|           kubectl taint nodes --all node-role.kubernetes.io/master- | ||||
|           kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml | ||||
|           kubectl wait --for=condition=ready --timeout=30s node --all | ||||
|           kubectl get nodes -o wide | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: ./ | ||||
|         with: | ||||
|           append: | | ||||
|             - name: builder2 | ||||
|               endpoint: ctxbuilder2 | ||||
|               platforms: linux/amd64 | ||||
|               driver-opts: | ||||
|                 - image=moby/buildkit:master | ||||
|                 - network=host | ||||
|             - endpoint: ctxbuilder3 | ||||
|               platforms: linux/arm64 | ||||
|       - | ||||
|         name: Create Dockerfile | ||||
|         run: | | ||||
|           cat > ./Dockerfile <<EOL | ||||
|           FROM alpine | ||||
|           RUN echo hello | ||||
|           EOL | ||||
|         name: List builder platforms | ||||
|         run: echo ${{ steps.buildx.outputs.platforms }} | ||||
|  | ||||
|   platforms: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: ./ | ||||
|         with: | ||||
|           driver: kubernetes | ||||
|       - | ||||
|         name: Build | ||||
|         run: | | ||||
|           buildx build . | ||||
|           platforms: linux/amd64 | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @@ -19,7 +19,7 @@ jobs: | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Validate | ||||
|         uses: docker/bake-action@v1 | ||||
|         uses: docker/bake-action@v2 | ||||
|         with: | ||||
|           targets: validate | ||||
|       - | ||||
| @@ -27,7 +27,7 @@ jobs: | ||||
|         uses: ./ | ||||
|       - | ||||
|         name: Test | ||||
|         uses: docker/bake-action@v1 | ||||
|         uses: docker/bake-action@v2 | ||||
|         with: | ||||
|           targets: test | ||||
|       - | ||||
|   | ||||
							
								
								
									
										282
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										282
									
								
								README.md
									
									
									
									
									
								
							| @@ -8,35 +8,34 @@ | ||||
|  | ||||
| GitHub Action to set up Docker [Buildx](https://github.com/docker/buildx). | ||||
|  | ||||
| This action will create and boot a builder that can be used in the following steps of your workflow if you're using | ||||
| [buildx](https://github.com/docker/buildx). By default, the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver) | ||||
| will be used to be able to build multi-platform images and export cache thanks to the [BuildKit](https://github.com/moby/buildkit) | ||||
| container. | ||||
| This action will create and boot a builder that can be used in the following | ||||
| steps of your workflow if you're using Buildx or the [`build-push` action](https://github.com/docker/build-push-action/). | ||||
| By default, the [`docker-container` driver](https://docs.docker.com/build/building/drivers/docker-container/) | ||||
| will be used to be able to build multi-platform images and export cache using | ||||
| a [BuildKit](https://github.com/moby/buildkit) container. | ||||
|  | ||||
|  | ||||
|  | ||||
| ___ | ||||
|  | ||||
| * [Usage](#usage) | ||||
|   * [Quick start](#quick-start) | ||||
|   * [With QEMU](#with-qemu) | ||||
|   * [Install by default](#install-by-default) | ||||
|   * [BuildKit daemon configuration](#buildkit-daemon-configuration) | ||||
|     * [Registry mirror](#registry-mirror) | ||||
|     * [Max parallelism](#max-parallelism) | ||||
|   * [Standalone mode](#standalone-mode) | ||||
| * [Advanced usage](#advanced-usage) | ||||
|   * [Authentication support](docs/advanced/auth.md) | ||||
|   * [Append additional nodes to the builder](docs/advanced/append-nodes.md) | ||||
|   * [Install by default](docs/advanced/install-default.md) | ||||
|   * [BuildKit daemon configuration](docs/advanced/buildkit-config.md) | ||||
|   * [Standalone mode](docs/advanced/standalone.md) | ||||
| * [Customizing](#customizing) | ||||
|   * [inputs](#inputs) | ||||
|   * [outputs](#outputs) | ||||
|   * [environment variables](#environment-variables) | ||||
| * [Notes](#notes) | ||||
|   * [`nodes` output](#nodes-output) | ||||
|   * [BuildKit container logs](#buildkit-container-logs) | ||||
| * [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot) | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| ### Quick start | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| @@ -49,227 +48,118 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: docker/setup-buildx-action@v1 | ||||
|       - | ||||
|         name: Inspect builder | ||||
|         run: | | ||||
|           echo "Name:      ${{ steps.buildx.outputs.name }}" | ||||
|           echo "Endpoint:  ${{ steps.buildx.outputs.endpoint }}" | ||||
|           echo "Status:    ${{ steps.buildx.outputs.status }}" | ||||
|           echo "Flags:     ${{ steps.buildx.outputs.flags }}" | ||||
|           echo "Platforms: ${{ steps.buildx.outputs.platforms }}" | ||||
| ``` | ||||
|  | ||||
| ### With QEMU | ||||
|  | ||||
| If you want support for more platforms you can use our [setup-qemu](https://github.com/docker/setup-qemu-action) action: | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         # Add support for more platforms with QEMU (optional) | ||||
|         # https://github.com/docker/setup-qemu-action | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v1 | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: docker/setup-buildx-action@v1 | ||||
|       - | ||||
|         name: Available platforms | ||||
|         run: echo ${{ steps.buildx.outputs.platforms }} | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
| ``` | ||||
|  | ||||
| ### Install by default | ||||
| ## Advanced usage | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|       - | ||||
|         uses: docker/setup-buildx-action@v1 | ||||
|         id: buildx | ||||
|         with: | ||||
|           install: true | ||||
|       - | ||||
|         name: Build | ||||
|         run: | | ||||
|           docker build . # will run buildx | ||||
| ``` | ||||
|  | ||||
| ### BuildKit daemon configuration | ||||
|  | ||||
| You can provide a [BuildKit configuration](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) | ||||
| to your builder if you're using the [`docker-container` driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver) | ||||
| (default) with the `config` or `config-inline` inputs: | ||||
|  | ||||
| #### Registry mirror | ||||
|  | ||||
| You can configure a registry mirror using an inline block directly in your | ||||
| workflow with the `config-inline` input: | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v1 | ||||
|         with: | ||||
|           config-inline: | | ||||
|             [registry."docker.io"] | ||||
|               mirrors = ["mirror.gcr.io"] | ||||
| ``` | ||||
|  | ||||
| #### Max parallelism | ||||
|  | ||||
| You can limit the parallelism of the BuildKit solver which is particularly | ||||
| useful for low-powered machines. | ||||
|  | ||||
| You can use the `config-inline` input like the | ||||
| previous example, or you can use a dedicated BuildKit config file from your | ||||
| repo if you want with the `config` input: | ||||
|  | ||||
| ```toml | ||||
| # .github/buildkitd.toml | ||||
| [worker.oci] | ||||
|   max-parallelism = 4 | ||||
| ``` | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v1 | ||||
|         with: | ||||
|           config: .github/buildkitd.toml | ||||
| ``` | ||||
|  | ||||
| ### Standalone mode | ||||
|  | ||||
| If you don't have the Docker CLI installed on the GitHub Runner, buildx binary | ||||
| is invoked directly, instead of calling it as a docker plugin. This can be | ||||
| useful if you want to use the `kubernetes` driver in your self-hosted runner: | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v1 | ||||
|         with: | ||||
|           driver: kubernetes | ||||
|       - | ||||
|         name: Build | ||||
|         run: | | ||||
|           buildx build . | ||||
| ``` | ||||
| * [Authentication support](docs/advanced/auth.md) | ||||
| * [Append additional nodes to the builder](docs/advanced/append-nodes.md) | ||||
| * [Install by default](docs/advanced/install-default.md) | ||||
| * [BuildKit daemon configuration](docs/advanced/buildkit-config.md) | ||||
| * [Standalone mode](docs/advanced/standalone.md) | ||||
|  | ||||
| ## Customizing | ||||
|  | ||||
| ### inputs | ||||
|  | ||||
| Following inputs can be used as `step.with` keys | ||||
| Following inputs can be used as `step.with` keys: | ||||
|  | ||||
| | Name               | Type    | Description                       | | ||||
| |--------------------|---------|-----------------------------------| | ||||
| | `version`          | String  | [buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`, `https://github.com/docker/buildx.git#master`) | | ||||
| | `driver`           | String  | Sets the [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver) to be used (default `docker-container`) | | ||||
| | `driver-opts`      | CSV     | List of additional [driver-specific options](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver-opt) (eg. `image=moby/buildkit:master`) | | ||||
| | `buildkitd-flags`  | String  | [Flags for buildkitd](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) daemon (since [buildx v0.3.0](https://github.com/docker/buildx/releases/tag/v0.3.0)) | | ||||
| | `install`          | Bool    | Sets up `docker build` command as an alias to `docker buildx` (default `false`) | | ||||
| | `use`              | Bool    | Switch to this builder instance (default `true`) | | ||||
| | `endpoint`         | String  | [Optional address for docker socket](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#description) or context from `docker context ls` | | ||||
| | `config`¹          | String  | [BuildKit config file](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#config) | | ||||
| | `config-inline`¹   | String  | Same as `config` but inline | | ||||
|  | ||||
| > * ¹ `config` and `config-inline` are mutually exclusive | ||||
|  | ||||
| > `CSV` type must be a newline-delimited string | ||||
| > ```yaml | ||||
| > driver-opts: image=moby/buildkit:master | ||||
| > ``` | ||||
| > `List` type is a newline-delimited string | ||||
| > ```yaml | ||||
| > driver-opts: | | ||||
| >   image=moby/buildkit:master | ||||
| >   network=host | ||||
| > ``` | ||||
|  | ||||
| > `CSV` type must be a newline-delimited string | ||||
| > ```yaml | ||||
| > platforms: linux/amd64,linux/arm64 | ||||
| > ``` | ||||
|  | ||||
| | Name              | Type     | Description                                                                                                                                                                                     | | ||||
| |-------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||||
| | `version`         | String   | [Buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`, `https://github.com/docker/buildx.git#master`)                                                                     | | ||||
| | `driver`          | String   | Sets the [builder driver](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver) to be used (default `docker-container`)                                                   | | ||||
| | `driver-opts`     | List     | List of additional [driver-specific options](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver-opt) (eg. `image=moby/buildkit:master`)                                 | | ||||
| | `buildkitd-flags` | String   | [Flags for buildkitd](https://docs.docker.com/engine/reference/commandline/buildx_create/#buildkitd-flags) daemon (since [buildx v0.3.0](https://github.com/docker/buildx/releases/tag/v0.3.0)) | | ||||
| | `install`         | Bool     | Sets up `docker build` command as an alias to `docker buildx` (default `false`)                                                                                                                 | | ||||
| | `use`             | Bool     | Switch to this builder instance (default `true`)                                                                                                                                                | | ||||
| | `endpoint`        | String   | [Optional address for docker socket](https://docs.docker.com/engine/reference/commandline/buildx_create/#description) or context from `docker context ls`                                       | | ||||
| | `platforms`       | List/CSV | Fixed [platforms](https://docs.docker.com/engine/reference/commandline/buildx_create/#platform) for current node. If not empty, values take priority over the detected ones.                    | | ||||
| | `config`¹         | String   | [BuildKit config file](https://docs.docker.com/engine/reference/commandline/buildx_create/#config)                                                                                              | | ||||
| | `config-inline`¹  | String   | Same as `config` but inline                                                                                                                                                                     | | ||||
| | `append`          | YAML     | [Append additional nodes](docs/advanced/append-nodes.md) to the builder                                                                                                                         | | ||||
|  | ||||
| > * ¹ `config` and `config-inline` are mutually exclusive | ||||
|  | ||||
| ### outputs | ||||
|  | ||||
| Following outputs are available | ||||
|  | ||||
| | Name          | Type    | Description                           | | ||||
| |---------------|---------|---------------------------------------| | ||||
| | `name`        | String  | Builder name | | ||||
| | `driver`      | String  | Builder driver | | ||||
| | `endpoint`    | String  | Builder node endpoint | | ||||
| | `status`      | String  | Builder node status | | ||||
| | `flags`       | String  | Builder node flags (if applicable) | | ||||
| | `platforms`   | String  | Builder node platforms available (comma separated) | | ||||
| | Name        | Type   | Description                                     | | ||||
| |-------------|--------|-------------------------------------------------| | ||||
| | `name`      | String | Builder name                                    | | ||||
| | `driver`    | String | Builder driver                                  | | ||||
| | `platforms` | String | Builder node platforms (preferred or available) | | ||||
| | `nodes`     | JSON   | Builder [nodes metadata](#nodes-output)         | | ||||
|  | ||||
| ### environment variables | ||||
|  | ||||
| The following [official docker environment variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) are supported: | ||||
|  | ||||
| | Name            | Type    | Default      | Description                                    | | ||||
| |-----------------|---------|-------------|-------------------------------------------------| | ||||
| | `DOCKER_CONFIG` | String  | `~/.docker` | The location of your client configuration files | | ||||
| | Name            | Type   | Default     | Description                                     | | ||||
| |-----------------|--------|-------------|-------------------------------------------------| | ||||
| | `DOCKER_CONFIG` | String | `~/.docker` | The location of your client configuration files | | ||||
|  | ||||
| ## Notes | ||||
|  | ||||
| ### `nodes` output | ||||
|  | ||||
| ```json | ||||
| [ | ||||
|   { | ||||
|      "name": "builder-3820d274-502c-4498-ae24-d4c32b3023d90", | ||||
|      "endpoint": "unix:///var/run/docker.sock", | ||||
|      "driver-opts": [ | ||||
|        "network=host", | ||||
|        "image=moby/buildkit:master" | ||||
|      ], | ||||
|     "status": "running", | ||||
|     "buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host", | ||||
|     "buildkit": "3fab389", | ||||
|     "platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386" | ||||
|   } | ||||
| ] | ||||
| ``` | ||||
|  | ||||
| | Name              | Type   | Description                | | ||||
| |-------------------|--------|----------------------------| | ||||
| | `name`            | String | Node name                  | | ||||
| | `endpoint`        | String | Node endpoint              | | ||||
| | `driver-opts`     | List   | Options for the driver     | | ||||
| | `status`          | String | Node status                | | ||||
| | `buildkitd-flags` | String | Flags for buildkitd daemon | | ||||
| | `buildkit`        | String | BuildKit version           | | ||||
| | `platforms`       | String | Platforms available        | | ||||
|  | ||||
| ### BuildKit container logs | ||||
|  | ||||
| To display BuildKit container logs (when `docker-container` driver is used) you have to [enable step debug logging](https://docs.github.com/en/actions/managing-workflow-runs/enabling-debug-logging#enabling-step-debug-logging) | ||||
| To display BuildKit container logs (when `docker-container` driver is used) you have to [enable step debug logging](https://docs.github.com/en/actions/managing-workflow-runs/enabling-debug-logging#enabling-step-debug-logging), | ||||
| or you can also enable debugging in the [setup-buildx action step](https://github.com/docker/setup-buildx-action): | ||||
|  | ||||
| ```yaml | ||||
|   - | ||||
|     name: Set up Docker Buildx | ||||
|     uses: docker/setup-buildx-action@v1 | ||||
|     uses: docker/setup-buildx-action@v2 | ||||
|     with: | ||||
|       buildkitd-flags: --debug | ||||
| ``` | ||||
|   | ||||
							
								
								
									
										88
									
								
								__tests__/auth.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								__tests__/auth.test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| import {describe, expect, test, beforeEach} from '@jest/globals'; | ||||
| import * as fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import * as auth from '../src/auth'; | ||||
|  | ||||
| const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-jest')).split(path.sep).join(path.posix.sep); | ||||
| const dockerConfigHome = path.join(tmpdir, '.docker'); | ||||
| const credsdir = path.join(dockerConfigHome, 'buildx', 'creds'); | ||||
|  | ||||
| describe('setCredentials', () => { | ||||
|   beforeEach(() => { | ||||
|     process.env = Object.keys(process.env).reduce((object, key) => { | ||||
|       if (!key.startsWith(auth.envPrefix)) { | ||||
|         object[key] = process.env[key]; | ||||
|       } | ||||
|       return object; | ||||
|     }, {}); | ||||
|   }); | ||||
|  | ||||
|   // prettier-ignore | ||||
|   test.each([ | ||||
|     [ | ||||
|       'mycontext', | ||||
|       'docker-container', | ||||
|       {}, | ||||
|       [], | ||||
|       [] | ||||
|     ], | ||||
|     [ | ||||
|       'docker-container://mycontainer', | ||||
|       'docker-container', | ||||
|       {}, | ||||
|       [], | ||||
|       [] | ||||
|     ], | ||||
|     [ | ||||
|       'tcp://graviton2:1234', | ||||
|       'remote', | ||||
|       {}, | ||||
|       [], | ||||
|       [] | ||||
|     ], | ||||
|     [ | ||||
|       'tcp://graviton2:1234', | ||||
|       'remote', | ||||
|       { | ||||
|         'BUILDER_NODE_0_AUTH_TLS_CACERT': 'foo', | ||||
|         'BUILDER_NODE_0_AUTH_TLS_CERT': 'foo', | ||||
|         'BUILDER_NODE_0_AUTH_TLS_KEY': 'foo' | ||||
|       }, | ||||
|       [ | ||||
|         path.join(credsdir, 'cacert_graviton2-1234.pem'), | ||||
|         path.join(credsdir, 'cert_graviton2-1234.pem'), | ||||
|         path.join(credsdir, 'key_graviton2-1234.pem') | ||||
|       ], | ||||
|       [ | ||||
|         `cacert=${path.join(credsdir, 'cacert_graviton2-1234.pem')}`, | ||||
|         `cert=${path.join(credsdir, 'cert_graviton2-1234.pem')}`, | ||||
|         `key=${path.join(credsdir, 'key_graviton2-1234.pem')}` | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       'tcp://graviton2:1234', | ||||
|       'docker-container', | ||||
|       { | ||||
|         'BUILDER_NODE_0_AUTH_TLS_CACERT': 'foo', | ||||
|         'BUILDER_NODE_0_AUTH_TLS_CERT': 'foo', | ||||
|         'BUILDER_NODE_0_AUTH_TLS_KEY': 'foo' | ||||
|       }, | ||||
|       [ | ||||
|         path.join(credsdir, 'cacert_graviton2-1234.pem'), | ||||
|         path.join(credsdir, 'cert_graviton2-1234.pem'), | ||||
|         path.join(credsdir, 'key_graviton2-1234.pem') | ||||
|       ], | ||||
|       [] | ||||
|     ], | ||||
|   ])('given %p endpoint', async (endpoint: string, driver: string, envs: Record<string, string>, expectedFiles: Array<string>, expectedOpts: Array<string>) => { | ||||
|     fs.mkdirSync(credsdir, {recursive: true}); | ||||
|     for (const [key, value] of Object.entries(envs)) { | ||||
|       process.env[key] = value; | ||||
|     } | ||||
|     expect(auth.setCredentials(credsdir, 0, driver, endpoint)).toEqual(expectedOpts); | ||||
|     expectedFiles.forEach( (file) => { | ||||
|       expect(fs.existsSync(file)).toBe(true); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| @@ -7,18 +7,14 @@ import * as context from '../src/context'; | ||||
| import * as semver from 'semver'; | ||||
| import * as exec from '@actions/exec'; | ||||
|  | ||||
| const tmpNameSync = path.join('/tmp/.docker-setup-buildx-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); | ||||
|  | ||||
| const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-')).split(path.sep).join(path.posix.sep); | ||||
| jest.spyOn(context, 'tmpDir').mockImplementation((): string => { | ||||
|   const tmpDir = path.join('/tmp/.docker-setup-buildx-jest').split(path.sep).join(path.posix.sep); | ||||
|   if (!fs.existsSync(tmpDir)) { | ||||
|     fs.mkdirSync(tmpDir, {recursive: true}); | ||||
|   } | ||||
|   return tmpDir; | ||||
|   return tmpdir; | ||||
| }); | ||||
|  | ||||
| const tmpname = path.join(tmpdir, '.tmpname').split(path.sep).join(path.posix.sep); | ||||
| jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => { | ||||
|   return tmpNameSync; | ||||
|   return tmpname; | ||||
| }); | ||||
|  | ||||
| describe('isAvailable', () => { | ||||
| @@ -77,10 +73,128 @@ describe('inspect', () => { | ||||
|     expect(builder).not.toBeUndefined(); | ||||
|     expect(builder.name).not.toEqual(''); | ||||
|     expect(builder.driver).not.toEqual(''); | ||||
|     expect(builder.node_platforms).not.toEqual(''); | ||||
|     expect(builder.nodes).not.toEqual({}); | ||||
|   }, 100000); | ||||
| }); | ||||
|  | ||||
| describe('parseInspect', () => { | ||||
|   // prettier-ignore | ||||
|   test.each([ | ||||
|     [ | ||||
|      'inspect1.txt', | ||||
|      { | ||||
|        "nodes": [ | ||||
|          { | ||||
|            "name": "builder-5cb467f7-0940-47e1-b94b-d51f54054d620", | ||||
|            "endpoint": "unix:///var/run/docker.sock", | ||||
|            "status": "running", | ||||
|            "buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host", | ||||
|            "buildkit": "v0.10.4", | ||||
|            "platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/arm64,linux/riscv64,linux/386,linux/arm/v7,linux/arm/v6" | ||||
|          } | ||||
|        ], | ||||
|        "name": "builder-5cb467f7-0940-47e1-b94b-d51f54054d62", | ||||
|        "driver": "docker-container" | ||||
|      } | ||||
|     ], | ||||
|     [ | ||||
|      'inspect2.txt', | ||||
|      { | ||||
|        "nodes": [ | ||||
|          { | ||||
|            "name": "builder-5f449644-ff29-48af-8344-abb0292d06730", | ||||
|            "endpoint": "unix:///var/run/docker.sock", | ||||
|            "driver-opts": [ | ||||
|              "image=moby/buildkit:latest" | ||||
|            ], | ||||
|            "status": "running", | ||||
|            "buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host", | ||||
|            "buildkit": "v0.10.4", | ||||
|            "platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386" | ||||
|          } | ||||
|        ], | ||||
|        "name": "builder-5f449644-ff29-48af-8344-abb0292d0673", | ||||
|        "driver": "docker-container" | ||||
|      } | ||||
|     ], | ||||
|     [ | ||||
|      'inspect3.txt', | ||||
|      { | ||||
|        "nodes": [ | ||||
|          { | ||||
|            "name": "builder-9929e463-7954-4dc3-89cd-514cca29ff800", | ||||
|            "endpoint": "unix:///var/run/docker.sock", | ||||
|            "driver-opts": [ | ||||
|              "image=moby/buildkit:master", | ||||
|              "network=host" | ||||
|            ], | ||||
|            "status": "running", | ||||
|            "buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host", | ||||
|            "buildkit": "3fab389", | ||||
|            "platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386" | ||||
|          } | ||||
|        ], | ||||
|        "name": "builder-9929e463-7954-4dc3-89cd-514cca29ff80", | ||||
|        "driver": "docker-container" | ||||
|      } | ||||
|     ], | ||||
|     [ | ||||
|      'inspect4.txt', | ||||
|      { | ||||
|        "nodes": [ | ||||
|          { | ||||
|            "name": "default", | ||||
|            "endpoint": "default", | ||||
|            "status": "running", | ||||
|            "buildkit": "20.10.17", | ||||
|            "platforms": "linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6" | ||||
|          } | ||||
|        ], | ||||
|        "name": "default", | ||||
|        "driver": "docker" | ||||
|      } | ||||
|     ], | ||||
|     [ | ||||
|      'inspect5.txt', | ||||
|      { | ||||
|        "nodes": [ | ||||
|          { | ||||
|            "name": "aws_graviton2", | ||||
|            "endpoint": "tcp://1.23.45.67:1234", | ||||
|            "driver-opts": [ | ||||
|              "cert=/home/user/.certs/aws_graviton2/cert.pem", | ||||
|              "key=/home/user/.certs/aws_graviton2/key.pem", | ||||
|              "cacert=/home/user/.certs/aws_graviton2/ca.pem" | ||||
|            ], | ||||
|            "status": "running", | ||||
|            "platforms": "darwin/arm64,linux/arm64,linux/arm/v5,linux/arm/v6,linux/arm/v7,windows/arm64" | ||||
|          } | ||||
|        ], | ||||
|        "name": "remote-builder", | ||||
|        "driver": "remote" | ||||
|      } | ||||
|     ], | ||||
|     [ | ||||
|      'inspect6.txt', | ||||
|      { | ||||
|        "nodes": [ | ||||
|          { | ||||
|            "name": "builder-17cfff01-48d9-4c3d-9332-9992e308a5100", | ||||
|            "endpoint": "unix:///var/run/docker.sock", | ||||
|            "status": "running", | ||||
|            "buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host", | ||||
|            "platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/386" | ||||
|          } | ||||
|        ], | ||||
|        "name": "builder-17cfff01-48d9-4c3d-9332-9992e308a510", | ||||
|        "driver": "docker-container" | ||||
|      } | ||||
|     ], | ||||
|   ])('given %p', async (inspectFile, expected) => { | ||||
|     expect(await buildx.parseInspect(fs.readFileSync(path.join(__dirname, 'fixtures', inspectFile)).toString())).toEqual(expected); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('build', () => { | ||||
|   const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-')); | ||||
|  | ||||
| @@ -136,8 +250,8 @@ describe('getConfig', () => { | ||||
|         config = await buildx.getConfigInline(val); | ||||
|       } | ||||
|       expect(true).toBe(!invalid); | ||||
|       expect(config).toEqual(`${tmpNameSync}`); | ||||
|       const configValue = fs.readFileSync(tmpNameSync, 'utf-8'); | ||||
|       expect(config).toEqual(tmpname); | ||||
|       const configValue = fs.readFileSync(tmpname, 'utf-8'); | ||||
|       expect(configValue).toEqual(exValue); | ||||
|     } catch (err) { | ||||
|       // eslint-disable-next-line jest/no-conditional-expect | ||||
|   | ||||
| @@ -1,19 +1,206 @@ | ||||
| import {beforeEach, describe, expect, it, jest} from '@jest/globals'; | ||||
| import {beforeEach, describe, expect, it, jest, test} from '@jest/globals'; | ||||
| import * as fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import * as uuid from 'uuid'; | ||||
| import * as context from '../src/context'; | ||||
| import * as nodes from '../src/nodes'; | ||||
|  | ||||
| const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-')).split(path.sep).join(path.posix.sep); | ||||
| jest.spyOn(context, 'tmpDir').mockImplementation((): string => { | ||||
|   const tmpDir = path.join('/tmp/.docker-setup-buildx-jest').split(path.sep).join(path.posix.sep); | ||||
|   if (!fs.existsSync(tmpDir)) { | ||||
|     fs.mkdirSync(tmpDir, {recursive: true}); | ||||
|   } | ||||
|   return tmpDir; | ||||
|   return tmpdir; | ||||
| }); | ||||
|  | ||||
| jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => { | ||||
|   return path.join('/tmp/.docker-setup-buildx-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); | ||||
|   return path.join(tmpdir, '.tmpname').split(path.sep).join(path.posix.sep); | ||||
| }); | ||||
|  | ||||
| jest.mock('uuid'); | ||||
| jest.spyOn(uuid, 'v4').mockReturnValue('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'); | ||||
|  | ||||
| describe('getCreateArgs', () => { | ||||
|   beforeEach(() => { | ||||
|     process.env = Object.keys(process.env).reduce((object, key) => { | ||||
|       if (!key.startsWith('INPUT_')) { | ||||
|         object[key] = process.env[key]; | ||||
|       } | ||||
|       return object; | ||||
|     }, {}); | ||||
|   }); | ||||
|  | ||||
|   // prettier-ignore | ||||
|   test.each([ | ||||
|     [ | ||||
|       0, | ||||
|       new Map<string, string>([ | ||||
|         ['install', 'false'], | ||||
|         ['use', 'true'], | ||||
|       ]), | ||||
|       [ | ||||
|         'create', | ||||
|         '--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', | ||||
|         '--driver', 'docker-container', | ||||
|         '--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|         '--use' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       1, | ||||
|       new Map<string, string>([ | ||||
|         ['driver', 'docker'], | ||||
|         ['install', 'false'], | ||||
|         ['use', 'true'], | ||||
|       ]), | ||||
|       [ | ||||
|         'create', | ||||
|         '--name', 'default', | ||||
|         '--driver', 'docker', | ||||
|         '--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|         '--use' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       2, | ||||
|       new Map<string, string>([ | ||||
|         ['install', 'false'], | ||||
|         ['use', 'false'], | ||||
|         ['driver-opts', 'image=moby/buildkit:master\nnetwork=host'], | ||||
|       ]), | ||||
|       [ | ||||
|         'create', | ||||
|         '--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', | ||||
|         '--driver', 'docker-container', | ||||
|         '--driver-opt', 'image=moby/buildkit:master', | ||||
|         '--driver-opt', 'network=host', | ||||
|         '--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       3, | ||||
|       new Map<string, string>([ | ||||
|         ['driver', 'remote'], | ||||
|         ['endpoint', 'tls://foo:1234'], | ||||
|         ['install', 'false'], | ||||
|         ['use', 'true'], | ||||
|       ]), | ||||
|       [ | ||||
|         'create', | ||||
|         '--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', | ||||
|         '--driver', 'remote', | ||||
|         '--use', | ||||
|         'tls://foo:1234' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       4, | ||||
|       new Map<string, string>([ | ||||
|         ['driver', 'remote'], | ||||
|         ['platforms', 'linux/arm64,linux/arm/v7'], | ||||
|         ['endpoint', 'tls://foo:1234'], | ||||
|         ['install', 'false'], | ||||
|         ['use', 'true'], | ||||
|       ]), | ||||
|       [ | ||||
|         'create', | ||||
|         '--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', | ||||
|         '--driver', 'remote', | ||||
|         '--platform', 'linux/arm64,linux/arm/v7', | ||||
|         '--use', | ||||
|         'tls://foo:1234' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       5, | ||||
|       new Map<string, string>([ | ||||
|         ['install', 'false'], | ||||
|         ['use', 'false'], | ||||
|         ['driver-opts', `"env.no_proxy=localhost,127.0.0.1,.mydomain"`], | ||||
|       ]), | ||||
|       [ | ||||
|         'create', | ||||
|         '--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', | ||||
|         '--driver', 'docker-container', | ||||
|         '--driver-opt', '"env.no_proxy=localhost,127.0.0.1,.mydomain"', | ||||
|         '--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       6, | ||||
|       new Map<string, string>([ | ||||
|         ['install', 'false'], | ||||
|         ['use', 'false'], | ||||
|         ['platforms', 'linux/amd64\n"linux/arm64,linux/arm/v7"'], | ||||
|       ]), | ||||
|       [ | ||||
|         'create', | ||||
|         '--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', | ||||
|         '--driver', 'docker-container', | ||||
|         '--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|         '--platform', 'linux/amd64,linux/arm64,linux/arm/v7' | ||||
|       ] | ||||
|     ], | ||||
|   ])( | ||||
|     '[%d] given %p as inputs, returns %p', | ||||
|     async (num: number, inputs: Map<string, string>, expected: Array<string>) => { | ||||
|       inputs.forEach((value: string, name: string) => { | ||||
|         setInput(name, value); | ||||
|       }); | ||||
|       const inp = await context.getInputs(); | ||||
|       const res = await context.getCreateArgs(inp, '0.9.0'); | ||||
|       expect(res).toEqual(expected); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| describe('getAppendArgs', () => { | ||||
|   beforeEach(() => { | ||||
|     process.env = Object.keys(process.env).reduce((object, key) => { | ||||
|       if (!key.startsWith('INPUT_')) { | ||||
|         object[key] = process.env[key]; | ||||
|       } | ||||
|       return object; | ||||
|     }, {}); | ||||
|   }); | ||||
|  | ||||
|   // prettier-ignore | ||||
|   test.each([ | ||||
|     [ | ||||
|       0, | ||||
|       new Map<string, string>([ | ||||
|         ['install', 'false'], | ||||
|         ['use', 'true'], | ||||
|       ]), | ||||
|       { | ||||
|         "name": "aws_graviton2", | ||||
|         "endpoint": "ssh://me@graviton2", | ||||
|         "driver-opts": [ | ||||
|           "image=moby/buildkit:latest" | ||||
|         ], | ||||
|         "buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host", | ||||
|         "platforms": "linux/arm64" | ||||
|       }, | ||||
|       [ | ||||
|         'create', | ||||
|         '--name', 'builder-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', | ||||
|         '--append', | ||||
|         '--node', 'aws_graviton2', | ||||
|         '--driver-opt', 'image=moby/buildkit:latest', | ||||
|         '--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|         '--platform', 'linux/arm64', | ||||
|         'ssh://me@graviton2' | ||||
|       ] | ||||
|     ] | ||||
|   ])( | ||||
|     '[%d] given %p as inputs, returns %p', | ||||
|     async (num: number, inputs: Map<string, string>, node: nodes.Node, expected: Array<string>) => { | ||||
|       inputs.forEach((value: string, name: string) => { | ||||
|         setInput(name, value); | ||||
|       }); | ||||
|       const inp = await context.getInputs(); | ||||
|       const res = await context.getAppendArgs(inp, node, '0.9.0'); | ||||
|       expect(res).toEqual(expected); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| describe('getInputList', () => { | ||||
| @@ -85,30 +272,6 @@ describe('asyncForEach', () => { | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('setOutput', () => { | ||||
|   beforeEach(() => { | ||||
|     process.stdout.write = jest.fn() as typeof process.stdout.write; | ||||
|   }); | ||||
|  | ||||
|   // eslint-disable-next-line jest/expect-expect | ||||
|   it('setOutput produces the correct command', () => { | ||||
|     context.setOutput('some output', 'some value'); | ||||
|     assertWriteCalls([`::set-output name=some output::some value${os.EOL}`]); | ||||
|   }); | ||||
|  | ||||
|   // eslint-disable-next-line jest/expect-expect | ||||
|   it('setOutput handles bools', () => { | ||||
|     context.setOutput('some output', false); | ||||
|     assertWriteCalls([`::set-output name=some output::false${os.EOL}`]); | ||||
|   }); | ||||
|  | ||||
|   // eslint-disable-next-line jest/expect-expect | ||||
|   it('setOutput handles numbers', () => { | ||||
|     context.setOutput('some output', 1.01); | ||||
|     assertWriteCalls([`::set-output name=some output::1.01${os.EOL}`]); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| // See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67 | ||||
| function getInputName(name: string): string { | ||||
|   return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`; | ||||
| @@ -117,11 +280,3 @@ function getInputName(name: string): string { | ||||
| function setInput(name: string, value: string): void { | ||||
|   process.env[getInputName(name)] = value; | ||||
| } | ||||
|  | ||||
| // Assert that process.stdout.write calls called only with the given arguments. | ||||
| function assertWriteCalls(calls: string[]): void { | ||||
|   expect(process.stdout.write).toHaveBeenCalledTimes(calls.length); | ||||
|   for (let i = 0; i < calls.length; i++) { | ||||
|     expect(process.stdout.write).toHaveBeenNthCalledWith(i + 1, calls[i]); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								__tests__/fixtures/inspect1.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								__tests__/fixtures/inspect1.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| Name:   builder-5cb467f7-0940-47e1-b94b-d51f54054d62 | ||||
| Driver: docker-container | ||||
|  | ||||
| Nodes: | ||||
| Name:      builder-5cb467f7-0940-47e1-b94b-d51f54054d620 | ||||
| Endpoint:  unix:///var/run/docker.sock | ||||
| Status:    running | ||||
| Flags:     --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host | ||||
| Buildkit:  v0.10.4 | ||||
| Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/arm64, linux/riscv64, linux/386, linux/arm/v7, linux/arm/v6 | ||||
							
								
								
									
										11
									
								
								__tests__/fixtures/inspect2.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								__tests__/fixtures/inspect2.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Name:   builder-5f449644-ff29-48af-8344-abb0292d0673 | ||||
| Driver: docker-container | ||||
|  | ||||
| Nodes: | ||||
| Name:           builder-5f449644-ff29-48af-8344-abb0292d06730 | ||||
| Endpoint:       unix:///var/run/docker.sock | ||||
| Driver Options: image="moby/buildkit:latest" | ||||
| Status:         running | ||||
| Flags:          --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host | ||||
| Buildkit:       v0.10.4 | ||||
| Platforms:      linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386 | ||||
							
								
								
									
										11
									
								
								__tests__/fixtures/inspect3.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								__tests__/fixtures/inspect3.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| Name:   builder-9929e463-7954-4dc3-89cd-514cca29ff80 | ||||
| Driver: docker-container | ||||
|  | ||||
| Nodes: | ||||
| Name:           builder-9929e463-7954-4dc3-89cd-514cca29ff800 | ||||
| Endpoint:       unix:///var/run/docker.sock | ||||
| Driver Options: image="moby/buildkit:master" network="host" | ||||
| Status:         running | ||||
| Flags:          --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host | ||||
| Buildkit:       3fab389 | ||||
| Platforms:      linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386 | ||||
							
								
								
									
										9
									
								
								__tests__/fixtures/inspect4.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								__tests__/fixtures/inspect4.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| Name:   default | ||||
| Driver: docker | ||||
|  | ||||
| Nodes: | ||||
| Name:      default | ||||
| Endpoint:  default | ||||
| Status:    running | ||||
| Buildkit:  20.10.17 | ||||
| Platforms: linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6 | ||||
							
								
								
									
										9
									
								
								__tests__/fixtures/inspect5.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								__tests__/fixtures/inspect5.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| Name:   remote-builder | ||||
| Driver: remote | ||||
|  | ||||
| Nodes: | ||||
| Name:           aws_graviton2 | ||||
| Endpoint:       tcp://1.23.45.67:1234 | ||||
| Driver Options: cert="/home/user/.certs/aws_graviton2/cert.pem" key="/home/user/.certs/aws_graviton2/key.pem" cacert="/home/user/.certs/aws_graviton2/ca.pem" | ||||
| Status:         running | ||||
| Platforms:      darwin/arm64*, linux/arm64*, linux/arm/v5*, linux/arm/v6*, linux/arm/v7*, windows/arm64*, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/mips64le, linux/mips64 | ||||
							
								
								
									
										9
									
								
								__tests__/fixtures/inspect6.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								__tests__/fixtures/inspect6.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| Name:   builder-17cfff01-48d9-4c3d-9332-9992e308a510 | ||||
| Driver: docker-container | ||||
|  | ||||
| Nodes: | ||||
| Name:      builder-17cfff01-48d9-4c3d-9332-9992e308a5100 | ||||
| Endpoint:  unix:///var/run/docker.sock | ||||
| Status:    running | ||||
| Flags:     --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host | ||||
| Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386 | ||||
							
								
								
									
										26
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								action.yml
									
									
									
									
									
								
							| @@ -22,7 +22,7 @@ inputs: | ||||
|     default: '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host' | ||||
|     required: false | ||||
|   install: | ||||
|     description: 'Sets up docker build command as an alias to docker buildx' | ||||
|     description: 'Sets up docker build command as an alias to docker buildx build' | ||||
|     default: 'false' | ||||
|     required: false | ||||
|   use: | ||||
| @@ -32,28 +32,36 @@ inputs: | ||||
|   endpoint: | ||||
|     description: 'Optional address for docker socket or context from `docker context ls`' | ||||
|     required: false | ||||
|   platforms: | ||||
|     description: 'Fixed platforms for current node. If not empty, values take priority over the detected ones' | ||||
|     required: false | ||||
|   config: | ||||
|     description: 'BuildKit config file' | ||||
|     required: false | ||||
|   config-inline: | ||||
|     description: 'Inline BuildKit config' | ||||
|     required: false | ||||
|   append: | ||||
|     description: 'Append additional nodes to the builder' | ||||
|     required: false | ||||
|  | ||||
| outputs: | ||||
|   name: | ||||
|     description: 'Builder name' | ||||
|   driver: | ||||
|     description: 'Builder driver' | ||||
|   endpoint: | ||||
|     description: 'Builder node endpoint' | ||||
|   status: | ||||
|     description: 'Builder node status' | ||||
|   flags: | ||||
|     description: 'Builder node flags (if applicable)' | ||||
|   platforms: | ||||
|     description: 'Builder node platforms available (comma separated)' | ||||
|     description: 'Builder node platforms (preferred or available)' | ||||
|   nodes: | ||||
|     description: 'Builder nodes metadata' | ||||
|   endpoint: | ||||
|     description: 'Builder node endpoint (deprecated, use nodes output instead)' | ||||
|   status: | ||||
|     description: 'Builder node status (deprecated, use nodes output instead)' | ||||
|   flags: | ||||
|     description: 'Builder node flags (deprecated, use nodes output instead)' | ||||
|  | ||||
| runs: | ||||
|   using: 'node12' | ||||
|   using: 'node16' | ||||
|   main: 'dist/index.js' | ||||
|   post: 'dist/index.js' | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| # syntax=docker/dockerfile:1 | ||||
|  | ||||
| ARG NODE_VERSION=12 | ||||
| ARG NODE_VERSION=16 | ||||
| ARG DOCKER_VERSION=20.10.13 | ||||
| ARG BUILDX_VERSION=0.8.1 | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/index.js.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/index.js.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										50
									
								
								dist/licenses.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								dist/licenses.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -143,6 +143,31 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||
| CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
|  | ||||
|  | ||||
| csv-parse | ||||
| MIT | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2010 Adaltas | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
|  | ||||
|  | ||||
| fs.realpath | ||||
| ISC | ||||
| The ISC License | ||||
| @@ -254,6 +279,31 @@ PERFORMANCE OF THIS SOFTWARE. | ||||
|  | ||||
|  | ||||
|  | ||||
| js-yaml | ||||
| MIT | ||||
| (The MIT License) | ||||
|  | ||||
| Copyright (C) 2011-2015 by Vitaly Puzrin | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
|  | ||||
|  | ||||
| lru-cache | ||||
| ISC | ||||
| The ISC License | ||||
|   | ||||
							
								
								
									
										56
									
								
								docs/advanced/append-nodes.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								docs/advanced/append-nodes.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| # Append additional nodes to the builder | ||||
|  | ||||
| Buildx also supports running builds on multiple machines. This is useful for | ||||
| building [multi-platform images](https://docs.docker.com/build/building/multi-platform/) | ||||
| on native nodes for more complicated cases that are not handled by QEMU and | ||||
| generally have better performance or for distributing the build across multiple | ||||
| machines. | ||||
|  | ||||
| You can append nodes to the builder that is going to be created with the | ||||
| `append` input in the form of a YAML string document to remove limitations | ||||
| intrinsically linked to GitHub Actions (only string format is handled in the | ||||
| input fields): | ||||
|  | ||||
| | Name              | Type   | Description                                                                                                                                                                                                                                                                           | | ||||
| |-------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||||
| | `name`            | String | [Name of the node](https://docs.docker.com/engine/reference/commandline/buildx_create/#node). If empty, it is the name of the builder it belongs to, with an index number suffix. This is useful to set it if you want to modify/remove a node in an underlying step of you workflow. | | ||||
| | `endpoint`        | String | [Docker context or endpoint](https://docs.docker.com/engine/reference/commandline/buildx_create/#description) of the node to add to the builder                                                                                                                                       | | ||||
| | `driver-opts`     | List   | List of additional [driver-specific options](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver-opt)                                                                                                                                                          | | ||||
| | `buildkitd-flags` | String | [Flags for buildkitd](https://docs.docker.com/engine/reference/commandline/buildx_create/#buildkitd-flags) daemon                                                                                                                                                                     | | ||||
| | `platforms`       | String | Fixed [platforms](https://docs.docker.com/engine/reference/commandline/buildx_create/#platform) for the node. If not empty, values take priority over the detected ones.                                                                                                              | | ||||
|  | ||||
| Here is an example using remote nodes with the [`remote` driver](https://docs.docker.com/build/building/drivers/remote/) | ||||
| and [TLS authentication](auth.md#tls-authentication): | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           driver: remote | ||||
|           endpoint: tcp://oneprovider:1234 | ||||
|           append: | | ||||
|             - endpoint: tcp://graviton2:1234 | ||||
|               platforms: linux/arm64 | ||||
|             - endpoint: tcp://linuxone:1234 | ||||
|               platforms: linux/s390x | ||||
|         env: | ||||
|           BUILDER_NODE_0_AUTH_TLS_CACERT: ${{ secrets.ONEPROVIDER_CA }} | ||||
|           BUILDER_NODE_0_AUTH_TLS_CERT: ${{ secrets.ONEPROVIDER_CERT }} | ||||
|           BUILDER_NODE_0_AUTH_TLS_KEY: ${{ secrets.ONEPROVIDER_KEY }} | ||||
|           BUILDER_NODE_1_AUTH_TLS_CACERT: ${{ secrets.GRAVITON2_CA }} | ||||
|           BUILDER_NODE_1_AUTH_TLS_CERT: ${{ secrets.GRAVITON2_CERT }} | ||||
|           BUILDER_NODE_1_AUTH_TLS_KEY: ${{ secrets.GRAVITON2_KEY }} | ||||
|           BUILDER_NODE_2_AUTH_TLS_CACERT: ${{ secrets.LINUXONE_CA }} | ||||
|           BUILDER_NODE_2_AUTH_TLS_CERT: ${{ secrets.LINUXONE_CERT }} | ||||
|           BUILDER_NODE_2_AUTH_TLS_KEY: ${{ secrets.LINUXONE_KEY }} | ||||
| ``` | ||||
							
								
								
									
										64
									
								
								docs/advanced/auth.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								docs/advanced/auth.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| # Authentication support | ||||
|  | ||||
| ## SSH authentication | ||||
|  | ||||
| To be able to connect to an SSH endpoint using the [`docker-container` driver](https://docs.docker.com/build/building/drivers/docker-container/), | ||||
| you have to set up the SSH private key and configuration on the GitHub Runner: | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Set up SSH | ||||
|         uses: MrSquaare/ssh-setup-action@523473d91581ccbf89565e12b40faba93f2708bd # v1.1.0 | ||||
|         with: | ||||
|           host: graviton2 | ||||
|           private-key: ${{ secrets.SSH_PRIVATE_KEY }} | ||||
|           private-key-name: aws_graviton2 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           endpoint: ssh://me@graviton2 | ||||
| ``` | ||||
|  | ||||
| ## TLS authentication | ||||
|  | ||||
| You can also [set up a remote BuildKit instance](https://docs.docker.com/build/building/drivers/remote/#remote-buildkit-in-docker-container) | ||||
| using the remote driver. To ease the integration in your workflow, we put in | ||||
| place environment variables that will set up authentication using the BuildKit | ||||
| client certificates for the `tcp://` endpoint where `<idx>` is the position of | ||||
| the node in the list of nodes: | ||||
|  | ||||
| * `BUILDER_NODE_<idx>_AUTH_TLS_CACERT` | ||||
| * `BUILDER_NODE_<idx>_AUTH_TLS_CERT` | ||||
| * `BUILDER_NODE_<idx>_AUTH_TLS_KEY` | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           driver: remote | ||||
|           endpoint: tcp://graviton2:1234 | ||||
|         env: | ||||
|           BUILDER_NODE_0_AUTH_TLS_CACERT: ${{ secrets.GRAVITON2_CA }} | ||||
|           BUILDER_NODE_0_AUTH_TLS_CERT: ${{ secrets.GRAVITON2_CERT }} | ||||
|           BUILDER_NODE_0_AUTH_TLS_KEY: ${{ secrets.GRAVITON2_KEY }} | ||||
| ``` | ||||
							
								
								
									
										67
									
								
								docs/advanced/buildkit-config.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								docs/advanced/buildkit-config.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| # BuildKit daemon configuration | ||||
|  | ||||
| You can provide a [BuildKit configuration](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) | ||||
| to your builder if you're using the [`docker-container` driver](https://docs.docker.com/build/building/drivers/docker-container/) | ||||
| (default) with the `config` or `config-inline` inputs: | ||||
|  | ||||
| ## Registry mirror | ||||
|  | ||||
| You can configure a registry mirror using an inline block directly in your | ||||
| workflow with the `config-inline` input: | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           config-inline: | | ||||
|             [registry."docker.io"] | ||||
|               mirrors = ["mirror.gcr.io"] | ||||
| ``` | ||||
|  | ||||
| ## Max parallelism | ||||
|  | ||||
| You can limit the parallelism of the BuildKit solver which is particularly | ||||
| useful for low-powered machines. | ||||
|  | ||||
| You can use the `config-inline` input like the previous example, or you can use | ||||
| a dedicated BuildKit config file from your repo if you want with the | ||||
| `config` input: | ||||
|  | ||||
| ```toml | ||||
| # .github/buildkitd.toml | ||||
| [worker.oci] | ||||
|   max-parallelism = 4 | ||||
| ``` | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           config: .github/buildkitd.toml | ||||
| ``` | ||||
							
								
								
									
										28
									
								
								docs/advanced/install-default.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								docs/advanced/install-default.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| # Install by default | ||||
|  | ||||
| If you want set up the `docker build` command as an alias to | ||||
| `docker buildx build`: | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           install: true | ||||
|       - | ||||
|         name: Build | ||||
|         run: | | ||||
|           docker build . # will run buildx | ||||
| ``` | ||||
							
								
								
									
										29
									
								
								docs/advanced/standalone.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								docs/advanced/standalone.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| # Standalone mode | ||||
|  | ||||
| If you don't have the Docker CLI installed on the GitHub Runner, Buildx binary | ||||
| is invoked directly, instead of calling it as a docker plugin. This can be | ||||
| useful if you want to use the `kubernetes` driver in your self-hosted runner: | ||||
|  | ||||
| ```yaml | ||||
| name: ci | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           driver: kubernetes | ||||
|       - | ||||
|         name: Build | ||||
|         run: | | ||||
|           buildx build . | ||||
| ``` | ||||
| @@ -1,10 +1,13 @@ | ||||
| module.exports = { | ||||
|   clearMocks: true, | ||||
|   moduleFileExtensions: ['js', 'ts'], | ||||
|   setupFiles: ["dotenv/config"], | ||||
|   setupFiles: ['dotenv/config'], | ||||
|   testMatch: ['**/*.test.ts'], | ||||
|   transform: { | ||||
|     '^.+\\.ts$': 'ts-jest' | ||||
|   }, | ||||
|   moduleNameMapper: { | ||||
|     '^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs' | ||||
|   }, | ||||
|   verbose: true | ||||
| } | ||||
| }; | ||||
|   | ||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @@ -27,13 +27,15 @@ | ||||
|   ], | ||||
|   "license": "Apache-2.0", | ||||
|   "dependencies": { | ||||
|     "@actions/core": "^1.6.0", | ||||
|     "@actions/core": "^1.10.0", | ||||
|     "@actions/exec": "^1.1.1", | ||||
|     "@actions/http-client": "^1.0.11", | ||||
|     "@actions/tool-cache": "^1.7.2", | ||||
|     "@actions/http-client": "^2.0.1", | ||||
|     "@actions/tool-cache": "^2.0.1", | ||||
|     "csv-parse": "^5.3.1", | ||||
|     "js-yaml": "^4.1.0", | ||||
|     "semver": "^7.3.7", | ||||
|     "tmp": "^0.2.1", | ||||
|     "uuid": "^8.3.2" | ||||
|     "uuid": "^9.0.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/node": "^16.11.26", | ||||
|   | ||||
							
								
								
									
										51
									
								
								src/auth.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/auth.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| import * as fs from 'fs'; | ||||
|  | ||||
| export const envPrefix = 'BUILDER_NODE'; | ||||
|  | ||||
| export function setCredentials(credsdir: string, index: number, driver: string, endpoint: string): Array<string> { | ||||
|   let url: URL; | ||||
|   try { | ||||
|     url = new URL(endpoint); | ||||
|   } catch (e) { | ||||
|     return []; | ||||
|   } | ||||
|   switch (url.protocol) { | ||||
|     case 'tcp:': { | ||||
|       return setBuildKitClientCerts(credsdir, index, driver, url); | ||||
|     } | ||||
|   } | ||||
|   return []; | ||||
| } | ||||
|  | ||||
| function setBuildKitClientCerts(credsdir: string, index: number, driver: string, endpoint: URL): Array<string> { | ||||
|   const driverOpts: Array<string> = []; | ||||
|   const buildkitCacert = process.env[`${envPrefix}_${index}_AUTH_TLS_CACERT`] || ''; | ||||
|   const buildkitCert = process.env[`${envPrefix}_${index}_AUTH_TLS_CERT`] || ''; | ||||
|   const buildkitKey = process.env[`${envPrefix}_${index}_AUTH_TLS_KEY`] || ''; | ||||
|   if (buildkitCacert.length == 0 && buildkitCert.length == 0 && buildkitKey.length == 0) { | ||||
|     return driverOpts; | ||||
|   } | ||||
|   let host = endpoint.hostname; | ||||
|   if (endpoint.port.length > 0) { | ||||
|     host += `-${endpoint.port}`; | ||||
|   } | ||||
|   if (buildkitCacert.length > 0) { | ||||
|     const cacertpath = `${credsdir}/cacert_${host}.pem`; | ||||
|     fs.writeFileSync(cacertpath, buildkitCacert); | ||||
|     driverOpts.push(`cacert=${cacertpath}`); | ||||
|   } | ||||
|   if (buildkitCert.length > 0) { | ||||
|     const certpath = `${credsdir}/cert_${host}.pem`; | ||||
|     fs.writeFileSync(certpath, buildkitCert); | ||||
|     driverOpts.push(`cert=${certpath}`); | ||||
|   } | ||||
|   if (buildkitKey.length > 0) { | ||||
|     const keypath = `${credsdir}/key_${host}.pem`; | ||||
|     fs.writeFileSync(keypath, buildkitKey); | ||||
|     driverOpts.push(`key=${keypath}`); | ||||
|   } | ||||
|   if (driver != 'remote') { | ||||
|     return []; | ||||
|   } | ||||
|   return driverOpts; | ||||
| } | ||||
							
								
								
									
										129
									
								
								src/buildx.ts
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								src/buildx.ts
									
									
									
									
									
								
							| @@ -12,11 +12,17 @@ import * as tc from '@actions/tool-cache'; | ||||
| export type Builder = { | ||||
|   name?: string; | ||||
|   driver?: string; | ||||
|   node_name?: string; | ||||
|   node_endpoint?: string; | ||||
|   node_status?: string; | ||||
|   node_flags?: string; | ||||
|   node_platforms?: string; | ||||
|   nodes: Node[]; | ||||
| }; | ||||
|  | ||||
| export type Node = { | ||||
|   name?: string; | ||||
|   endpoint?: string; | ||||
|   'driver-opts'?: Array<string>; | ||||
|   status?: string; | ||||
|   'buildkitd-flags'?: string; | ||||
|   buildkit?: string; | ||||
|   platforms?: string; | ||||
| }; | ||||
|  | ||||
| export async function getConfigInline(s: string): Promise<string> { | ||||
| @@ -98,48 +104,83 @@ export async function inspect(name: string, standalone?: boolean): Promise<Build | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(res.stderr.trim()); | ||||
|       } | ||||
|       const builder: Builder = {}; | ||||
|       itlines: for (const line of res.stdout.trim().split(`\n`)) { | ||||
|         const [key, ...rest] = line.split(':'); | ||||
|         const value = rest.map(v => v.trim()).join(':'); | ||||
|         if (key.length == 0 || value.length == 0) { | ||||
|           continue; | ||||
|         } | ||||
|         switch (key) { | ||||
|           case 'Name': { | ||||
|             if (builder.name == undefined) { | ||||
|               builder.name = value; | ||||
|             } else { | ||||
|               builder.node_name = value; | ||||
|             } | ||||
|             break; | ||||
|           } | ||||
|           case 'Driver': { | ||||
|             builder.driver = value; | ||||
|             break; | ||||
|           } | ||||
|           case 'Endpoint': { | ||||
|             builder.node_endpoint = value; | ||||
|             break; | ||||
|           } | ||||
|           case 'Status': { | ||||
|             builder.node_status = value; | ||||
|             break; | ||||
|           } | ||||
|           case 'Flags': { | ||||
|             builder.node_flags = value; | ||||
|             break; | ||||
|           } | ||||
|           case 'Platforms': { | ||||
|             builder.node_platforms = value.replace(/\s/g, ''); | ||||
|             break itlines; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       return builder; | ||||
|       return parseInspect(res.stdout); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| export async function parseInspect(data: string): Promise<Builder> { | ||||
|   const builder: Builder = { | ||||
|     nodes: [] | ||||
|   }; | ||||
|   let node: Node = {}; | ||||
|   for (const line of data.trim().split(`\n`)) { | ||||
|     const [key, ...rest] = line.split(':'); | ||||
|     const value = rest.map(v => v.trim()).join(':'); | ||||
|     if (key.length == 0 || value.length == 0) { | ||||
|       continue; | ||||
|     } | ||||
|     switch (key.toLowerCase()) { | ||||
|       case 'name': { | ||||
|         if (builder.name == undefined) { | ||||
|           builder.name = value; | ||||
|         } else { | ||||
|           if (Object.keys(node).length > 0) { | ||||
|             builder.nodes.push(node); | ||||
|             node = {}; | ||||
|           } | ||||
|           node.name = value; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case 'driver': { | ||||
|         builder.driver = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'endpoint': { | ||||
|         node.endpoint = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'driver options': { | ||||
|         node['driver-opts'] = (value.match(/(\w+)="([^"]*)"/g) || []).map(v => v.replace(/^(.*)="(.*)"$/g, '$1=$2')); | ||||
|         break; | ||||
|       } | ||||
|       case 'status': { | ||||
|         node.status = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'flags': { | ||||
|         node['buildkitd-flags'] = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'buildkit': { | ||||
|         node.buildkit = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'platforms': { | ||||
|         let platforms: Array<string> = []; | ||||
|         // if a preferred platform is being set then use only these | ||||
|         // https://docs.docker.com/engine/reference/commandline/buildx_inspect/#get-information-about-a-builder-instance | ||||
|         if (value.includes('*')) { | ||||
|           for (const platform of value.split(', ')) { | ||||
|             if (platform.includes('*')) { | ||||
|               platforms.push(platform.replace('*', '')); | ||||
|             } | ||||
|           } | ||||
|         } else { | ||||
|           // otherwise set all platforms available | ||||
|           platforms = value.split(', '); | ||||
|         } | ||||
|         node.platforms = platforms.join(','); | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if (Object.keys(node).length > 0) { | ||||
|     builder.nodes.push(node); | ||||
|   } | ||||
|   return builder; | ||||
| } | ||||
|  | ||||
| export async function build(inputBuildRef: string, dest: string, standalone: boolean): Promise<string> { | ||||
|   // eslint-disable-next-line prefer-const | ||||
|   let [repo, ref] = inputBuildRef.split('#'); | ||||
|   | ||||
							
								
								
									
										113
									
								
								src/context.ts
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								src/context.ts
									
									
									
									
									
								
							| @@ -2,8 +2,11 @@ import fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import path from 'path'; | ||||
| import * as tmp from 'tmp'; | ||||
| import * as uuid from 'uuid'; | ||||
| import {parse} from 'csv-parse/sync'; | ||||
| import * as buildx from './buildx'; | ||||
| import * as nodes from './nodes'; | ||||
| import * as core from '@actions/core'; | ||||
| import {issueCommand} from '@actions/core/lib/command'; | ||||
|  | ||||
| let _tmpDir: string; | ||||
| export const osPlat: string = os.platform(); | ||||
| @@ -22,39 +25,128 @@ export function tmpNameSync(options?: tmp.TmpNameOptions): string { | ||||
|  | ||||
| export interface Inputs { | ||||
|   version: string; | ||||
|   name: string; | ||||
|   driver: string; | ||||
|   driverOpts: string[]; | ||||
|   buildkitdFlags: string; | ||||
|   platforms: string[]; | ||||
|   install: boolean; | ||||
|   use: boolean; | ||||
|   endpoint: string; | ||||
|   config: string; | ||||
|   configInline: string; | ||||
|   append: string; | ||||
| } | ||||
|  | ||||
| export async function getInputs(): Promise<Inputs> { | ||||
|   return { | ||||
|     version: core.getInput('version'), | ||||
|     name: getBuilderName(core.getInput('driver') || 'docker-container'), | ||||
|     driver: core.getInput('driver') || 'docker-container', | ||||
|     driverOpts: await getInputList('driver-opts', true), | ||||
|     buildkitdFlags: core.getInput('buildkitd-flags') || '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|     platforms: await getInputList('platforms', false, true), | ||||
|     install: core.getBooleanInput('install'), | ||||
|     use: core.getBooleanInput('use'), | ||||
|     endpoint: core.getInput('endpoint'), | ||||
|     config: core.getInput('config'), | ||||
|     configInline: core.getInput('config-inline') | ||||
|     configInline: core.getInput('config-inline'), | ||||
|     append: core.getInput('append') | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> { | ||||
| export function getBuilderName(driver: string): string { | ||||
|   return driver == 'docker' ? 'default' : `builder-${uuid.v4()}`; | ||||
| } | ||||
|  | ||||
| export async function getCreateArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> { | ||||
|   const args: Array<string> = ['create', '--name', inputs.name, '--driver', inputs.driver]; | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.3.0')) { | ||||
|     await asyncForEach(inputs.driverOpts, async driverOpt => { | ||||
|       args.push('--driver-opt', driverOpt); | ||||
|     }); | ||||
|     if (inputs.driver != 'remote' && inputs.buildkitdFlags) { | ||||
|       args.push('--buildkitd-flags', inputs.buildkitdFlags); | ||||
|     } | ||||
|   } | ||||
|   if (inputs.platforms.length > 0) { | ||||
|     args.push('--platform', inputs.platforms.join(',')); | ||||
|   } | ||||
|   if (inputs.use) { | ||||
|     args.push('--use'); | ||||
|   } | ||||
|   if (inputs.driver != 'remote') { | ||||
|     if (inputs.config) { | ||||
|       args.push('--config', await buildx.getConfigFile(inputs.config)); | ||||
|     } else if (inputs.configInline) { | ||||
|       args.push('--config', await buildx.getConfigInline(inputs.configInline)); | ||||
|     } | ||||
|   } | ||||
|   if (inputs.endpoint) { | ||||
|     args.push(inputs.endpoint); | ||||
|   } | ||||
|   return args; | ||||
| } | ||||
|  | ||||
| export async function getAppendArgs(inputs: Inputs, node: nodes.Node, buildxVersion: string): Promise<Array<string>> { | ||||
|   const args: Array<string> = ['create', '--name', inputs.name, '--append']; | ||||
|   if (node.name) { | ||||
|     args.push('--node', node.name); | ||||
|   } | ||||
|   if (node['driver-opts'] && buildx.satisfies(buildxVersion, '>=0.3.0')) { | ||||
|     await asyncForEach(node['driver-opts'], async driverOpt => { | ||||
|       args.push('--driver-opt', driverOpt); | ||||
|     }); | ||||
|     if (inputs.driver != 'remote' && node['buildkitd-flags']) { | ||||
|       args.push('--buildkitd-flags', node['buildkitd-flags']); | ||||
|     } | ||||
|   } | ||||
|   if (node.platforms) { | ||||
|     args.push('--platform', node.platforms); | ||||
|   } | ||||
|   if (node.endpoint) { | ||||
|     args.push(node.endpoint); | ||||
|   } | ||||
|   return args; | ||||
| } | ||||
|  | ||||
| export async function getInspectArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> { | ||||
|   const args: Array<string> = ['inspect', '--bootstrap']; | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.4.0')) { | ||||
|     args.push('--builder', inputs.name); | ||||
|   } | ||||
|   return args; | ||||
| } | ||||
|  | ||||
| export async function getInputList(name: string, ignoreComma?: boolean, escapeQuotes?: boolean): Promise<string[]> { | ||||
|   const res: Array<string> = []; | ||||
|  | ||||
|   const items = core.getInput(name); | ||||
|   if (items == '') { | ||||
|     return []; | ||||
|     return res; | ||||
|   } | ||||
|   return items | ||||
|     .split(/\r?\n/) | ||||
|     .filter(x => x) | ||||
|     .reduce<string[]>((acc, line) => acc.concat(!ignoreComma ? line.split(',').filter(x => x) : line).map(pat => pat.trim()), []); | ||||
|  | ||||
|   const records = parse(items, { | ||||
|     columns: false, | ||||
|     relaxQuotes: true, | ||||
|     comment: '#', | ||||
|     relaxColumnCount: true, | ||||
|     skipEmptyLines: true, | ||||
|     quote: escapeQuotes ? `"` : false | ||||
|   }); | ||||
|  | ||||
|   for (const record of records as Array<string[]>) { | ||||
|     if (record.length == 1) { | ||||
|       res.push(record[0]); | ||||
|       continue; | ||||
|     } else if (!ignoreComma) { | ||||
|       res.push(...record); | ||||
|       continue; | ||||
|     } | ||||
|     res.push(record.join(',')); | ||||
|   } | ||||
|  | ||||
|   return res.filter(item => item).map(pat => pat.trim()); | ||||
| } | ||||
|  | ||||
| export const asyncForEach = async (array, callback) => { | ||||
| @@ -62,8 +154,3 @@ export const asyncForEach = async (array, callback) => { | ||||
|     await callback(array[index], index, array); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // FIXME: Temp fix https://github.com/actions/toolkit/issues/777 | ||||
| export function setOutput(name: string, value: unknown): void { | ||||
|   issueCommand('set-output', {name}, value); | ||||
| } | ||||
|   | ||||
							
								
								
									
										99
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								src/main.ts
									
									
									
									
									
								
							| @@ -1,9 +1,11 @@ | ||||
| import * as fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import * as uuid from 'uuid'; | ||||
| import * as auth from './auth'; | ||||
| import * as buildx from './buildx'; | ||||
| import * as context from './context'; | ||||
| import * as docker from './docker'; | ||||
| import * as nodes from './nodes'; | ||||
| import * as stateHelper from './state-helper'; | ||||
| import * as util from './util'; | ||||
| import * as core from '@actions/core'; | ||||
| @@ -52,46 +54,44 @@ async function run(): Promise<void> { | ||||
|       }); | ||||
|     }); | ||||
|  | ||||
|     const builderName: string = inputs.driver == 'docker' ? 'default' : `builder-${uuid.v4()}`; | ||||
|     context.setOutput('name', builderName); | ||||
|     stateHelper.setBuilderName(builderName); | ||||
|     core.setOutput('name', inputs.name); | ||||
|     stateHelper.setBuilderName(inputs.name); | ||||
|  | ||||
|     const credsdir = path.join(dockerConfigHome, 'buildx', 'creds', inputs.name); | ||||
|     fs.mkdirSync(credsdir, {recursive: true}); | ||||
|     stateHelper.setCredsDir(credsdir); | ||||
|  | ||||
|     if (inputs.driver !== 'docker') { | ||||
|       core.startGroup(`Creating a new builder instance`); | ||||
|       const createArgs: Array<string> = ['create', '--name', builderName, '--driver', inputs.driver]; | ||||
|       if (buildx.satisfies(buildxVersion, '>=0.3.0')) { | ||||
|         await context.asyncForEach(inputs.driverOpts, async driverOpt => { | ||||
|           createArgs.push('--driver-opt', driverOpt); | ||||
|         }); | ||||
|         if (inputs.buildkitdFlags) { | ||||
|           createArgs.push('--buildkitd-flags', inputs.buildkitdFlags); | ||||
|         } | ||||
|       const authOpts = auth.setCredentials(credsdir, 0, inputs.driver, inputs.endpoint); | ||||
|       if (authOpts.length > 0) { | ||||
|         inputs.driverOpts = [...inputs.driverOpts, ...authOpts]; | ||||
|       } | ||||
|       if (inputs.use) { | ||||
|         createArgs.push('--use'); | ||||
|       } | ||||
|       if (inputs.endpoint) { | ||||
|         createArgs.push(inputs.endpoint); | ||||
|       } | ||||
|       if (inputs.config) { | ||||
|         createArgs.push('--config', await buildx.getConfigFile(inputs.config)); | ||||
|       } else if (inputs.configInline) { | ||||
|         createArgs.push('--config', await buildx.getConfigInline(inputs.configInline)); | ||||
|       } | ||||
|       const createCmd = buildx.getCommand(createArgs, standalone); | ||||
|       const createCmd = buildx.getCommand(await context.getCreateArgs(inputs, buildxVersion), standalone); | ||||
|       await exec.exec(createCmd.commandLine, createCmd.args); | ||||
|       core.endGroup(); | ||||
|     } | ||||
|  | ||||
|       core.startGroup(`Booting builder`); | ||||
|       const bootstrapArgs: Array<string> = ['inspect', '--bootstrap']; | ||||
|       if (buildx.satisfies(buildxVersion, '>=0.4.0')) { | ||||
|         bootstrapArgs.push('--builder', builderName); | ||||
|     if (inputs.append) { | ||||
|       core.startGroup(`Appending node(s) to builder`); | ||||
|       let nodeIndex = 1; | ||||
|       for (const node of nodes.Parse(inputs.append)) { | ||||
|         const authOpts = auth.setCredentials(credsdir, nodeIndex, inputs.driver, node.endpoint || ''); | ||||
|         if (authOpts.length > 0) { | ||||
|           node['driver-opts'] = [...(node['driver-opts'] || []), ...authOpts]; | ||||
|         } | ||||
|         const appendCmd = buildx.getCommand(await context.getAppendArgs(inputs, node, buildxVersion), standalone); | ||||
|         await exec.exec(appendCmd.commandLine, appendCmd.args); | ||||
|         nodeIndex++; | ||||
|       } | ||||
|       const bootstrapCmd = buildx.getCommand(bootstrapArgs, standalone); | ||||
|       await exec.exec(bootstrapCmd.commandLine, bootstrapCmd.args); | ||||
|       core.endGroup(); | ||||
|     } | ||||
|  | ||||
|     core.startGroup(`Booting builder`); | ||||
|     const inspectCmd = buildx.getCommand(await context.getInspectArgs(inputs, buildxVersion), standalone); | ||||
|     await exec.exec(inspectCmd.commandLine, inspectCmd.args); | ||||
|     core.endGroup(); | ||||
|  | ||||
|     if (inputs.install) { | ||||
|       if (standalone) { | ||||
|         throw new Error(`Cannot set buildx as default builder without the Docker CLI`); | ||||
| @@ -102,22 +102,36 @@ async function run(): Promise<void> { | ||||
|     } | ||||
|  | ||||
|     core.startGroup(`Inspect builder`); | ||||
|     const builder = await buildx.inspect(builderName, standalone); | ||||
|     const builder = await buildx.inspect(inputs.name, standalone); | ||||
|     const firstNode = builder.nodes[0]; | ||||
|     const reducedPlatforms: Array<string> = []; | ||||
|     for (const node of builder.nodes) { | ||||
|       for (const platform of node.platforms?.split(',') || []) { | ||||
|         if (reducedPlatforms.indexOf(platform) > -1) { | ||||
|           continue; | ||||
|         } | ||||
|         reducedPlatforms.push(platform); | ||||
|       } | ||||
|     } | ||||
|     core.info(JSON.stringify(builder, undefined, 2)); | ||||
|     context.setOutput('driver', builder.driver); | ||||
|     context.setOutput('endpoint', builder.node_endpoint); | ||||
|     context.setOutput('status', builder.node_status); | ||||
|     context.setOutput('flags', builder.node_flags); | ||||
|     context.setOutput('platforms', builder.node_platforms); | ||||
|     core.setOutput('driver', builder.driver); | ||||
|     core.setOutput('platforms', reducedPlatforms.join(',')); | ||||
|     core.setOutput('nodes', JSON.stringify(builder.nodes, undefined, 2)); | ||||
|     core.setOutput('endpoint', firstNode.endpoint); // TODO: deprecated, to be removed in a later version | ||||
|     core.setOutput('status', firstNode.status); // TODO: deprecated, to be removed in a later version | ||||
|     core.setOutput('flags', firstNode['buildkitd-flags']); // TODO: deprecated, to be removed in a later version | ||||
|     core.endGroup(); | ||||
|  | ||||
|     if (!standalone && inputs.driver == 'docker-container') { | ||||
|       stateHelper.setContainerName(`buildx_buildkit_${builder.node_name}`); | ||||
|     if (!standalone && builder.driver == 'docker-container') { | ||||
|       stateHelper.setContainerName(`buildx_buildkit_${firstNode.name}`); | ||||
|       core.startGroup(`BuildKit version`); | ||||
|       core.info(await buildx.getBuildKitVersion(`buildx_buildkit_${builder.node_name}`)); | ||||
|       for (const node of builder.nodes) { | ||||
|         const bkvers = await buildx.getBuildKitVersion(`buildx_buildkit_${node.name}`); | ||||
|         core.info(`${node.name}: ${bkvers}`); | ||||
|       } | ||||
|       core.endGroup(); | ||||
|     } | ||||
|     if (core.isDebug() || builder.node_flags?.includes('--debug')) { | ||||
|     if (core.isDebug() || firstNode['buildkitd-flags']?.includes('--debug')) { | ||||
|       stateHelper.setDebug('true'); | ||||
|     } | ||||
|   } catch (error) { | ||||
| @@ -154,6 +168,11 @@ async function cleanup(): Promise<void> { | ||||
|       }); | ||||
|     core.endGroup(); | ||||
|   } | ||||
|  | ||||
|   if (stateHelper.credsDir.length > 0 && fs.existsSync(stateHelper.credsDir)) { | ||||
|     core.info(`Cleaning up credentials`); | ||||
|     fs.rmSync(stateHelper.credsDir, {recursive: true}); | ||||
|   } | ||||
| } | ||||
|  | ||||
| if (!stateHelper.IsPost) { | ||||
|   | ||||
							
								
								
									
										13
									
								
								src/nodes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/nodes.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| import * as yaml from 'js-yaml'; | ||||
|  | ||||
| export type Node = { | ||||
|   name?: string; | ||||
|   endpoint?: string; | ||||
|   'driver-opts'?: Array<string>; | ||||
|   'buildkitd-flags'?: string; | ||||
|   platforms?: string; | ||||
| }; | ||||
|  | ||||
| export function Parse(data: string): Node[] { | ||||
|   return yaml.load(data) as Node[]; | ||||
| } | ||||
| @@ -5,6 +5,7 @@ export const IsDebug = !!process.env['STATE_isDebug']; | ||||
| export const standalone = process.env['STATE_standalone'] || ''; | ||||
| export const builderName = process.env['STATE_builderName'] || ''; | ||||
| export const containerName = process.env['STATE_containerName'] || ''; | ||||
| export const credsDir = process.env['STATE_credsDir'] || ''; | ||||
|  | ||||
| export function setDebug(debug: string) { | ||||
|   core.saveState('isDebug', debug); | ||||
| @@ -22,6 +23,10 @@ export function setContainerName(containerName: string) { | ||||
|   core.saveState('containerName', containerName); | ||||
| } | ||||
|  | ||||
| export function setCredsDir(credsDir: string) { | ||||
|   core.saveState('credsDir', credsDir); | ||||
| } | ||||
|  | ||||
| if (!IsPost) { | ||||
|   core.saveState('isPost', 'true'); | ||||
| } | ||||
|   | ||||
							
								
								
									
										43
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -2,12 +2,13 @@ | ||||
| # yarn lockfile v1 | ||||
|  | ||||
|  | ||||
| "@actions/core@^1.2.6", "@actions/core@^1.6.0": | ||||
|   version "1.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.6.0.tgz#0568e47039bfb6a9170393a73f3b7eb3b22462cb" | ||||
|   integrity sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw== | ||||
| "@actions/core@^1.10.0", "@actions/core@^1.2.6": | ||||
|   version "1.10.0" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.10.0.tgz#44551c3c71163949a2f06e94d9ca2157a0cfac4f" | ||||
|   integrity sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug== | ||||
|   dependencies: | ||||
|     "@actions/http-client" "^1.0.11" | ||||
|     "@actions/http-client" "^2.0.1" | ||||
|     uuid "^8.3.2" | ||||
|  | ||||
| "@actions/exec@^1.0.0", "@actions/exec@^1.1.1": | ||||
|   version "1.1.1" | ||||
| @@ -16,26 +17,26 @@ | ||||
|   dependencies: | ||||
|     "@actions/io" "^1.0.1" | ||||
|  | ||||
| "@actions/http-client@^1.0.11", "@actions/http-client@^1.0.8": | ||||
|   version "1.0.11" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-1.0.11.tgz#c58b12e9aa8b159ee39e7dd6cbd0e91d905633c0" | ||||
|   integrity sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg== | ||||
| "@actions/http-client@^2.0.1": | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.0.1.tgz#873f4ca98fe32f6839462a6f046332677322f99c" | ||||
|   integrity sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw== | ||||
|   dependencies: | ||||
|     tunnel "0.0.6" | ||||
|     tunnel "^0.0.6" | ||||
|  | ||||
| "@actions/io@^1.0.1", "@actions/io@^1.1.1": | ||||
|   version "1.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/io/-/io-1.1.1.tgz#4a157406309e212ab27ed3ae30e8c1d641686a66" | ||||
|   integrity sha512-Qi4JoKXjmE0O67wAOH6y0n26QXhMKMFo7GD/4IXNVcrtLjUlGjGuVys6pQgwF3ArfGTQu0XpqaNr0YhED2RaRA== | ||||
|  | ||||
| "@actions/tool-cache@^1.7.2": | ||||
|   version "1.7.2" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-1.7.2.tgz#389ad15916f91999959c6b2865144839ecc571a9" | ||||
|   integrity sha512-GYlcgg/PK2RWBrGG2sFg6s7im3S94LMKuqAv8UPDq/pGTZbuEvmN4a95Fn1Z19OE+vt7UbUHeewOD5tEBT+4TQ== | ||||
| "@actions/tool-cache@^2.0.1": | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-2.0.1.tgz#8a649b9c07838d9d750c9864814e66a7660ab720" | ||||
|   integrity sha512-iPU+mNwrbA8jodY8eyo/0S/QqCKDajiR8OxWTnSk/SnYg0sj8Hp4QcUEVC1YFpHWXtrfbQrE13Jz4k4HXJQKcA== | ||||
|   dependencies: | ||||
|     "@actions/core" "^1.2.6" | ||||
|     "@actions/exec" "^1.0.0" | ||||
|     "@actions/http-client" "^1.0.8" | ||||
|     "@actions/http-client" "^2.0.1" | ||||
|     "@actions/io" "^1.1.1" | ||||
|     semver "^6.1.0" | ||||
|     uuid "^3.3.2" | ||||
| @@ -1449,6 +1450,11 @@ cssstyle@^2.3.0: | ||||
|   dependencies: | ||||
|     cssom "~0.3.6" | ||||
|  | ||||
| csv-parse@^5.3.1: | ||||
|   version "5.3.1" | ||||
|   resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-5.3.1.tgz#78b028eb2d2a3e16e62ee8abe710ff7a0b1f8b3b" | ||||
|   integrity sha512-R4Hv6eGJNzgcKdThZ6XORbSQ873HVcNke74QIq+LbwpT90LaZ8Xzl7KKiuIP16xq/P7ofzRt0h7S0xm+fVScsw== | ||||
|  | ||||
| data-urls@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" | ||||
| @@ -3351,7 +3357,7 @@ tsutils@^3.21.0: | ||||
|   dependencies: | ||||
|     tslib "^1.8.1" | ||||
|  | ||||
| tunnel@0.0.6: | ||||
| tunnel@^0.0.6: | ||||
|   version "0.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" | ||||
|   integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== | ||||
| @@ -3419,6 +3425,11 @@ uuid@^8.3.2: | ||||
|   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" | ||||
|   integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== | ||||
|  | ||||
| uuid@^9.0.0: | ||||
|   version "9.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" | ||||
|   integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== | ||||
|  | ||||
| v8-compile-cache-lib@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user