Compare commits
	
		
			64 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | abe5d8f79a | ||
|   | 580d5c72a2 | ||
|   | e673438944 | ||
|   | f40e8894f1 | ||
|   | a1c666d855 | ||
|   | d5b70f51d8 | ||
|   | 2e941f2def | ||
|   | eef74457f7 | ||
|   | e168301d39 | ||
|   | 29f1eeb9e5 | ||
|   | faca7837b0 | ||
|   | dffa64995b | ||
|   | c0e291b502 | ||
|   | 2323559062 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | e80b8cc6d8 | ||
|   | 31e7cc5f84 | ||
|   | 9db0a23fb3 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 90e26af07a | ||
|   | 01ed3f7910 | ||
|   | 11ae4c31f6 | ||
|   | 983bf3e000 | ||
|   | 9a462131b5 | ||
|   | 1806a02fac | ||
|   | c1f17c078a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 76bfd425d8 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 5a93241d03 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 2f13c4010e | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 1dd5af0c3a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 55dd79473c | ||
|   | b1f1f719c7 | ||
|   | 68810d1ede | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | cd8b844a0a | ||
|   | 894f000c27 | ||
|   | f080c7125b | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 49b8353604 | ||
|   | 0d135e0c2f | ||
|   | 36d8e005ca | ||
|   | 012185ccbe | ||
|   | 881cacd606 | ||
|   | 076026291d | ||
|   | f4b1b8d38d | ||
|   | 316c3e4a7c | ||
|   | 5b1c96aee8 | ||
|   | 0f034385ce | ||
|   | 72750233ac | ||
|   | abdb186058 | ||
|   | 9b365965c1 | ||
|   | 583a3147f8 | ||
|   | 2913c18445 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 26e1d017b6 | ||
|   | 2a4b53665e | ||
|   | 03951fea2c | ||
|   | 04f80b2fda | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 240d54e928 | ||
|   | 070ea47eff | ||
|   | d3872b2920 | ||
|   | cb02c5f3d1 | ||
|   | f0d07f4abd | ||
|   | 31740423d9 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | f25fc8d621 | ||
|   | 8d9ae5d563 | ||
|   | 33d65376eb | ||
|   | 4ad06cec8a | ||
|   | bae85ae215 | 
							
								
								
									
										2
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | /coverage | ||||||
|  | /node_modules | ||||||
							
								
								
									
										33
									
								
								.github/CONTRIBUTING.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								.github/CONTRIBUTING.md
									
									
									
									
										vendored
									
									
								
							| @@ -2,35 +2,24 @@ | |||||||
|  |  | ||||||
| Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. | Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. | ||||||
|  |  | ||||||
| Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE). | Contributions to this project are [released](https://docs.github.com/en/github/site-policy/github-terms-of-service#6-contributions-under-repository-license) | ||||||
|  | to the public under the [project's open source license](LICENSE). | ||||||
|  |  | ||||||
| ## Submitting a pull request | ## Submitting a pull request | ||||||
|  |  | ||||||
| 1. [Fork](https://github.com/docker/setup-buildx-action/fork) and clone the repository | 1. [Fork](https://github.com/docker/setup-buildx-action/fork) and clone the repository | ||||||
| 2. Configure and install the dependencies: `yarn install` | 2. Configure and install the dependencies: `yarn install` | ||||||
| 3. Create a new branch: `git checkout -b my-branch-name` | 3. Create a new branch: `git checkout -b my-branch-name` | ||||||
| 4. Make your change, add tests, and make sure the tests still pass | 4. Make your changes | ||||||
| 5. Run pre-checkin: `yarn run pre-checkin` | 5. Make sure the tests pass: `docker buildx bake test` | ||||||
| 6. Push to your fork and [submit a pull request](https://github.com/docker/setup-buildx-action/compare) | 6. Format code and build javascript artifacts: `docker buildx bake pre-checkin` | ||||||
| 7. Pat yourself on the back and wait for your pull request to be reviewed and merged. | 7. Validate all code has correctly formatted and built: `docker buildx bake validate` | ||||||
|  | 8. Push to your fork and [submit a pull request](https://github.com/docker/setup-buildx-action/compare) | ||||||
| ## Container based developer flow | 9. Pat your self on the back and wait for your pull request to be reviewed and merged. | ||||||
|  |  | ||||||
| If you don't want to maintain a Node developer environment that fits this project you can use containerized commands instead of invoking yarn directly. |  | ||||||
|  |  | ||||||
| ``` |  | ||||||
| # format code and build javascript artifacts |  | ||||||
| docker buildx bake pre-checkin |  | ||||||
|  |  | ||||||
| # validate all code has correctly formatted and built |  | ||||||
| docker buildx bake validate |  | ||||||
|  |  | ||||||
| # run tests |  | ||||||
| docker buildx bake test |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| Here are a few things you can do that will increase the likelihood of your pull request being accepted: | Here are a few things you can do that will increase the likelihood of your pull request being accepted: | ||||||
|  |  | ||||||
|  | - Write tests. | ||||||
| - Make sure the `README.md` and any other relevant **documentation are kept up-to-date**. | - Make sure the `README.md` and any other relevant **documentation are kept up-to-date**. | ||||||
| - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. | - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. | ||||||
| - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as **separate pull requests**. | - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as **separate pull requests**. | ||||||
| @@ -39,5 +28,5 @@ Here are a few things you can do that will increase the likelihood of your pull | |||||||
| ## Resources | ## Resources | ||||||
|  |  | ||||||
| - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) | - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) | ||||||
| - [Using Pull Requests](https://help.github.com/articles/about-pull-requests/) | - [Using Pull Requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) | ||||||
| - [GitHub Help](https://help.github.com) | - [GitHub Help](https://docs.github.com/en) | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							| @@ -30,4 +30,5 @@ about: Create a report to help us improve | |||||||
|  |  | ||||||
| ### Logs | ### Logs | ||||||
|  |  | ||||||
| > Download the [log file of your build](https://help.github.com/en/actions/configuring-and-managing-workflows/managing-a-workflow-run#downloading-logs) and [attach it](https://help.github.com/en/github/managing-your-work-on-github/file-attachments-on-issues-and-pull-requests) to this issue. | > Download the [log file of your build](https://docs.github.com/en/actions/managing-workflow-runs/using-workflow-run-logs#downloading-logs) | ||||||
|  | > and [attach it](https://docs.github.com/en/github/managing-your-work-on-github/file-attachments-on-issues-and-pull-requests) to this issue. | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								.github/buildkit-container-logs.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								.github/buildkit-container-logs.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 13 KiB | 
							
								
								
									
										77
									
								
								.github/labels.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								.github/labels.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,77 +0,0 @@ | |||||||
| ## more info https://github.com/crazy-max/ghaction-github-labeler |  | ||||||
| - # automerge |  | ||||||
|   name: ":bell: automerge" |  | ||||||
|   color: "8f4fbc" |  | ||||||
|   description: "" |  | ||||||
| - # bot |  | ||||||
|   name: ":robot: bot" |  | ||||||
|   color: "69cde9" |  | ||||||
|   description: "" |  | ||||||
| - # bug |  | ||||||
|   name: ":bug: bug" |  | ||||||
|   color: "b60205" |  | ||||||
|   description: "" |  | ||||||
| - # dependencies |  | ||||||
|   name: ":game_die: dependencies" |  | ||||||
|   color: "0366d6" |  | ||||||
|   description: "" |  | ||||||
| - # documentation |  | ||||||
|   name: ":memo: documentation" |  | ||||||
|   color: "c5def5" |  | ||||||
|   description: "" |  | ||||||
| - # duplicate |  | ||||||
|   name: ":busts_in_silhouette: duplicate" |  | ||||||
|   color: "cccccc" |  | ||||||
|   description: "" |  | ||||||
| - # enhancement |  | ||||||
|   name: ":sparkles: enhancement" |  | ||||||
|   color: "0054ca" |  | ||||||
|   description: "" |  | ||||||
| - # feature request |  | ||||||
|   name: ":bulb: feature request" |  | ||||||
|   color: "0e8a16" |  | ||||||
|   description: "" |  | ||||||
| - # feedback |  | ||||||
|   name: ":mega: feedback" |  | ||||||
|   color: "03a9f4" |  | ||||||
|   description: "" |  | ||||||
| - # future maybe |  | ||||||
|   name: ":rocket: future maybe" |  | ||||||
|   color: "fef2c0" |  | ||||||
|   description: "" |  | ||||||
| - # good first issue |  | ||||||
|   name: ":hatching_chick: good first issue" |  | ||||||
|   color: "7057ff" |  | ||||||
|   description: "" |  | ||||||
| - # help wanted |  | ||||||
|   name: ":pray: help wanted" |  | ||||||
|   color: "4caf50" |  | ||||||
|   description: "" |  | ||||||
| - # hold |  | ||||||
|   name: ":hand: hold" |  | ||||||
|   color: "24292f" |  | ||||||
|   description: "" |  | ||||||
| - # invalid |  | ||||||
|   name: ":no_entry_sign: invalid" |  | ||||||
|   color: "e6e6e6" |  | ||||||
|   description: "" |  | ||||||
| - # maybe bug |  | ||||||
|   name: ":interrobang: maybe bug" |  | ||||||
|   color: "ff5722" |  | ||||||
|   description: "" |  | ||||||
| - # needs more info |  | ||||||
|   name: ":thinking: needs more info" |  | ||||||
|   color: "795548" |  | ||||||
|   description: "" |  | ||||||
| - # question |  | ||||||
|   name: ":question: question" |  | ||||||
|   color: "3f51b5" |  | ||||||
|   description: "" |  | ||||||
| - # upstream |  | ||||||
|   name: ":eyes: upstream" |  | ||||||
|   color: "fbca04" |  | ||||||
|   description: "" |  | ||||||
| - # wontfix |  | ||||||
|   name: ":coffin: wontfix" |  | ||||||
|   color: "ffffff" |  | ||||||
|   description: "" |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								.github/setup-buildx-action.png
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								.github/setup-buildx-action.png
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										181
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										181
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,18 +1,18 @@ | |||||||
| name: ci | name: ci | ||||||
|  |  | ||||||
| on: | on: | ||||||
|  |   schedule: | ||||||
|  |     - cron: '0 10 * * *' # everyday at 10am | ||||||
|   push: |   push: | ||||||
|     branches: |     branches: | ||||||
|       - master |       - 'master' | ||||||
|       - releases/v* |       - 'releases/v*' | ||||||
|     paths-ignore: |     tags: | ||||||
|       - "**.md" |       - 'v*' | ||||||
|   pull_request: |   pull_request: | ||||||
|     branches: |     branches: | ||||||
|       - master |       - 'master' | ||||||
|       - releases/v* |       - 'releases/v*' | ||||||
|     paths-ignore: |  | ||||||
|       - "**.md" |  | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   main: |   main: | ||||||
| @@ -35,11 +35,13 @@ jobs: | |||||||
|         with: |         with: | ||||||
|           version: ${{ matrix.buildx-version }} |           version: ${{ matrix.buildx-version }} | ||||||
|       - |       - | ||||||
|         name: Builder instance name |         name: Inspect builder | ||||||
|         run: echo ${{ steps.buildx.outputs.name }} |         run: | | ||||||
|       - |           echo "Name:      ${{ steps.buildx.outputs.name }}" | ||||||
|         name: Available platforms |           echo "Endpoint:  ${{ steps.buildx.outputs.endpoint }}" | ||||||
|         run: echo ${{ steps.buildx.outputs.platforms }} |           echo "Status:    ${{ steps.buildx.outputs.status }}" | ||||||
|  |           echo "Flags:     ${{ steps.buildx.outputs.flags }}" | ||||||
|  |           echo "Platforms: ${{ steps.buildx.outputs.platforms }}" | ||||||
|       - |       - | ||||||
|         name: Dump context |         name: Dump context | ||||||
|         uses: crazy-max/ghaction-dump-context@v1 |         uses: crazy-max/ghaction-dump-context@v1 | ||||||
| @@ -55,15 +57,81 @@ jobs: | |||||||
|         id: buildx1 |         id: buildx1 | ||||||
|         uses: ./ |         uses: ./ | ||||||
|       - |       - | ||||||
|         name: Builder 1 instance name |         name: Inspect builder 1 | ||||||
|         run: echo ${{ steps.buildx1.outputs.name }} |         run: | | ||||||
|  |           echo "Name:      ${{ steps.buildx1.outputs.name }}" | ||||||
|  |           echo "Endpoint:  ${{ steps.buildx1.outputs.endpoint }}" | ||||||
|  |           echo "Status:    ${{ steps.buildx1.outputs.status }}" | ||||||
|  |           echo "Flags:     ${{ steps.buildx1.outputs.flags }}" | ||||||
|  |           echo "Platforms: ${{ steps.buildx1.outputs.platforms }}" | ||||||
|       - |       - | ||||||
|         name: Set up Docker Buildx 2 |         name: Set up Docker Buildx 2 | ||||||
|         id: buildx2 |         id: buildx2 | ||||||
|         uses: ./ |         uses: ./ | ||||||
|       - |       - | ||||||
|         name: Builder 2 instance name |         name: Inspect builder 2 | ||||||
|         run: echo ${{ steps.buildx2.outputs.name }} |         run: | | ||||||
|  |           echo "Name:      ${{ steps.buildx2.outputs.name }}" | ||||||
|  |           echo "Endpoint:  ${{ steps.buildx2.outputs.endpoint }}" | ||||||
|  |           echo "Status:    ${{ steps.buildx2.outputs.status }}" | ||||||
|  |           echo "Flags:     ${{ steps.buildx2.outputs.flags }}" | ||||||
|  |           echo "Platforms: ${{ steps.buildx2.outputs.platforms }}" | ||||||
|  |  | ||||||
|  |   error: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - | ||||||
|  |         name: Checkout | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - | ||||||
|  |         name: Stop docker | ||||||
|  |         run: | | ||||||
|  |           sudo systemctl stop docker | ||||||
|  |       - | ||||||
|  |         name: Set up Docker Buildx | ||||||
|  |         id: buildx | ||||||
|  |         continue-on-error: true | ||||||
|  |         uses: ./ | ||||||
|  |       - | ||||||
|  |         name: Check | ||||||
|  |         run: | | ||||||
|  |           echo "${{ toJson(steps.buildx) }}" | ||||||
|  |           if [ "${{ steps.buildx.outcome }}" != "failure" ] || [ "${{ steps.buildx.conclusion }}" != "success" ]; then | ||||||
|  |             echo "::error::Should have failed" | ||||||
|  |             exit 1 | ||||||
|  |           fi | ||||||
|  |       - | ||||||
|  |         name: Dump context | ||||||
|  |         if: always() | ||||||
|  |         uses: crazy-max/ghaction-dump-context@v1 | ||||||
|  |  | ||||||
|  |   debug: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - | ||||||
|  |         name: Checkout | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - | ||||||
|  |         name: Create Dockerfile | ||||||
|  |         run: | | ||||||
|  |           cat > ./Dockerfile <<EOL | ||||||
|  |           FROM alpine | ||||||
|  |           RUN uname -a | ||||||
|  |           EOL | ||||||
|  |       - | ||||||
|  |         name: Set up QEMU | ||||||
|  |         uses: docker/setup-qemu-action@v1 | ||||||
|  |       - | ||||||
|  |         name: Set up Docker Buildx | ||||||
|  |         uses: ./ | ||||||
|  |         with: | ||||||
|  |           buildkitd-flags: --debug | ||||||
|  |       - | ||||||
|  |         name: Build | ||||||
|  |         uses: docker/build-push-action@v2 | ||||||
|  |         with: | ||||||
|  |           context: . | ||||||
|  |           platforms: linux/amd64,linux/arm64,linux/ppc64le | ||||||
|  |  | ||||||
|   install: |   install: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
| @@ -175,6 +243,40 @@ jobs: | |||||||
|         uses: ./ |         uses: ./ | ||||||
|         with: |         with: | ||||||
|           endpoint: mycontext |           endpoint: mycontext | ||||||
|  |         env: | ||||||
|  |           DOCKER_CONTEXT: mycontext | ||||||
|  |  | ||||||
|  |   config: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - | ||||||
|  |         name: Checkout | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - | ||||||
|  |         name: Create buildkitd conf | ||||||
|  |         run: | | ||||||
|  |           cat > /tmp/buildkitd.toml <<EOL | ||||||
|  |           debug = true | ||||||
|  |           [registry."docker.io"] | ||||||
|  |             mirrors = ["mirror.gcr.io"] | ||||||
|  |           EOL | ||||||
|  |       - | ||||||
|  |         name: Create Dockerfile | ||||||
|  |         run: | | ||||||
|  |           cat > ./Dockerfile <<EOL | ||||||
|  |           FROM alpine | ||||||
|  |           EOL | ||||||
|  |       - | ||||||
|  |         name: Set up Docker Buildx | ||||||
|  |         uses: ./ | ||||||
|  |         with: | ||||||
|  |           buildkitd-flags: --debug | ||||||
|  |           config: /tmp/buildkitd.toml | ||||||
|  |       - | ||||||
|  |         name: Build | ||||||
|  |         uses: docker/build-push-action@v2 | ||||||
|  |         with: | ||||||
|  |           context: . | ||||||
|  |  | ||||||
|   with-qemu: |   with-qemu: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
| @@ -204,8 +306,45 @@ jobs: | |||||||
|         with: |         with: | ||||||
|           version: ${{ matrix.buildx-version }} |           version: ${{ matrix.buildx-version }} | ||||||
|       - |       - | ||||||
|         name: Available platforms |         name: Inspect builder | ||||||
|         run: echo ${{ steps.buildx.outputs.platforms }} |         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 }}" | ||||||
|  |  | ||||||
|  |   build-ref: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         ref: | ||||||
|  |           - master | ||||||
|  |           - refs/tags/v0.5.1 | ||||||
|  |           - refs/pull/648/head | ||||||
|  |           - 67bd6f4dc82a9cd96f34133dab3f6f7af803bb14 | ||||||
|  |     steps: | ||||||
|       - |       - | ||||||
|         name: Builder instance name |         name: Checkout | ||||||
|         run: echo ${{ steps.buildx.outputs.name }} |         uses: actions/checkout@v2 | ||||||
|  |       - | ||||||
|  |         name: Set up Docker Buildx | ||||||
|  |         uses: ./ | ||||||
|  |         with: | ||||||
|  |           version: https://github.com/docker/buildx.git#${{ matrix.ref }} | ||||||
|  |       - | ||||||
|  |         name: Check version | ||||||
|  |         run: | | ||||||
|  |           docker buildx version | ||||||
|  |       - | ||||||
|  |         name: Create Dockerfile | ||||||
|  |         run: | | ||||||
|  |           cat > ./Dockerfile <<EOL | ||||||
|  |           FROM alpine | ||||||
|  |           EOL | ||||||
|  |       - | ||||||
|  |         name: Build | ||||||
|  |         uses: docker/build-push-action@master | ||||||
|  |         with: | ||||||
|  |           context: . | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								.github/workflows/labels.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								.github/workflows/labels.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,20 +0,0 @@ | |||||||
| name: labels |  | ||||||
|  |  | ||||||
| on: |  | ||||||
|   push: |  | ||||||
|     branches: |  | ||||||
|       - 'master' |  | ||||||
|     paths: |  | ||||||
|       - '.github/labels.yml' |  | ||||||
|       - '.github/workflows/labels.yml' |  | ||||||
|  |  | ||||||
| jobs: |  | ||||||
|   labeler: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|       - |  | ||||||
|         name: Checkout |  | ||||||
|         uses: actions/checkout@v2 |  | ||||||
|       - |  | ||||||
|         name: Run Labeler |  | ||||||
|         uses: crazy-max/ghaction-github-labeler@v3 |  | ||||||
							
								
								
									
										39
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @@ -3,28 +3,14 @@ name: test | |||||||
| on: | on: | ||||||
|   push: |   push: | ||||||
|     branches: |     branches: | ||||||
|       - master |       - 'master' | ||||||
|       - releases/v* |       - 'releases/v*' | ||||||
|     paths-ignore: |  | ||||||
|       - "**.md" |  | ||||||
|   pull_request: |   pull_request: | ||||||
|     paths-ignore: |     branches: | ||||||
|       - "**.md" |       - 'master' | ||||||
|  |       - 'releases/v*' | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   test-containerized: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|       - |  | ||||||
|         name: Checkout |  | ||||||
|         uses: actions/checkout@v2 |  | ||||||
|       - |  | ||||||
|         name: Validate |  | ||||||
|         run: docker buildx bake validate |  | ||||||
|       - |  | ||||||
|         name: Test |  | ||||||
|         run: docker buildx bake test |  | ||||||
|  |  | ||||||
|   test: |   test: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
| @@ -32,15 +18,20 @@ jobs: | |||||||
|         name: Checkout |         name: Checkout | ||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|       - |       - | ||||||
|         name: Install |         name: Validate | ||||||
|         run: yarn install |         uses: docker/bake-action@v1 | ||||||
|  |         with: | ||||||
|  |           targets: validate | ||||||
|  |       - | ||||||
|  |         name: Set up Docker Buildx | ||||||
|  |         uses: ./ | ||||||
|       - |       - | ||||||
|         name: Test |         name: Test | ||||||
|         run: yarn run test |         uses: docker/bake-action@v1 | ||||||
|  |         with: | ||||||
|  |           targets: test | ||||||
|       - |       - | ||||||
|         name: Upload coverage |         name: Upload coverage | ||||||
|         uses: codecov/codecov-action@v1 |         uses: codecov/codecov-action@v1 | ||||||
|         if: success() |  | ||||||
|         with: |         with: | ||||||
|           token: ${{ secrets.CODECOV_TOKEN }} |  | ||||||
|           file: ./coverage/clover.xml |           file: ./coverage/clover.xml | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| { | { | ||||||
|   "printWidth": 120, |   "printWidth": 240, | ||||||
|   "tabWidth": 2, |   "tabWidth": 2, | ||||||
|   "useTabs": false, |   "useTabs": false, | ||||||
|   "semi": true, |   "semi": true, | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,52 +0,0 @@ | |||||||
| #syntax=docker/dockerfile:1.1-experimental |  | ||||||
|  |  | ||||||
| FROM node:14 AS deps |  | ||||||
| WORKDIR /src |  | ||||||
| COPY package.json yarn.lock ./ |  | ||||||
| RUN --mount=type=cache,target=/usr/local/share/.cache/yarn \ |  | ||||||
|   yarn install |  | ||||||
|  |  | ||||||
| FROM scratch AS update-yarn |  | ||||||
| COPY --from=deps /src/yarn.lock / |  | ||||||
|  |  | ||||||
| FROM deps AS validate-yarn |  | ||||||
| COPY .git .git |  | ||||||
| RUN status=$(git status --porcelain -- yarn.lock); if [ -n "$status" ]; then echo $status; exit 1; fi |  | ||||||
|  |  | ||||||
| FROM deps AS base |  | ||||||
| COPY . . |  | ||||||
|  |  | ||||||
| FROM base AS build |  | ||||||
| RUN yarn build |  | ||||||
|  |  | ||||||
| FROM deps AS test |  | ||||||
| COPY --from=docker /usr/local/bin/docker /usr/bin/ |  | ||||||
| ARG TARGETOS |  | ||||||
| ARG TARGETARCH |  | ||||||
| ARG BUILDX_VERSION=v0.4.2 |  | ||||||
| ENV RUNNER_TEMP=/tmp/github_runner |  | ||||||
| ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache |  | ||||||
| RUN mkdir -p /usr/local/lib/docker/cli-plugins && \ |  | ||||||
|   curl -fsSL https://github.com/docker/buildx/releases/download/$BUILDX_VERSION/buildx-$BUILDX_VERSION.$TARGETOS-$TARGETARCH > /usr/local/lib/docker/cli-plugins/docker-buildx && \ |  | ||||||
|   chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx && \ |  | ||||||
|   docker buildx version |  | ||||||
| COPY . . |  | ||||||
| RUN yarn run test |  | ||||||
|  |  | ||||||
| FROM base AS run-format |  | ||||||
| RUN yarn run format |  | ||||||
|  |  | ||||||
| FROM scratch AS format |  | ||||||
| COPY --from=run-format /src/src/*.ts /src/ |  | ||||||
|  |  | ||||||
| FROM base AS validate-format |  | ||||||
| RUN yarn run format-check |  | ||||||
|  |  | ||||||
| FROM scratch AS dist |  | ||||||
| COPY --from=build /src/dist/ /dist/ |  | ||||||
|  |  | ||||||
| FROM build AS validate-build |  | ||||||
| RUN status=$(git status --porcelain -- dist); if [ -n "$status" ]; then echo $status; exit 1; fi |  | ||||||
|  |  | ||||||
| FROM base AS dev |  | ||||||
| ENTRYPOINT ["bash"] |  | ||||||
							
								
								
									
										63
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								README.md
									
									
									
									
									
								
							| @@ -8,10 +8,10 @@ | |||||||
|  |  | ||||||
| GitHub Action to set up Docker [Buildx](https://github.com/docker/buildx). | GitHub Action to set up Docker [Buildx](https://github.com/docker/buildx). | ||||||
|  |  | ||||||
| > :bulb: See also: | This action will create and boot a builder that can be used in the following steps of your workflow if you're using | ||||||
| > * [login](https://github.com/docker/login-action) action | [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) | ||||||
| > * [setup-qemu](https://github.com/docker/setup-qemu-action) action | will be used to be able to build multi-platform images and export cache thanks to the [BuildKit](https://github.com/moby/buildkit) | ||||||
| > * [build-push](https://github.com/docker/build-push-action) action | container. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -25,8 +25,9 @@ ___ | |||||||
|   * [inputs](#inputs) |   * [inputs](#inputs) | ||||||
|   * [outputs](#outputs) |   * [outputs](#outputs) | ||||||
|   * [environment variables](#environment-variables) |   * [environment variables](#environment-variables) | ||||||
|  | * [Notes](#notes) | ||||||
|  |   * [BuildKit container logs](#buildkit-container-logs) | ||||||
| * [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot) | * [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot) | ||||||
| * [Limitation](#limitation) |  | ||||||
|  |  | ||||||
| ## Usage | ## Usage | ||||||
|  |  | ||||||
| @@ -50,11 +51,13 @@ jobs: | |||||||
|         id: buildx |         id: buildx | ||||||
|         uses: docker/setup-buildx-action@v1 |         uses: docker/setup-buildx-action@v1 | ||||||
|       - |       - | ||||||
|         name: Builder instance name |         name: Inspect builder | ||||||
|         run: echo ${{ steps.buildx.outputs.name }} |         run: | | ||||||
|       - |           echo "Name:      ${{ steps.buildx.outputs.name }}" | ||||||
|         name: Available platforms |           echo "Endpoint:  ${{ steps.buildx.outputs.endpoint }}" | ||||||
|         run: echo ${{ steps.buildx.outputs.platforms }} |           echo "Status:    ${{ steps.buildx.outputs.status }}" | ||||||
|  |           echo "Flags:     ${{ steps.buildx.outputs.flags }}" | ||||||
|  |           echo "Platforms: ${{ steps.buildx.outputs.platforms }}" | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### With QEMU | ### With QEMU | ||||||
| @@ -122,13 +125,14 @@ Following inputs can be used as `step.with` keys | |||||||
|  |  | ||||||
| | Name               | Type    | Description                       | | | Name               | Type    | Description                       | | ||||||
| |--------------------|---------|-----------------------------------| | |--------------------|---------|-----------------------------------| | ||||||
| | `version`          | String  | [Buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`) | | | `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#--driver-driver) to be used (default `docker-container`) | | | `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#--driver-opt-options) (eg. `image=moby/buildkit:master`) | | | `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)) | | | `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`) | | | `install`          | Bool    | Sets up `docker build` command as an alias to `docker buildx` (default `false`) | | ||||||
| | `use`              | Bool    | Switch to this builder instance (default `true`) | | | `use`              | Bool    | Switch to this builder instance (default `true`) | | ||||||
| | `endpoint`         | String  | [Optional address for docker socket](https://github.com/docker/buildx#buildx-create-options-contextendpoint) or context from `docker context ls` | | | `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) | | ||||||
|  |  | ||||||
| > `CSV` type must be a newline-delimited string | > `CSV` type must be a newline-delimited string | ||||||
| > ```yaml | > ```yaml | ||||||
| @@ -146,8 +150,12 @@ Following outputs are available | |||||||
|  |  | ||||||
| | Name          | Type    | Description                           | | | Name          | Type    | Description                           | | ||||||
| |---------------|---------|---------------------------------------| | |---------------|---------|---------------------------------------| | ||||||
| | `name`        | String  | Builder instance name | | | `name`        | String  | Builder name | | ||||||
| | `platforms`   | String  | Available platforms (comma separated) | | | `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) | | ||||||
|  |  | ||||||
| ### environment variables | ### environment variables | ||||||
|  |  | ||||||
| @@ -157,6 +165,25 @@ The following [official docker environment variables](https://docs.docker.com/en | |||||||
| |-----------------|---------|-------------|-------------------------------------------------| | |-----------------|---------|-------------|-------------------------------------------------| | ||||||
| | `DOCKER_CONFIG` | String  | `~/.docker` | The location of your client configuration files | | | `DOCKER_CONFIG` | String  | `~/.docker` | The location of your client configuration files | | ||||||
|  |  | ||||||
|  | ## Notes | ||||||
|  |  | ||||||
|  | ### BuildKit container logs | ||||||
|  |  | ||||||
|  | To display BuildKit container logs (when `docker-container` driver is used) you have to [enable step debug logging](https://docs.github.com/en/actions/managing-workflow-runs/enabling-debug-logging#enabling-step-debug-logging) | ||||||
|  | or you can also enable debugging in the [setup-buildx action step](https://github.com/docker/setup-buildx-action): | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  |   - | ||||||
|  |     name: Set up Docker Buildx | ||||||
|  |     uses: docker/setup-buildx-action@v1 | ||||||
|  |     with: | ||||||
|  |       buildkitd-flags: --debug | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Logs will be available at the end of a job: | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Keep up-to-date with GitHub Dependabot | ## Keep up-to-date with GitHub Dependabot | ||||||
|  |  | ||||||
| Since [Dependabot](https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-github-dependabot) | Since [Dependabot](https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-github-dependabot) | ||||||
| @@ -172,7 +199,3 @@ updates: | |||||||
|     schedule: |     schedule: | ||||||
|       interval: "daily" |       interval: "daily" | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Limitation |  | ||||||
|  |  | ||||||
| This action is only available for Linux [virtual environments](https://docs.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners#supported-virtual-environments-and-hardware-resources). |  | ||||||
|   | |||||||
| @@ -1,46 +1,111 @@ | |||||||
| import fs = require('fs'); | import * as fs from 'fs'; | ||||||
| import * as docker from '../src/docker'; |  | ||||||
| import * as buildx from '../src/buildx'; |  | ||||||
| import * as path from 'path'; |  | ||||||
| import * as os from 'os'; | import * as os from 'os'; | ||||||
|  | import * as path from 'path'; | ||||||
|  | import * as buildx from '../src/buildx'; | ||||||
|  | import * as context from '../src/context'; | ||||||
| import * as semver from 'semver'; | import * as semver from 'semver'; | ||||||
| import * as exec from '@actions/exec'; | import * as exec from '@actions/exec'; | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | describe('isAvailable', () => { | ||||||
|  |   const execSpy: jest.SpyInstance = jest.spyOn(exec, 'getExecOutput'); | ||||||
|  |   buildx.isAvailable(); | ||||||
|  |  | ||||||
|  |   expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], { | ||||||
|  |     silent: true, | ||||||
|  |     ignoreReturnCode: true | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  |  | ||||||
| describe('getVersion', () => { | describe('getVersion', () => { | ||||||
|   it('valid', async () => { |   async function isDaemonRunning() { | ||||||
|     await exec.exec('docker', ['buildx', 'version']); |     return await exec | ||||||
|     const version = await buildx.getVersion(); |       .getExecOutput(`docker`, ['version', '--format', '{{.Server.Os}}'], { | ||||||
|     console.log(`version: ${version}`); |         ignoreReturnCode: true, | ||||||
|     expect(semver.valid(version)).not.toBeNull(); |         silent: true | ||||||
|   }, 100000); |       }) | ||||||
|  |       .then(res => { | ||||||
|  |         return !res.stdout.trim().includes(' ') && res.exitCode == 0; | ||||||
|  |       }); | ||||||
|  |   } | ||||||
|  |   (isDaemonRunning() ? it : it.skip)( | ||||||
|  |     'valid', | ||||||
|  |     async () => { | ||||||
|  |       const version = await buildx.getVersion(); | ||||||
|  |       console.log(`version: ${version}`); | ||||||
|  |       expect(semver.valid(version)).not.toBeNull(); | ||||||
|  |     }, | ||||||
|  |     100000 | ||||||
|  |   ); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| describe('parseVersion', () => { | describe('parseVersion', () => { | ||||||
|   test.each([ |   test.each([ | ||||||
|     ['github.com/docker/buildx 0.4.1+azure bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'], |     ['github.com/docker/buildx 0.4.1+azure bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'], | ||||||
|     ['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'], |     ['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'], | ||||||
|     ['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'] |     ['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'], | ||||||
|  |     ['github.com/docker/buildx f117971 f11797113e5a9b86bd976329c5dbb8a8bfdfadfa', 'f117971'] | ||||||
|   ])('given %p', async (stdout, expected) => { |   ])('given %p', async (stdout, expected) => { | ||||||
|     expect(await buildx.parseVersion(stdout)).toEqual(expected); |     expect(buildx.parseVersion(stdout)).toEqual(expected); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| describe('platforms', () => { | describe('satisfies', () => { | ||||||
|  |   test.each([ | ||||||
|  |     ['0.4.1', '>=0.3.2', true], | ||||||
|  |     ['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false], | ||||||
|  |     ['f117971', '>0.6.0', true] | ||||||
|  |   ])('given %p', async (version, range, expected) => { | ||||||
|  |     expect(buildx.satisfies(version, range)).toBe(expected); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | describe('inspect', () => { | ||||||
|   async function isDaemonRunning() { |   async function isDaemonRunning() { | ||||||
|     return await docker.isDaemonRunning(); |     return await exec | ||||||
|  |       .getExecOutput(`docker`, ['version', '--format', '{{.Server.Os}}'], { | ||||||
|  |         ignoreReturnCode: true, | ||||||
|  |         silent: true | ||||||
|  |       }) | ||||||
|  |       .then(res => { | ||||||
|  |         return !res.stdout.trim().includes(' ') && res.exitCode == 0; | ||||||
|  |       }); | ||||||
|   } |   } | ||||||
|   (isDaemonRunning() ? it : it.skip)( |   (isDaemonRunning() ? it : it.skip)( | ||||||
|     'valid', |     'valid', | ||||||
|     async () => { |     async () => { | ||||||
|       const platforms = buildx.platforms(); |       const builder = await buildx.inspect(''); | ||||||
|       console.log(`platforms: ${platforms}`); |       console.log('builder', builder); | ||||||
|       expect(platforms).not.toBeUndefined(); |       expect(builder).not.toBeUndefined(); | ||||||
|       expect(platforms).not.toEqual(''); |       expect(builder.name).not.toEqual(''); | ||||||
|  |       expect(builder.driver).not.toEqual(''); | ||||||
|  |       expect(builder.node_platforms).not.toEqual(''); | ||||||
|     }, |     }, | ||||||
|     100000 |     100000 | ||||||
|   ); |   ); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | describe('build', () => { | ||||||
|  |   const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-')); | ||||||
|  |   it.skip('builds refs/pull/648/head', async () => { | ||||||
|  |     const buildxBin = await buildx.build('https://github.com/docker/buildx.git#refs/pull/648/head', tmpDir); | ||||||
|  |     console.log(buildxBin); | ||||||
|  |     expect(fs.existsSync(buildxBin)).toBe(true); | ||||||
|  |   }, 100000); | ||||||
|  |   it.skip('builds 67bd6f4dc82a9cd96f34133dab3f6f7af803bb14', async () => { | ||||||
|  |     const buildxBin = await buildx.build('https://github.com/docker/buildx.git#67bd6f4dc82a9cd96f34133dab3f6f7af803bb14', tmpDir); | ||||||
|  |     console.log(buildxBin); | ||||||
|  |     expect(fs.existsSync(buildxBin)).toBe(true); | ||||||
|  |   }, 100000); | ||||||
|  | }); | ||||||
|  |  | ||||||
| describe('install', () => { | describe('install', () => { | ||||||
|   const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-')); |   const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-')); | ||||||
|   it('acquires v0.4.1 version of buildx', async () => { |   it('acquires v0.4.1 version of buildx', async () => { | ||||||
|   | |||||||
| @@ -1,5 +1,16 @@ | |||||||
|  | import * as fs from 'fs'; | ||||||
|  | import * as os from 'os'; | ||||||
|  | import * as path from 'path'; | ||||||
| import * as context from '../src/context'; | import * as context from '../src/context'; | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  | }); | ||||||
|  |  | ||||||
| describe('getInputList', () => { | describe('getInputList', () => { | ||||||
|   it('handles single line correctly', async () => { |   it('handles single line correctly', async () => { | ||||||
|     await setInput('foo', 'bar'); |     await setInput('foo', 'bar'); | ||||||
| @@ -78,6 +89,27 @@ describe('asyncForEach', () => { | |||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | describe('setOutput', () => { | ||||||
|  |   beforeEach(() => { | ||||||
|  |     process.stdout.write = jest.fn(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('setOutput produces the correct command', () => { | ||||||
|  |     context.setOutput('some output', 'some value'); | ||||||
|  |     assertWriteCalls([`::set-output name=some output::some value${os.EOL}`]); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('setOutput handles bools', () => { | ||||||
|  |     context.setOutput('some output', false); | ||||||
|  |     assertWriteCalls([`::set-output name=some output::false${os.EOL}`]); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('setOutput handles numbers', () => { | ||||||
|  |     context.setOutput('some output', 1.01); | ||||||
|  |     assertWriteCalls([`::set-output name=some output::1.01${os.EOL}`]); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  |  | ||||||
| // See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67 | // See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67 | ||||||
| function getInputName(name: string): string { | function getInputName(name: string): string { | ||||||
|   return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`; |   return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`; | ||||||
| @@ -86,3 +118,11 @@ function getInputName(name: string): string { | |||||||
| function setInput(name: string, value: string): void { | function setInput(name: string, value: string): void { | ||||||
|   process.env[getInputName(name)] = value; |   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]); | ||||||
|  |   } | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								__tests__/git.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								__tests__/git.test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | import * as git from '../src/git'; | ||||||
|  |  | ||||||
|  | describe('git', () => { | ||||||
|  |   it('returns git remote ref', async () => { | ||||||
|  |     const ref: string = await git.getRemoteSha('https://github.com/docker/buildx.git', 'refs/pull/648/head'); | ||||||
|  |     console.log(`ref: ${ref}`); | ||||||
|  |     expect(ref).toEqual('f11797113e5a9b86bd976329c5dbb8a8bfdfadfa'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
							
								
								
									
										11
									
								
								__tests__/util.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								__tests__/util.test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | import * as util from '../src/util'; | ||||||
|  |  | ||||||
|  | describe('isValidUrl', () => { | ||||||
|  |   test.each([ | ||||||
|  |     ['https://github.com/docker/buildx.git', true], | ||||||
|  |     ['https://github.com/docker/buildx.git#refs/pull/648/head', true], | ||||||
|  |     ['v0.4.1', false] | ||||||
|  |   ])('given %p', async (url, expected) => { | ||||||
|  |     expect(util.isValidUrl(url)).toEqual(expected); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
							
								
								
									
										15
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								action.yml
									
									
									
									
									
								
							| @@ -32,12 +32,23 @@ inputs: | |||||||
|   endpoint: |   endpoint: | ||||||
|     description: 'Optional address for docker socket or context from `docker context ls`' |     description: 'Optional address for docker socket or context from `docker context ls`' | ||||||
|     required: false |     required: false | ||||||
|  |   config: | ||||||
|  |     description: 'BuildKit config file' | ||||||
|  |     required: false | ||||||
|  |  | ||||||
| outputs: | outputs: | ||||||
|   name: |   name: | ||||||
|     description: 'Builder instance 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: |   platforms: | ||||||
|     description: 'Available platforms (comma separated)' |     description: 'Builder node platforms available (comma separated)' | ||||||
|  |  | ||||||
| runs: | runs: | ||||||
|   using: 'node12' |   using: 'node12' | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								codecov.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								codecov.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | comment: false | ||||||
|  | github_checks: | ||||||
|  |   annotations: false | ||||||
							
								
								
									
										12322
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12322
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,42 +1,67 @@ | |||||||
|  | variable "NODE_VERSION" { | ||||||
|  |   default = "12" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | target "node-version" { | ||||||
|  |   args = { | ||||||
|  |     NODE_VERSION = NODE_VERSION | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| group "default" { | group "default" { | ||||||
|   targets = ["build"] |   targets = ["build"] | ||||||
| } | } | ||||||
|  |  | ||||||
| group "pre-checkin" { | group "pre-checkin" { | ||||||
|   targets = ["update-yarn", "format", "build"] |   targets = ["vendor-update", "format", "build"] | ||||||
| } | } | ||||||
|  |  | ||||||
| group "validate" { | group "validate" { | ||||||
| 	targets = ["validate-format", "validate-build", "validate-yarn"] |   targets = ["format-validate", "build-validate", "vendor-validate"] | ||||||
| } |  | ||||||
|  |  | ||||||
| target "update-yarn" { |  | ||||||
|   target = "update-yarn" |  | ||||||
|   output = ["."] |  | ||||||
| } | } | ||||||
|  |  | ||||||
| target "build" { | target "build" { | ||||||
|   target = "dist" |   inherits = ["node-version"] | ||||||
|  |   dockerfile = "./hack/build.Dockerfile" | ||||||
|  |   target = "build-update" | ||||||
|   output = ["."] |   output = ["."] | ||||||
| } | } | ||||||
|  |  | ||||||
| target "test" { | target "build-validate" { | ||||||
|   target = "test" |   inherits = ["node-version"] | ||||||
|  |   dockerfile = "./hack/build.Dockerfile" | ||||||
|  |   target = "build-validate" | ||||||
| } | } | ||||||
|  |  | ||||||
| target "format" { | target "format" { | ||||||
|   target = "format" |   inherits = ["node-version"] | ||||||
|  |   dockerfile = "./hack/build.Dockerfile" | ||||||
|  |   target = "format-update" | ||||||
|   output = ["."] |   output = ["."] | ||||||
| } | } | ||||||
|  |  | ||||||
| target "validate-format" { | target "format-validate" { | ||||||
|   target = "validate-format" |   inherits = ["node-version"] | ||||||
|  |   dockerfile = "./hack/build.Dockerfile" | ||||||
|  |   target = "format-validate" | ||||||
| } | } | ||||||
|  |  | ||||||
| target "validate-build" { | target "vendor-update" { | ||||||
|   target = "validate-build" |   inherits = ["node-version"] | ||||||
|  |   dockerfile = "./hack/vendor.Dockerfile" | ||||||
|  |   target = "update" | ||||||
|  |   output = ["."] | ||||||
| } | } | ||||||
|  |  | ||||||
| target "validate-yarn" { | target "vendor-validate" { | ||||||
| 	target = "validate-yarn" |   inherits = ["node-version"] | ||||||
| } |   dockerfile = "./hack/vendor.Dockerfile" | ||||||
|  |   target = "validate" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | target "test" { | ||||||
|  |   inherits = ["node-version"] | ||||||
|  |   dockerfile = "./hack/test.Dockerfile" | ||||||
|  |   target = "test-coverage" | ||||||
|  |   output = ["./coverage"] | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								hack/build.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								hack/build.Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | # syntax=docker/dockerfile:1.2 | ||||||
|  | ARG NODE_VERSION | ||||||
|  |  | ||||||
|  | FROM node:${NODE_VERSION}-alpine AS base | ||||||
|  | RUN apk add --no-cache cpio findutils git | ||||||
|  | WORKDIR /src | ||||||
|  |  | ||||||
|  | FROM base AS deps | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   --mount=type=cache,target=/src/node_modules \ | ||||||
|  |   yarn install | ||||||
|  |  | ||||||
|  | FROM deps AS build | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   --mount=type=cache,target=/src/node_modules \ | ||||||
|  |   yarn run build && mkdir /out && cp -Rf dist /out/ | ||||||
|  |  | ||||||
|  | FROM scratch AS build-update | ||||||
|  | COPY --from=build /out / | ||||||
|  |  | ||||||
|  | FROM build AS build-validate | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   git add -A && cp -rf /out/* .; \ | ||||||
|  |   if [ -n "$(git status --porcelain -- dist)" ]; then \ | ||||||
|  |     echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'; \ | ||||||
|  |     git status --porcelain -- dist; \ | ||||||
|  |     exit 1; \ | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  | FROM deps AS format | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   --mount=type=cache,target=/src/node_modules \ | ||||||
|  |   yarn run format \ | ||||||
|  |   && mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out | ||||||
|  |  | ||||||
|  | FROM scratch AS format-update | ||||||
|  | COPY --from=format /out / | ||||||
|  |  | ||||||
|  | FROM deps AS format-validate | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   --mount=type=cache,target=/src/node_modules \ | ||||||
|  |   yarn run format-check \ | ||||||
| @@ -1,6 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| iidfile=$(mktemp -t docker-iidfile.XXXXXXXXXX) |  | ||||||
| DOCKER_BUILDKIT=1 docker build --iidfile $iidfile --progress=plain . |  | ||||||
| docker run -it --rm $(cat $iidfile) |  | ||||||
| docker rmi $(cat $iidfile) |  | ||||||
							
								
								
									
										23
									
								
								hack/test.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								hack/test.Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | # syntax=docker/dockerfile:1.2 | ||||||
|  | ARG NODE_VERSION | ||||||
|  |  | ||||||
|  | FROM node:${NODE_VERSION}-alpine AS base | ||||||
|  | RUN apk add --no-cache git | ||||||
|  | WORKDIR /src | ||||||
|  |  | ||||||
|  | FROM base AS deps | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   --mount=type=cache,target=/src/node_modules \ | ||||||
|  |   yarn install | ||||||
|  |  | ||||||
|  | FROM deps AS test | ||||||
|  | ENV RUNNER_TEMP=/tmp/github_runner | ||||||
|  | ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   --mount=type=cache,target=/src/node_modules \ | ||||||
|  |   --mount=type=bind,from=crazymax/docker,source=/usr/libexec/docker/cli-plugins/docker-buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \ | ||||||
|  |   --mount=type=bind,from=crazymax/docker,source=/usr/local/bin/docker,target=/usr/bin/docker \ | ||||||
|  |   yarn run test --coverageDirectory=/tmp/coverage | ||||||
|  |  | ||||||
|  | FROM scratch AS test-coverage | ||||||
|  | COPY --from=test /tmp/coverage / | ||||||
							
								
								
									
										23
									
								
								hack/vendor.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								hack/vendor.Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | # syntax=docker/dockerfile:1.2 | ||||||
|  | ARG NODE_VERSION | ||||||
|  |  | ||||||
|  | FROM node:${NODE_VERSION}-alpine AS base | ||||||
|  | RUN apk add --no-cache git | ||||||
|  | WORKDIR /src | ||||||
|  |  | ||||||
|  | FROM base AS vendored | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   --mount=type=cache,target=/src/node_modules \ | ||||||
|  |   yarn install && mkdir /out && cp yarn.lock /out | ||||||
|  |  | ||||||
|  | FROM scratch AS update | ||||||
|  | COPY --from=vendored /out / | ||||||
|  |  | ||||||
|  | FROM vendored AS validate | ||||||
|  | RUN --mount=type=bind,target=.,rw \ | ||||||
|  |   git add -A && cp -rf /out/* .; \ | ||||||
|  |   if [ -n "$(git status --porcelain -- yarn.lock)" ]; then \ | ||||||
|  |     echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'; \ | ||||||
|  |     git status --porcelain -- yarn.lock; \ | ||||||
|  |     exit 1; \ | ||||||
|  |   fi | ||||||
							
								
								
									
										30
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								package.json
									
									
									
									
									
								
							| @@ -27,24 +27,24 @@ | |||||||
|   ], |   ], | ||||||
|   "license": "Apache-2.0", |   "license": "Apache-2.0", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@actions/core": "^1.2.6", |     "@actions/core": "^1.4.0", | ||||||
|     "@actions/exec": "^1.0.4", |     "@actions/exec": "^1.1.0", | ||||||
|     "@actions/http-client": "^1.0.9", |     "@actions/http-client": "^1.0.11", | ||||||
|     "@actions/tool-cache": "^1.6.1", |     "@actions/tool-cache": "^1.7.1", | ||||||
|     "semver": "^7.3.4", |     "semver": "^7.3.5", | ||||||
|     "uuid": "^8.3.2" |     "uuid": "^8.3.2" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@types/jest": "^26.0.3", |     "@types/jest": "^26.0.23", | ||||||
|     "@types/node": "^14.0.14", |     "@types/node": "^14.17.4", | ||||||
|     "@vercel/ncc": "^0.23.0", |     "@vercel/ncc": "^0.28.6", | ||||||
|     "dotenv": "^8.2.0", |     "dotenv": "^8.6.0", | ||||||
|     "jest": "^26.1.0", |     "jest": "^26.6.3", | ||||||
|     "jest-circus": "^26.1.0", |     "jest-circus": "^26.6.3", | ||||||
|     "jest-runtime": "^26.1.0", |     "jest-runtime": "^26.6.3", | ||||||
|     "prettier": "^2.0.5", |     "prettier": "^2.3.1", | ||||||
|     "ts-jest": "^26.1.1", |     "ts-jest": "^26.5.6", | ||||||
|     "typescript": "^3.9.5", |     "typescript": "^4.3.4", | ||||||
|     "typescript-formatter": "^7.2.2" |     "typescript-formatter": "^7.2.2" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										207
									
								
								src/buildx.ts
									
									
									
									
									
								
							
							
						
						
									
										207
									
								
								src/buildx.ts
									
									
									
									
									
								
							| @@ -3,48 +3,145 @@ import * as path from 'path'; | |||||||
| import * as semver from 'semver'; | import * as semver from 'semver'; | ||||||
| import * as util from 'util'; | import * as util from 'util'; | ||||||
| import * as context from './context'; | import * as context from './context'; | ||||||
| import * as exec from './exec'; | import * as git from './git'; | ||||||
| import * as github from './github'; | import * as github from './github'; | ||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
|  | import * as exec from '@actions/exec'; | ||||||
| import * as tc from '@actions/tool-cache'; | import * as tc from '@actions/tool-cache'; | ||||||
|  |  | ||||||
| export async function getVersion(): Promise<string> { | export type Builder = { | ||||||
|   return await exec.exec(`docker`, ['buildx', 'version'], true).then(res => { |   name?: string; | ||||||
|     if (res.stderr != '' && !res.success) { |   driver?: string; | ||||||
|       throw new Error(res.stderr); |   node_name?: string; | ||||||
|     } |   node_endpoint?: string; | ||||||
|     return parseVersion(res.stdout); |   node_status?: string; | ||||||
|   }); |   node_flags?: string; | ||||||
| } |   node_platforms?: string; | ||||||
|  | }; | ||||||
| export async function parseVersion(stdout: string): Promise<string> { |  | ||||||
|   const matches = /\sv?([0-9.]+)/.exec(stdout); |  | ||||||
|   if (!matches) { |  | ||||||
|     throw new Error(`Cannot parse Buildx version`); |  | ||||||
|   } |  | ||||||
|   return semver.clean(matches[1]); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export async function isAvailable(): Promise<Boolean> { | export async function isAvailable(): Promise<Boolean> { | ||||||
|   return await exec.exec(`docker`, ['buildx'], true).then(res => { |   return await exec | ||||||
|     if (res.stderr != '' && !res.success) { |     .getExecOutput('docker', ['buildx'], { | ||||||
|       return false; |       ignoreReturnCode: true, | ||||||
|     } |       silent: true | ||||||
|     return res.success; |     }) | ||||||
|   }); |     .then(res => { | ||||||
|  |       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||||
|  |         return false; | ||||||
|  |       } | ||||||
|  |       return res.exitCode == 0; | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| export async function platforms(): Promise<String | undefined> { | export async function getVersion(): Promise<string> { | ||||||
|   return await exec.exec(`docker`, ['buildx', 'inspect'], true).then(res => { |   return await exec | ||||||
|     if (res.stderr != '' && !res.success) { |     .getExecOutput('docker', ['buildx', 'version'], { | ||||||
|       throw new Error(res.stderr); |       ignoreReturnCode: true, | ||||||
|     } |       silent: true | ||||||
|     for (const line of res.stdout.trim().split(`\n`)) { |     }) | ||||||
|       if (line.startsWith('Platforms')) { |     .then(res => { | ||||||
|         return line.replace('Platforms: ', '').replace(/\s/g, '').trim(); |       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||||
|  |         throw new Error(res.stderr.trim()); | ||||||
|       } |       } | ||||||
|     } |       return parseVersion(res.stdout.trim()); | ||||||
|   }); |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function parseVersion(stdout: string): string { | ||||||
|  |   const matches = /\sv?([0-9a-f]{7}|[0-9.]+)/.exec(stdout); | ||||||
|  |   if (!matches) { | ||||||
|  |     throw new Error(`Cannot parse buildx version`); | ||||||
|  |   } | ||||||
|  |   return matches[1]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function satisfies(version: string, range: string): boolean { | ||||||
|  |   return semver.satisfies(version, range) || /^[0-9a-f]{7}$/.exec(version) !== null; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export async function inspect(name: string): Promise<Builder> { | ||||||
|  |   return await exec | ||||||
|  |     .getExecOutput(`docker`, ['buildx', 'inspect', name], { | ||||||
|  |       ignoreReturnCode: true, | ||||||
|  |       silent: true | ||||||
|  |     }) | ||||||
|  |     .then(res => { | ||||||
|  |       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; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export async function build(inputBuildRef: string, dockerConfigHome: string): Promise<string> { | ||||||
|  |   let [repo, ref] = inputBuildRef.split('#'); | ||||||
|  |   if (ref.length == 0) { | ||||||
|  |     ref = 'master'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   let vspec: string; | ||||||
|  |   if (ref.match(/^[0-9a-fA-F]{40}$/)) { | ||||||
|  |     vspec = ref; | ||||||
|  |   } else { | ||||||
|  |     vspec = await git.getRemoteSha(repo, ref); | ||||||
|  |   } | ||||||
|  |   core.debug(`Tool version spec ${vspec}`); | ||||||
|  |  | ||||||
|  |   let toolPath: string; | ||||||
|  |   toolPath = tc.find('buildx', vspec); | ||||||
|  |   if (!toolPath) { | ||||||
|  |     const outFolder = path.join(context.tmpDir(), 'out').split(path.sep).join(path.posix.sep); | ||||||
|  |     toolPath = await exec | ||||||
|  |       .getExecOutput('docker', ['buildx', 'build', '--target', 'binaries', '--build-arg', 'BUILDKIT_CONTEXT_KEEP_GIT_DIR=1', '--output', `type=local,dest=${outFolder}`, inputBuildRef], { | ||||||
|  |         ignoreReturnCode: true | ||||||
|  |       }) | ||||||
|  |       .then(res => { | ||||||
|  |         if (res.stderr.length > 0 && res.exitCode != 0) { | ||||||
|  |           core.warning(res.stderr.trim()); | ||||||
|  |         } | ||||||
|  |         return tc.cacheFile(`${outFolder}/buildx`, context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx', 'buildx', vspec); | ||||||
|  |       }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return setPlugin(toolPath, dockerConfigHome); | ||||||
| } | } | ||||||
|  |  | ||||||
| export async function install(inputVersion: string, dockerConfigHome: string): Promise<string> { | export async function install(inputVersion: string, dockerConfigHome: string): Promise<string> { | ||||||
| @@ -52,7 +149,7 @@ export async function install(inputVersion: string, dockerConfigHome: string): P | |||||||
|   if (!release) { |   if (!release) { | ||||||
|     throw new Error(`Cannot find buildx ${inputVersion} release`); |     throw new Error(`Cannot find buildx ${inputVersion} release`); | ||||||
|   } |   } | ||||||
|   core.debug(`Release found: ${release.tag_name}`); |   core.debug(`Release ${release.tag_name} found`); | ||||||
|   const version = release.tag_name.replace(/^v+|v+$/g, ''); |   const version = release.tag_name.replace(/^v+|v+$/g, ''); | ||||||
|  |  | ||||||
|   let toolPath: string; |   let toolPath: string; | ||||||
| @@ -65,6 +162,10 @@ export async function install(inputVersion: string, dockerConfigHome: string): P | |||||||
|     toolPath = await download(version); |     toolPath = await download(version); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   return setPlugin(toolPath, dockerConfigHome); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function setPlugin(toolPath: string, dockerConfigHome: string): Promise<string> { | ||||||
|   const pluginsDir: string = path.join(dockerConfigHome, 'cli-plugins'); |   const pluginsDir: string = path.join(dockerConfigHome, 'cli-plugins'); | ||||||
|   core.debug(`Plugins dir is ${pluginsDir}`); |   core.debug(`Plugins dir is ${pluginsDir}`); | ||||||
|   if (!fs.existsSync(pluginsDir)) { |   if (!fs.existsSync(pluginsDir)) { | ||||||
| @@ -76,7 +177,7 @@ export async function install(inputVersion: string, dockerConfigHome: string): P | |||||||
|   core.debug(`Plugin path is ${pluginPath}`); |   core.debug(`Plugin path is ${pluginPath}`); | ||||||
|   fs.copyFileSync(path.join(toolPath, filename), pluginPath); |   fs.copyFileSync(path.join(toolPath, filename), pluginPath); | ||||||
|  |  | ||||||
|   core.info('🔨 Fixing perms...'); |   core.info('Fixing perms'); | ||||||
|   fs.chmodSync(pluginPath, '0755'); |   fs.chmodSync(pluginPath, '0755'); | ||||||
|  |  | ||||||
|   return pluginPath; |   return pluginPath; | ||||||
| @@ -84,15 +185,11 @@ export async function install(inputVersion: string, dockerConfigHome: string): P | |||||||
|  |  | ||||||
| async function download(version: string): Promise<string> { | async function download(version: string): Promise<string> { | ||||||
|   const targetFile: string = context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx'; |   const targetFile: string = context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx'; | ||||||
|   const downloadUrl = util.format( |   const downloadUrl = util.format('https://github.com/docker/buildx/releases/download/v%s/%s', version, await filename(version)); | ||||||
|     'https://github.com/docker/buildx/releases/download/v%s/%s', |  | ||||||
|     version, |  | ||||||
|     await filename(version) |  | ||||||
|   ); |  | ||||||
|   let downloadPath: string; |   let downloadPath: string; | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
|     core.info(`⬇️ Downloading ${downloadUrl}...`); |     core.info(`Downloading ${downloadUrl}`); | ||||||
|     downloadPath = await tc.downloadTool(downloadUrl); |     downloadPath = await tc.downloadTool(downloadUrl); | ||||||
|     core.debug(`Downloaded to ${downloadPath}`); |     core.debug(`Downloaded to ${downloadPath}`); | ||||||
|   } catch (error) { |   } catch (error) { | ||||||
| @@ -127,3 +224,31 @@ async function filename(version: string): Promise<string> { | |||||||
|   const ext: string = context.osPlat == 'win32' ? '.exe' : ''; |   const ext: string = context.osPlat == 'win32' ? '.exe' : ''; | ||||||
|   return util.format('buildx-v%s.%s-%s%s', version, platform, arch, ext); |   return util.format('buildx-v%s.%s-%s%s', version, platform, arch, ext); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export async function getBuildKitVersion(containerID: string): Promise<string> { | ||||||
|  |   return exec | ||||||
|  |     .getExecOutput(`docker`, ['inspect', '--format', '{{.Config.Image}}', containerID], { | ||||||
|  |       ignoreReturnCode: true, | ||||||
|  |       silent: true | ||||||
|  |     }) | ||||||
|  |     .then(bkitimage => { | ||||||
|  |       if (bkitimage.exitCode == 0 && bkitimage.stdout.length > 0) { | ||||||
|  |         return exec | ||||||
|  |           .getExecOutput(`docker`, ['run', '--rm', bkitimage.stdout.trim(), '--version'], { | ||||||
|  |             ignoreReturnCode: true, | ||||||
|  |             silent: true | ||||||
|  |           }) | ||||||
|  |           .then(bkitversion => { | ||||||
|  |             if (bkitversion.exitCode == 0 && bkitversion.stdout.length > 0) { | ||||||
|  |               return `${bkitimage.stdout.trim()} => ${bkitversion.stdout.trim()}`; | ||||||
|  |             } else if (bkitversion.stderr.length > 0) { | ||||||
|  |               core.warning(bkitversion.stderr.trim()); | ||||||
|  |             } | ||||||
|  |             return bkitversion.stdout.trim(); | ||||||
|  |           }); | ||||||
|  |       } else if (bkitimage.stderr.length > 0) { | ||||||
|  |         core.warning(bkitimage.stderr.trim()); | ||||||
|  |       } | ||||||
|  |       return bkitimage.stdout.trim(); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,9 +1,20 @@ | |||||||
|  | import fs from 'fs'; | ||||||
| import * as os from 'os'; | import * as os from 'os'; | ||||||
|  | import path from 'path'; | ||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
|  | import {issueCommand} from '@actions/core/lib/command'; | ||||||
|  |  | ||||||
|  | let _tmpDir: string; | ||||||
| export const osPlat: string = os.platform(); | export const osPlat: string = os.platform(); | ||||||
| export const osArch: string = os.arch(); | export const osArch: string = os.arch(); | ||||||
|  |  | ||||||
|  | export function tmpDir(): string { | ||||||
|  |   if (!_tmpDir) { | ||||||
|  |     _tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-')).split(path.sep).join(path.posix.sep); | ||||||
|  |   } | ||||||
|  |   return _tmpDir; | ||||||
|  | } | ||||||
|  |  | ||||||
| export interface Inputs { | export interface Inputs { | ||||||
|   version: string; |   version: string; | ||||||
|   driver: string; |   driver: string; | ||||||
| @@ -12,6 +23,7 @@ export interface Inputs { | |||||||
|   install: boolean; |   install: boolean; | ||||||
|   use: boolean; |   use: boolean; | ||||||
|   endpoint: string; |   endpoint: string; | ||||||
|  |   config: string; | ||||||
| } | } | ||||||
|  |  | ||||||
| export async function getInputs(): Promise<Inputs> { | export async function getInputs(): Promise<Inputs> { | ||||||
| @@ -19,12 +31,11 @@ export async function getInputs(): Promise<Inputs> { | |||||||
|     version: core.getInput('version'), |     version: core.getInput('version'), | ||||||
|     driver: core.getInput('driver') || 'docker-container', |     driver: core.getInput('driver') || 'docker-container', | ||||||
|     driverOpts: await getInputList('driver-opts', true), |     driverOpts: await getInputList('driver-opts', true), | ||||||
|     buildkitdFlags: |     buildkitdFlags: core.getInput('buildkitd-flags') || '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||||
|       core.getInput('buildkitd-flags') || |     install: core.getBooleanInput('install'), | ||||||
|       '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', |     use: core.getBooleanInput('use'), | ||||||
|     install: /true/i.test(core.getInput('install')), |     endpoint: core.getInput('endpoint'), | ||||||
|     use: /true/i.test(core.getInput('use')), |     config: core.getInput('config') | ||||||
|     endpoint: core.getInput('endpoint') |  | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -36,10 +47,7 @@ export async function getInputList(name: string, ignoreComma?: boolean): Promise | |||||||
|   return items |   return items | ||||||
|     .split(/\r?\n/) |     .split(/\r?\n/) | ||||||
|     .filter(x => x) |     .filter(x => x) | ||||||
|     .reduce<string[]>( |     .reduce<string[]>((acc, line) => acc.concat(!ignoreComma ? line.split(',').filter(x => x) : line).map(pat => pat.trim()), []); | ||||||
|       (acc, line) => acc.concat(!ignoreComma ? line.split(',').filter(x => x) : line).map(pat => pat.trim()), |  | ||||||
|       [] |  | ||||||
|     ); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| export const asyncForEach = async (array, callback) => { | export const asyncForEach = async (array, callback) => { | ||||||
| @@ -47,3 +55,8 @@ export const asyncForEach = async (array, callback) => { | |||||||
|     await callback(array[index], index, array); |     await callback(array[index], index, array); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | // FIXME: Temp fix https://github.com/actions/toolkit/issues/777 | ||||||
|  | export function setOutput(name: string, value: any): void { | ||||||
|  |   issueCommand('set-output', {name}, value); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,7 +0,0 @@ | |||||||
| import * as exec from './exec'; |  | ||||||
|  |  | ||||||
| export async function isDaemonRunning(): Promise<boolean> { |  | ||||||
|   return await exec.exec(`docker`, ['version', '--format', '{{.Server.Os}}'], true).then(res => { |  | ||||||
|     return !res.stdout.includes(' ') && res.success; |  | ||||||
|   }); |  | ||||||
| } |  | ||||||
							
								
								
									
										34
									
								
								src/exec.ts
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								src/exec.ts
									
									
									
									
									
								
							| @@ -1,34 +0,0 @@ | |||||||
| import * as aexec from '@actions/exec'; |  | ||||||
| import {ExecOptions} from '@actions/exec'; |  | ||||||
|  |  | ||||||
| export interface ExecResult { |  | ||||||
|   success: boolean; |  | ||||||
|   stdout: string; |  | ||||||
|   stderr: string; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export const exec = async (command: string, args: string[] = [], silent: boolean): Promise<ExecResult> => { |  | ||||||
|   let stdout: string = ''; |  | ||||||
|   let stderr: string = ''; |  | ||||||
|  |  | ||||||
|   const options: ExecOptions = { |  | ||||||
|     silent: silent, |  | ||||||
|     ignoreReturnCode: true |  | ||||||
|   }; |  | ||||||
|   options.listeners = { |  | ||||||
|     stdout: (data: Buffer) => { |  | ||||||
|       stdout += data.toString(); |  | ||||||
|     }, |  | ||||||
|     stderr: (data: Buffer) => { |  | ||||||
|       stderr += data.toString(); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   const returnCode: number = await aexec.exec(command, args, options); |  | ||||||
|  |  | ||||||
|   return { |  | ||||||
|     success: returnCode === 0, |  | ||||||
|     stdout: stdout.trim(), |  | ||||||
|     stderr: stderr.trim() |  | ||||||
|   }; |  | ||||||
| }; |  | ||||||
							
								
								
									
										19
									
								
								src/git.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/git.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | import * as exec from '@actions/exec'; | ||||||
|  |  | ||||||
|  | export async function getRemoteSha(repo: string, ref: string): Promise<string> { | ||||||
|  |   return await exec | ||||||
|  |     .getExecOutput(`git`, ['ls-remote', repo, ref], { | ||||||
|  |       ignoreReturnCode: true, | ||||||
|  |       silent: true | ||||||
|  |     }) | ||||||
|  |     .then(res => { | ||||||
|  |       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||||
|  |         throw new Error(res.stderr); | ||||||
|  |       } | ||||||
|  |       const [rsha, rref] = res.stdout.trim().split(/[\s\t]/); | ||||||
|  |       if (rsha.length == 0) { | ||||||
|  |         throw new Error(`Cannot find remote ref for ${repo}#${ref}`); | ||||||
|  |       } | ||||||
|  |       return rsha; | ||||||
|  |     }); | ||||||
|  | } | ||||||
							
								
								
									
										95
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								src/main.ts
									
									
									
									
									
								
							| @@ -1,40 +1,41 @@ | |||||||
| import * as core from '@actions/core'; |  | ||||||
| import * as exec from '@actions/exec'; |  | ||||||
| import * as os from 'os'; | import * as os from 'os'; | ||||||
| import * as path from 'path'; | import * as path from 'path'; | ||||||
| import * as semver from 'semver'; |  | ||||||
| import * as buildx from './buildx'; | import * as buildx from './buildx'; | ||||||
| import * as context from './context'; | import * as context from './context'; | ||||||
| import * as mexec from './exec'; |  | ||||||
| import * as stateHelper from './state-helper'; | import * as stateHelper from './state-helper'; | ||||||
|  | import * as util from './util'; | ||||||
|  | import * as core from '@actions/core'; | ||||||
|  | import * as exec from '@actions/exec'; | ||||||
|  |  | ||||||
| async function run(): Promise<void> { | async function run(): Promise<void> { | ||||||
|   try { |   try { | ||||||
|     if (os.platform() !== 'linux') { |     core.startGroup(`Docker info`); | ||||||
|       core.setFailed('Only supported on linux platform'); |     await exec.exec('docker', ['version']); | ||||||
|       return; |     await exec.exec('docker', ['info']); | ||||||
|     } |     core.endGroup(); | ||||||
|  |  | ||||||
|     const inputs: context.Inputs = await context.getInputs(); |     const inputs: context.Inputs = await context.getInputs(); | ||||||
|     const dockerConfigHome: string = process.env.DOCKER_CONFIG || path.join(os.homedir(), '.docker'); |     const dockerConfigHome: string = process.env.DOCKER_CONFIG || path.join(os.homedir(), '.docker'); | ||||||
|  |  | ||||||
|     if (!(await buildx.isAvailable()) || inputs.version) { |     if (util.isValidUrl(inputs.version)) { | ||||||
|       core.startGroup(`👉 Installing Buildx`); |       core.startGroup(`Build and install buildx`); | ||||||
|  |       await buildx.build(inputs.version, dockerConfigHome); | ||||||
|  |       core.endGroup(); | ||||||
|  |     } else if (!(await buildx.isAvailable()) || inputs.version) { | ||||||
|  |       core.startGroup(`Download and install buildx`); | ||||||
|       await buildx.install(inputs.version || 'latest', dockerConfigHome); |       await buildx.install(inputs.version || 'latest', dockerConfigHome); | ||||||
|       core.endGroup(); |       core.endGroup(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const buildxVersion = await buildx.getVersion(); |     const buildxVersion = await buildx.getVersion(); | ||||||
|     core.info(`📣 Buildx version: ${buildxVersion}`); |  | ||||||
|  |  | ||||||
|     const builderName: string = inputs.driver == 'docker' ? 'default' : `builder-${require('uuid').v4()}`; |     const builderName: string = inputs.driver == 'docker' ? 'default' : `builder-${require('uuid').v4()}`; | ||||||
|     core.setOutput('name', builderName); |     context.setOutput('name', builderName); | ||||||
|     stateHelper.setBuilderName(builderName); |     stateHelper.setBuilderName(builderName); | ||||||
|  |  | ||||||
|     if (inputs.driver !== 'docker') { |     if (inputs.driver !== 'docker') { | ||||||
|       core.startGroup(`🔨 Creating a new builder instance`); |       core.startGroup(`Creating a new builder instance`); | ||||||
|       let createArgs: Array<string> = ['buildx', 'create', '--name', builderName, '--driver', inputs.driver]; |       let createArgs: Array<string> = ['buildx', 'create', '--name', builderName, '--driver', inputs.driver]; | ||||||
|       if (semver.satisfies(buildxVersion, '>=0.3.0')) { |       if (buildx.satisfies(buildxVersion, '>=0.3.0')) { | ||||||
|         await context.asyncForEach(inputs.driverOpts, async driverOpt => { |         await context.asyncForEach(inputs.driverOpts, async driverOpt => { | ||||||
|           createArgs.push('--driver-opt', driverOpt); |           createArgs.push('--driver-opt', driverOpt); | ||||||
|         }); |         }); | ||||||
| @@ -48,12 +49,15 @@ async function run(): Promise<void> { | |||||||
|       if (inputs.endpoint) { |       if (inputs.endpoint) { | ||||||
|         createArgs.push(inputs.endpoint); |         createArgs.push(inputs.endpoint); | ||||||
|       } |       } | ||||||
|  |       if (inputs.config) { | ||||||
|  |         createArgs.push('--config', inputs.config); | ||||||
|  |       } | ||||||
|       await exec.exec('docker', createArgs); |       await exec.exec('docker', createArgs); | ||||||
|       core.endGroup(); |       core.endGroup(); | ||||||
|  |  | ||||||
|       core.startGroup(`🏃 Booting builder`); |       core.startGroup(`Booting builder`); | ||||||
|       let bootstrapArgs: Array<string> = ['buildx', 'inspect', '--bootstrap']; |       let bootstrapArgs: Array<string> = ['buildx', 'inspect', '--bootstrap']; | ||||||
|       if (semver.satisfies(buildxVersion, '>=0.4.0')) { |       if (buildx.satisfies(buildxVersion, '>=0.4.0')) { | ||||||
|         bootstrapArgs.push('--builder', builderName); |         bootstrapArgs.push('--builder', builderName); | ||||||
|       } |       } | ||||||
|       await exec.exec('docker', bootstrapArgs); |       await exec.exec('docker', bootstrapArgs); | ||||||
| @@ -61,30 +65,63 @@ async function run(): Promise<void> { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (inputs.install) { |     if (inputs.install) { | ||||||
|       core.startGroup(`🤝 Setting buildx as default builder`); |       core.startGroup(`Setting buildx as default builder`); | ||||||
|       await exec.exec('docker', ['buildx', 'install']); |       await exec.exec('docker', ['buildx', 'install']); | ||||||
|       core.endGroup(); |       core.endGroup(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     core.startGroup(`🛒 Extracting available platforms`); |     core.startGroup(`Inspect builder`); | ||||||
|     const platforms = await buildx.platforms(); |     const builder = await buildx.inspect(builderName); | ||||||
|     core.info(`${platforms}`); |     core.info(JSON.stringify(builder, undefined, 2)); | ||||||
|     core.setOutput('platforms', platforms); |     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.endGroup(); |     core.endGroup(); | ||||||
|  |  | ||||||
|  |     if (inputs.driver == 'docker-container') { | ||||||
|  |       stateHelper.setContainerName(`buildx_buildkit_${builder.node_name}`); | ||||||
|  |       core.startGroup(`BuildKit version`); | ||||||
|  |       core.info(await buildx.getBuildKitVersion(`buildx_buildkit_${builder.node_name}`)); | ||||||
|  |       core.endGroup(); | ||||||
|  |     } | ||||||
|  |     if (core.isDebug() || builder.node_flags?.includes('--debug')) { | ||||||
|  |       stateHelper.setDebug('true'); | ||||||
|  |     } | ||||||
|   } catch (error) { |   } catch (error) { | ||||||
|     core.setFailed(error.message); |     core.setFailed(error.message); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| async function cleanup(): Promise<void> { | async function cleanup(): Promise<void> { | ||||||
|   if (stateHelper.builderName.length == 0) { |   if (stateHelper.IsDebug && stateHelper.containerName.length > 0) { | ||||||
|     return; |     core.startGroup(`BuildKit container logs`); | ||||||
|  |     await exec | ||||||
|  |       .getExecOutput('docker', ['logs', `${stateHelper.containerName}`], { | ||||||
|  |         ignoreReturnCode: true | ||||||
|  |       }) | ||||||
|  |       .then(res => { | ||||||
|  |         if (res.stderr.length > 0 && res.exitCode != 0) { | ||||||
|  |           core.warning(res.stderr.trim()); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     core.endGroup(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (stateHelper.builderName.length > 0) { | ||||||
|  |     core.startGroup(`Removing builder`); | ||||||
|  |     await exec | ||||||
|  |       .getExecOutput('docker', ['buildx', 'rm', `${stateHelper.builderName}`], { | ||||||
|  |         ignoreReturnCode: true | ||||||
|  |       }) | ||||||
|  |       .then(res => { | ||||||
|  |         if (res.stderr.length > 0 && res.exitCode != 0) { | ||||||
|  |           core.warning(res.stderr.trim()); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     core.endGroup(); | ||||||
|   } |   } | ||||||
|   await mexec.exec('docker', ['buildx', 'rm', `${stateHelper.builderName}`], false).then(res => { |  | ||||||
|     if (res.stderr != '' && !res.success) { |  | ||||||
|       core.warning(res.stderr); |  | ||||||
|     } |  | ||||||
|   }); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| if (!stateHelper.IsPost) { | if (!stateHelper.IsPost) { | ||||||
|   | |||||||
| @@ -1,12 +1,22 @@ | |||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
|  |  | ||||||
| export const IsPost = !!process.env['STATE_isPost']; | export const IsPost = !!process.env['STATE_isPost']; | ||||||
|  | export const IsDebug = !!process.env['STATE_isDebug']; | ||||||
| export const builderName = process.env['STATE_builderName'] || ''; | export const builderName = process.env['STATE_builderName'] || ''; | ||||||
|  | export const containerName = process.env['STATE_containerName'] || ''; | ||||||
|  |  | ||||||
|  | export function setDebug(debug: string) { | ||||||
|  |   core.saveState('isDebug', debug); | ||||||
|  | } | ||||||
|  |  | ||||||
| export function setBuilderName(builderName: string) { | export function setBuilderName(builderName: string) { | ||||||
|   core.saveState('builderName', builderName); |   core.saveState('builderName', builderName); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export function setContainerName(containerName: string) { | ||||||
|  |   core.saveState('containerName', containerName); | ||||||
|  | } | ||||||
|  |  | ||||||
| if (!IsPost) { | if (!IsPost) { | ||||||
|   core.saveState('isPost', 'true'); |   core.saveState('isPost', 'true'); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								src/util.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/util.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | export function isValidUrl(url: string): boolean { | ||||||
|  |   try { | ||||||
|  |     new URL(url); | ||||||
|  |   } catch (e) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   return true; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user