Compare commits
	
		
			174 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | af5a7ed5ba | ||
|   | 2a85189a6c | ||
|   | 6c2079483e | ||
|   | afdf0c0a67 | ||
|   | 00ae31ab6e | ||
|   | 701942b6e5 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 90e54d0b1d | ||
|   | 831ca179d3 | ||
|   | 6bd0e5492f | ||
|   | b3eddbb94c | ||
|   | ffd798c1f1 | ||
|   | 62d8db0960 | ||
|   | 8ab81cb898 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | d47e7c357d | ||
|   | 4976231911 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | d236adc992 | ||
|   | 94d76d3bc1 | ||
|   | 2b28f2a854 | ||
|   | 9f6f8c940b | ||
|   | 8411d080ee | ||
|   | 4a13e500e5 | ||
|   | 7416668686 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | b4f76a5dc6 | ||
|   | b7feb766fa | ||
|   | fae8018297 | ||
|   | b625868b13 | ||
|   | 5193ef1da6 | ||
|   | d3afd779e4 | ||
|   | 7a786bb2b9 | ||
|   | c66ae3adcf | ||
|   | 248131c7bf | ||
|   | b425c4cd5a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 9834ce5b4d | ||
|   | fdf7f43ecf | ||
|   | e3a4c332fb | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | c48d200483 | ||
|   | 8d2cf95286 | ||
|   | 3c7915695f | ||
|   | 0a283b683f | ||
|   | c544b50d70 | ||
|   | dd31262fa7 | ||
|   | 5f01267817 | ||
|   | 0f847266c3 | ||
|   | ea8499618b | ||
|   | 4c1b68d83a | ||
|   | 5909c5bffe | ||
|   | 285730d174 | ||
|   | 4bbe0177ef | ||
|   | cc4d1d4d5f | ||
|   | e7d3750abc | ||
|   | 4556201a14 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 9fa62cfa91 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 8026f009fc | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 6b35a7a7f1 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | c6e64b478a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | e2505c6383 | ||
|   | 0565240e2d | ||
|   | 3ab07f8801 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | b9e7e4daec | ||
|   | 04d1a3b049 | ||
|   | 1a4d1a13fb | ||
|   | 675965c0e1 | ||
|   | 58ee34cb6b | ||
|   | c97c4060bd | ||
|   | 47d5369e0b | ||
|   | 8895c7468f | ||
|   | 59ba712c53 | ||
|   | 0c20fff10d | ||
|   | 0a97817b6a | ||
|   | ec39ef320c | ||
|   | f46044b799 | ||
|   | 4e4ee680f6 | ||
|   | e86cf554b6 | ||
|   | daa0106f78 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | ce51e905a6 | ||
|   | 1fde16337d | ||
|   | ae311c520f | ||
|   | 9311bf5263 | ||
|   | b1654941ef | ||
|   | 12a9f89349 | ||
|   | 2036a561be | ||
|   | b1d46f11a2 | ||
|   | e5b2fc7017 | ||
|   | 24216ba114 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | eb33afda71 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 9407ba1305 | ||
|   | 429cdb70ad | ||
|   | 74a34eff3a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 6787bde0a6 | ||
|   | 56932deb0a | ||
|   | 0681013357 | ||
|   | be4bf1099e | ||
|   | 9ec154c4b6 | ||
|   | 380260b6c7 | ||
|   | ac790be09a | ||
|   | dc0a85b056 | ||
|   | aca01f02d5 | ||
|   | 4b0752a2b1 | ||
|   | be06a9da57 | ||
|   | 19184b90ca | ||
|   | 57e90a56ab | ||
|   | 4fad532b9f | ||
|   | 413aee355f | ||
|   | f05b754b57 | ||
|   | 2f3765570b | ||
|   | 68d0dc20df | ||
|   | 1fd7f72e60 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | ea907fb0a4 | ||
|   | 2eb1c1961a | ||
|   | 27376fe2fc | ||
|   | c9330004c2 | ||
|   | dac08d41ad | ||
|   | 44ea916f6c | ||
|   | 0167eef179 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 91bf8bfc4d | ||
|   | a799b4decf | ||
|   | 87480bdf69 | ||
|   | f9efed53cc | ||
|   | 3580b78e04 | ||
|   | 91df6b874e | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | ea92b18afb | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 6f91eb31f7 | ||
|   | eafaea8d0f | ||
|   | ddd2a92197 | ||
|   | a54198e85a | ||
|   | 7e3a79c50d | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 4a730ce64b | ||
|   | 817ed59f97 | ||
|   | a3646c08f8 | ||
|   | 5c3465b033 | ||
|   | e9c0697e5b | ||
|   | e090350180 | ||
|   | f2a1d5e99d | ||
|   | 81f5252b54 | ||
|   | b3435979d1 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 80def7c74e | ||
|   | 35434f557a | ||
|   | d63c96254b | ||
|   | 21fe05ff59 | ||
|   | 097a3e23ac | ||
|   | d8823bfaed | ||
|   | 3a3620ed49 | ||
|   | 8082ebc6ea | ||
|   | a3ae207c14 | ||
|   | 4858a31f84 | ||
|   | d10433366f | ||
|   | ee5cabd9e3 | ||
|   | 7944f9a25b | ||
|   | c088e12d82 | ||
|   | e941dc0149 | ||
|   | 0d6f3e8936 | ||
|   | c779d8500d | ||
|   | b651cf69a6 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 0db6129a57 | ||
|   | 70cc701b9c | ||
|   | af7537dc3e | ||
|   | 2d8166c4b9 | ||
|   | 6a8fbf0dbc | ||
|   | f74fd039f3 | ||
|   | 695ee8547d | ||
|   | fd7264830a | ||
|   | 6842956e83 | ||
|   | 9d1b8fa4e2 | ||
|   | 17c742ea85 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 916f6873ae | ||
|   | a3f7a443f9 | ||
|   | 05e89e68aa | ||
|   | d16cc0b66f | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 306a0a9f50 | ||
|   | 55a3485913 | ||
|   | 71e9aaaf29 | ||
|   | 3b5e8027fc | ||
|   | 02d3266a89 | ||
|   | f403dafe18 | 
							
								
								
									
										3
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| /dist/** | ||||
| /coverage/** | ||||
| /node_modules/** | ||||
| @@ -1,11 +1,12 @@ | ||||
| { | ||||
|   "env": { | ||||
|     "node": true, | ||||
|     "es2021": true, | ||||
|     "jest/globals": true | ||||
|     "es6": true, | ||||
|     "jest": true | ||||
|   }, | ||||
|   "extends": [ | ||||
|     "eslint:recommended", | ||||
|     "plugin:@typescript-eslint/eslint-recommended", | ||||
|     "plugin:@typescript-eslint/recommended", | ||||
|     "plugin:jest/recommended", | ||||
|     "plugin:prettier/recommended" | ||||
|   | ||||
							
								
								
									
										1
									
								
								.github/CODEOWNERS
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/CODEOWNERS
									
									
									
									
										vendored
									
									
								
							| @@ -1 +0,0 @@ | ||||
| *	@crazy-max | ||||
							
								
								
									
										3
									
								
								.github/CODE_OF_CONDUCT.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.github/CODE_OF_CONDUCT.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # Code of conduct | ||||
|  | ||||
| - [Moby community guidelines](https://github.com/moby/moby/blob/master/CONTRIBUTING.md#moby-community-guidelines) | ||||
							
								
								
									
										101
									
								
								.github/ISSUE_TEMPLATE/bug.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								.github/ISSUE_TEMPLATE/bug.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema | ||||
| name: Bug Report | ||||
| description: Report a bug | ||||
| labels: | ||||
|   - status/triage | ||||
|  | ||||
| body: | ||||
|   - type: markdown | ||||
|     attributes: | ||||
|       value: | | ||||
|         Thank you for taking the time to report a bug! | ||||
|         If this is a security issue please report it to the [Docker Security team](mailto:security@docker.com). | ||||
|         Before submitting a bug report, check out the [Troubleshooting doc](https://github.com/docker/build-push-action/blob/master/TROUBLESHOOTING.md). | ||||
|  | ||||
|   - type: checkboxes | ||||
|     attributes: | ||||
|       label: Contributing guidelines | ||||
|       description: > | ||||
|         Make sure you've read the contributing guidelines before proceeding. | ||||
|       options: | ||||
|         - label: I've read the [contributing guidelines](https://github.com/docker/build-push-action/blob/master/.github/CONTRIBUTING.md) and wholeheartedly agree | ||||
|           required: true | ||||
|  | ||||
|   - type: checkboxes | ||||
|     attributes: | ||||
|       label: "I've found a bug, and:" | ||||
|       description: | | ||||
|         Make sure that your request fulfills all of the following requirements. | ||||
|         If one requirement cannot be satisfied, explain in detail why. | ||||
|       options: | ||||
|         - label: The documentation does not mention anything about my problem | ||||
|         - label: There are no open or closed issues that are related to my problem | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Description | ||||
|       description: > | ||||
|         Provide a brief description of the bug in 1-2 sentences. | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Expected behaviour | ||||
|       description: > | ||||
|         Describe precisely what you'd expect to happen. | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Actual behaviour | ||||
|       description: > | ||||
|         Describe precisely what is actually happening. | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: input | ||||
|     attributes: | ||||
|       label: Repository URL | ||||
|       description: > | ||||
|         Enter the URL of the repository where you are experiencing the | ||||
|         issue. If your repository is private, provide a link to a minimal | ||||
|         repository that reproduces the issue. | ||||
|  | ||||
|   - type: input | ||||
|     attributes: | ||||
|       label: Workflow run URL | ||||
|       description: > | ||||
|         Enter the URL of the GitHub Action workflow run, if public. | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: YAML workflow | ||||
|       description: | | ||||
|         Provide the YAML of the workflow that's causing the issue. | ||||
|         Make sure to remove any sensitive information. | ||||
|       render: yaml | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Workflow logs | ||||
|       description: > | ||||
|         [Attach](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/attaching-files) | ||||
|         the [log file of your workflow run](https://docs.github.com/en/actions/managing-workflow-runs/using-workflow-run-logs#downloading-logs) | ||||
|         and make sure to remove any sensitive information. | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: BuildKit logs | ||||
|       description: > | ||||
|         If applicable, provide the [BuildKit container logs](https://docs.docker.com/build/ci/github-actions/configure-builder/#buildkit-container-logs) | ||||
|       render: text | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Additional info | ||||
|       description: | | ||||
|         Provide any additional information that could be useful. | ||||
							
								
								
									
										37
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,37 +0,0 @@ | ||||
| --- | ||||
| name: Bug report | ||||
| about: Create a report to help us improve | ||||
| --- | ||||
|  | ||||
| ### Troubleshooting | ||||
|  | ||||
| Before submitting a bug report please read the [Troubleshooting doc](https://github.com/docker/build-push-action/blob/master/TROUBLESHOOTING.md). | ||||
|  | ||||
| ### Behaviour | ||||
|  | ||||
| #### Steps to reproduce this issue | ||||
|  | ||||
| 1. | ||||
| 2. | ||||
| 3. | ||||
|  | ||||
| #### Expected behaviour | ||||
|  | ||||
| > Tell us what should happen | ||||
|  | ||||
| #### Actual behaviour | ||||
|  | ||||
| > Tell us what happens instead | ||||
|  | ||||
| ### Configuration | ||||
|  | ||||
| * Repository URL (if public):  | ||||
| * Build URL (if public):  | ||||
|  | ||||
| ```yml | ||||
| # paste your YAML workflow file here and remove sensitive data | ||||
| ``` | ||||
|  | ||||
| ### Logs | ||||
|  | ||||
| > 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. | ||||
							
								
								
									
										9
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser | ||||
| blank_issues_enabled: true | ||||
| contact_links: | ||||
|   - name: Questions and Discussions | ||||
|     url: https://github.com/docker/build-push-action/discussions/new | ||||
|     about: Use Github Discussions to ask questions and/or open discussion topics. | ||||
|   - name: Documentation | ||||
|     url: https://docs.docker.com/build/ci/github-actions/ | ||||
|     about: Read the documentation. | ||||
							
								
								
									
										15
									
								
								.github/ISSUE_TEMPLATE/feature.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								.github/ISSUE_TEMPLATE/feature.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema | ||||
| name: Feature request | ||||
| description: Missing functionality? Come tell us about it! | ||||
| labels: | ||||
|   - kind/enhancement | ||||
|   - status/triage | ||||
|  | ||||
| body: | ||||
|   - type: textarea | ||||
|     id: description | ||||
|     attributes: | ||||
|       label: Description | ||||
|       description: What is the feature you want to see? | ||||
|     validations: | ||||
|       required: true | ||||
							
								
								
									
										12
									
								
								.github/SECURITY.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.github/SECURITY.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| # Reporting security issues | ||||
|  | ||||
| The project maintainers take security seriously. If you discover a security | ||||
| issue, please bring it to their attention right away! | ||||
|  | ||||
| **Please _DO NOT_ file a public issue**, instead send your report privately to | ||||
| [security@docker.com](mailto:security@docker.com). | ||||
|  | ||||
| Security reports are greatly appreciated, and we will publicly thank you for it. | ||||
| We also like to send gifts—if you'd like Docker swag, make sure to let | ||||
| us know. We currently do not offer a paid security bounty program, but are not | ||||
| ruling it out in the future. | ||||
							
								
								
									
										31
									
								
								.github/SUPPORT.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								.github/SUPPORT.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,31 +0,0 @@ | ||||
| # Support [](https://isitmaintained.com/project/docker/build-push-action) | ||||
|  | ||||
| First, [be a good guy](https://github.com/kossnocorp/etiquette/blob/master/README.md). | ||||
|  | ||||
| ## Reporting an issue | ||||
|  | ||||
| Please do a search in [open issues](https://github.com/docker/build-push-action/issues?utf8=%E2%9C%93&q=) to see if the issue or feature request has already been filed. | ||||
|  | ||||
| If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment. | ||||
|  | ||||
| :+1: - upvote | ||||
|  | ||||
| :-1: - downvote | ||||
|  | ||||
| If you cannot find an existing issue that describes your bug or feature, submit an issue using the guidelines below. | ||||
|  | ||||
| ## Writing good bug reports and feature requests | ||||
|  | ||||
| File a single issue per problem and feature request. | ||||
|  | ||||
| * Do not enumerate multiple bugs or feature requests in the same issue. | ||||
| * Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes. | ||||
|  | ||||
| The more information you can provide, the more likely someone will be successful reproducing the issue and finding a fix. | ||||
|  | ||||
| You are now ready to [create a new issue](https://github.com/docker/build-push-action/issues/new/choose)! | ||||
|  | ||||
| ## Closure policy | ||||
|  | ||||
| * Issues that don't have the information requested above (when applicable) will be closed immediately and the poster directed to the support guidelines. | ||||
| * Issues that go a week without a response from original poster are subject to closure at our discretion. | ||||
							
								
								
									
										1
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
								
							| @@ -11,6 +11,7 @@ updates: | ||||
|     directory: "/" | ||||
|     schedule: | ||||
|       interval: "daily" | ||||
|     versioning-strategy: "increase" | ||||
|     allow: | ||||
|       - dependency-type: "production" | ||||
|     labels: | ||||
|   | ||||
							
								
								
									
										5
									
								
								.github/e2e/distribution/env
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.github/e2e/distribution/env
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| REGISTRY_FQDN=localhost:8080 | ||||
| REGISTRY_SLUG=localhost:8080/test-docker-action | ||||
|  | ||||
| DISTRIBUTION_HOST=localhost | ||||
| DISTRIBUTION_PORT=8080 | ||||
							
								
								
									
										13
									
								
								.github/e2e/distribution/install.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								.github/e2e/distribution/install.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #!/usr/bin/env bash | ||||
| set -eu | ||||
|  | ||||
| : "${DISTRIBUTION_VERSION:=2}" | ||||
| : "${DISTRIBUTION_HOST:=localhost}" | ||||
| : "${DISTRIBUTION_PORT:=8080}" | ||||
|  | ||||
| echo "::group::Starting registry:${DISTRIBUTION_VERSION}" | ||||
| ( | ||||
|   set -x | ||||
|   docker run -d --name registry -p "${DISTRIBUTION_PORT}:5000" "registry:${DISTRIBUTION_VERSION}" | ||||
| ) | ||||
| echo "::endgroup::" | ||||
							
								
								
									
										8
									
								
								.github/e2e/harbor/env
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.github/e2e/harbor/env
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| REGISTRY_FQDN=localhost:8081 | ||||
| REGISTRY_USER=admin | ||||
| REGISTRY_PASSWORD=Harbor12345 | ||||
| REGISTRY_SLUG=localhost:8081/test-docker-action/test-docker-action | ||||
|  | ||||
| HARBOR_HOST=localhost | ||||
| HARBOR_PORT=8081 | ||||
| HARBOR_PROJECT=test-docker-action | ||||
							
								
								
									
										79
									
								
								.github/e2e/harbor/install.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										79
									
								
								.github/e2e/harbor/install.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| #!/usr/bin/env bash | ||||
| set -eu | ||||
|  | ||||
| : "${HARBOR_VERSION:=v2.7.0}" | ||||
| : "${HARBOR_HOST:=localhost}" | ||||
| : "${HARBOR_PORT:=49154}" | ||||
| : "${REGISTRY_USER:=admin}" | ||||
| : "${REGISTRY_PASSWORD:=Harbor12345}" | ||||
|  | ||||
| : "${HARBOR_PROJECT:=test-docker-action}" | ||||
|  | ||||
| project_post_data() { | ||||
|   cat <<EOF | ||||
| { | ||||
|   "project_name": "$HARBOR_PROJECT", | ||||
|   "public": true | ||||
| } | ||||
| EOF | ||||
| } | ||||
|  | ||||
| export TERM=xterm | ||||
|  | ||||
| # download | ||||
| echo "::group::Downloading Harbor $HARBOR_VERSION" | ||||
| ( | ||||
|   cd /tmp | ||||
|   set -x | ||||
|   wget -q "https://github.com/goharbor/harbor/releases/download/${HARBOR_VERSION}/harbor-offline-installer-${HARBOR_VERSION}.tgz" -O harbor-online-installer.tgz | ||||
|   tar xvf harbor-online-installer.tgz | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| # config | ||||
| echo "::group::Configuring Harbor" | ||||
| ( | ||||
|   cd /tmp/harbor | ||||
|   set -x | ||||
|   cp harbor.yml.tmpl harbor.yml | ||||
|   harborConfig="$(harborHost="$HARBOR_HOST" harborPort="$HARBOR_PORT" harborPwd="$REGISTRY_PASSWORD" yq --no-colors '.hostname = env(harborHost) | .http.port = env(harborPort) | .harbor_admin_password = env(harborPwd) | del(.https)' harbor.yml)" | ||||
|   tee harbor.yml <<<"$harborConfig" >/dev/null | ||||
|   yq --no-colors harbor.yml | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| # install and start | ||||
| echo "::group::Installing Harbor" | ||||
| ( | ||||
|   cd /tmp/harbor | ||||
|   set -x | ||||
|   ./install.sh | ||||
|   sleep 10 | ||||
|   netstat -aptn | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| # compose config | ||||
| echo "::group::Compose config" | ||||
| ( | ||||
|   cd /tmp/harbor | ||||
|   set -x | ||||
|   docker compose config | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| # create project | ||||
| echo "::group::Creating project" | ||||
| ( | ||||
|   set -x | ||||
|   curl --fail -v -k --max-time 10 -u "$REGISTRY_USER:$REGISTRY_PASSWORD" -X POST -H "Content-Type: application/json" -d "$(project_post_data)" "http://$HARBOR_HOST:$HARBOR_PORT/api/v2.0/projects" | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| # list projects | ||||
| echo "::group::List projects" | ||||
| ( | ||||
|   set -x | ||||
|   curl --fail -s -k --max-time 10 -u "$REGISTRY_USER:$REGISTRY_PASSWORD" -H "Content-Type: application/json" "http://$HARBOR_HOST:$HARBOR_PORT/api/v2.0/projects" | jq | ||||
| ) | ||||
| echo "::endgroup::" | ||||
							
								
								
									
										8
									
								
								.github/e2e/nexus/docker-compose.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.github/e2e/nexus/docker-compose.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| services: | ||||
|   nexus: | ||||
|     image: sonatype/nexus3:${NEXUS_VERSION:-latest} | ||||
|     volumes: | ||||
|       - "./data:/nexus-data" | ||||
|     ports: | ||||
|       - "8081:8081" | ||||
|       - "8082:8082" | ||||
							
								
								
									
										9
									
								
								.github/e2e/nexus/env
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.github/e2e/nexus/env
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| REGISTRY_FQDN=localhost:8082 | ||||
| REGISTRY_USER=admin | ||||
| REGISTRY_PASSWORD=Nexus12345 | ||||
| REGISTRY_SLUG=localhost:8082/test-docker-action | ||||
|  | ||||
| NEXUS_HOST=localhost | ||||
| NEXUS_PORT=8081 | ||||
| NEXUS_REGISTRY_PORT=8082 | ||||
| NEXUS_REPO=test-docker-action | ||||
							
								
								
									
										93
									
								
								.github/e2e/nexus/install.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										93
									
								
								.github/e2e/nexus/install.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| #!/usr/bin/env bash | ||||
| set -eu | ||||
|  | ||||
| SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) | ||||
|  | ||||
| : "${NEXUS_VERSION:=3.47.1}" | ||||
| : "${NEXUS_HOST:=localhost}" | ||||
| : "${NEXUS_PORT:=8081}" | ||||
| : "${NEXUS_REGISTRY_PORT:=8082}" | ||||
| : "${REGISTRY_USER:=admin}" | ||||
| : "${REGISTRY_PASSWORD:=Nexus12345}" | ||||
|  | ||||
| : "${NEXUS_REPO:=test-docker-action}" | ||||
|  | ||||
| createrepo_post_data() { | ||||
|   cat <<EOF | ||||
| { | ||||
|   "name": "${NEXUS_REPO}", | ||||
|   "online": true, | ||||
|   "storage": { | ||||
|     "blobStoreName": "default", | ||||
|     "strictContentTypeValidation": true, | ||||
|     "writePolicy": "ALLOW" | ||||
|   }, | ||||
|   "docker": { | ||||
|     "v1Enabled": false, | ||||
|     "forceBasicAuth": true, | ||||
|     "httpPort": ${NEXUS_REGISTRY_PORT}, | ||||
|     "httpsPort": null, | ||||
|     "subdomain": null | ||||
|   } | ||||
| } | ||||
| EOF | ||||
| } | ||||
|  | ||||
| export NEXUS_VERSION | ||||
|  | ||||
| mkdir -p /tmp/nexus/data | ||||
| chown 200:200 /tmp/nexus/data | ||||
| cp "${SCRIPT_DIR}/docker-compose.yml" /tmp/nexus/docker-compose.yml | ||||
|  | ||||
| echo "::group::Pulling Nexus $NEXUS_VERSION" | ||||
| ( | ||||
|   cd /tmp/nexus | ||||
|   set -x | ||||
|   docker compose pull | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| echo "::group::Compose config" | ||||
| ( | ||||
|   cd /tmp/nexus | ||||
|   set -x | ||||
|   docker compose config | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| echo "::group::Running Nexus" | ||||
| ( | ||||
|   cd /tmp/nexus | ||||
|   set -x | ||||
|   docker compose up -d | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| echo "::group::Running Nexus" | ||||
| ( | ||||
|   cd /tmp/nexus | ||||
|   set -x | ||||
|   docker compose up -d | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| echo "::group::Waiting for Nexus to be ready" | ||||
| until $(curl --output /dev/null --silent --head --fail "http://$NEXUS_HOST:$NEXUS_PORT"); do | ||||
|   printf '.' | ||||
|   sleep 5 | ||||
| done | ||||
| echo "::endgroup::" | ||||
|  | ||||
| echo "::group::Change user's password" | ||||
| ( | ||||
|   set -x | ||||
|   curl --fail -v -k --max-time 10 -u "$REGISTRY_USER:$(cat /tmp/nexus/data/admin.password)" -X PUT -H 'Content-Type: text/plain' -d "$REGISTRY_PASSWORD" "http://$NEXUS_HOST:$NEXUS_PORT/service/rest/v1/security/users/$REGISTRY_USER/change-password" | ||||
| ) | ||||
| echo "::endgroup::" | ||||
|  | ||||
| echo "::group::Create Docker repository" | ||||
| ( | ||||
|   set -x | ||||
|   curl --fail -v -k --max-time 10 -u "$REGISTRY_USER:$REGISTRY_PASSWORD" -X POST -H 'Content-Type: application/json' -d "$(createrepo_post_data)" "http://$NEXUS_HOST:$NEXUS_PORT/service/rest/v1/repositories/docker/hosted" | ||||
| ) | ||||
| echo "::endgroup::" | ||||
							
								
								
									
										130
									
								
								.github/workflows/.e2e-run.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								.github/workflows/.e2e-run.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,130 @@ | ||||
| # reusable workflow | ||||
| name: .e2e-run | ||||
|  | ||||
| on: | ||||
|   workflow_call: | ||||
|     inputs: | ||||
|       id: | ||||
|         required: false | ||||
|         type: string | ||||
|       type: | ||||
|         required: true | ||||
|         type: string | ||||
|       name: | ||||
|         required: true | ||||
|         type: string | ||||
|       registry: | ||||
|         required: false | ||||
|         type: string | ||||
|       slug: | ||||
|         required: false | ||||
|         type: string | ||||
|       username_secret: | ||||
|         required: false | ||||
|         type: string | ||||
|       password_secret: | ||||
|         required: false | ||||
|         type: string | ||||
|  | ||||
| env: | ||||
|   HARBOR_VERSION: v2.7.0 | ||||
|   NEXUS_VERSION: 3.47.1 | ||||
|   DISTRIBUTION_VERSION: 2.8.1 | ||||
|  | ||||
| jobs: | ||||
|   run: | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - | ||||
|             buildx_version: latest | ||||
|             buildkit_image: moby/buildkit:buildx-stable-1 | ||||
|           - | ||||
|             buildx_version: https://github.com/docker/buildx.git#master | ||||
|             buildkit_image: moby/buildkit:master | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up env | ||||
|         if: inputs.type == 'local' | ||||
|         run: | | ||||
|           cat ./.github/e2e/${{ inputs.id }}/env >> $GITHUB_ENV | ||||
|       - | ||||
|         name: Set up BuildKit config | ||||
|         run: | | ||||
|           touch /tmp/buildkitd.toml | ||||
|           if [ "${{ inputs.type }}" = "local" ]; then | ||||
|             echo -e "[registry.\"${{ env.REGISTRY_FQDN }}\"]\nhttp = true\ninsecure = true" > /tmp/buildkitd.toml | ||||
|           fi | ||||
|       - | ||||
|         name: Set up Docker daemon | ||||
|         if: inputs.type == 'local' | ||||
|         run: | | ||||
|           if [ ! -e /etc/docker/daemon.json ]; then | ||||
|             echo '{}' | tee /etc/docker/daemon.json >/dev/null | ||||
|           fi | ||||
|           DOCKERD_CONFIG=$(jq '.+{"insecure-registries":["http://${{ env.REGISTRY_FQDN }}"]}' /etc/docker/daemon.json) | ||||
|           sudo tee /etc/docker/daemon.json <<<"$DOCKERD_CONFIG" >/dev/null | ||||
|           sudo service docker restart | ||||
|       - | ||||
|         name: Install ${{ inputs.name }} | ||||
|         if: inputs.type == 'local' | ||||
|         run: | | ||||
|           sudo -E bash ./.github/e2e/${{ inputs.id }}/install.sh | ||||
|           sudo chown $(id -u):$(id -g) -R ~/.docker | ||||
|       - | ||||
|         name: Docker meta | ||||
|         id: meta | ||||
|         uses: docker/metadata-action@v5 | ||||
|         with: | ||||
|           images: ${{ env.REGISTRY_SLUG || inputs.slug }} | ||||
|           tags: | | ||||
|             type=ref,event=branch,enable=${{ matrix.buildx_version == 'latest' && matrix.buildkit_image == 'moby/buildkit:buildx-stable-1' }} | ||||
|             type=ref,event=tag,enable=${{ matrix.buildx_version == 'latest' && matrix.buildkit_image == 'moby/buildkit:buildx-stable-1' }} | ||||
|             type=raw,gh-runid-${{ github.run_id }} | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ matrix.buildx_version }} | ||||
|           config: /tmp/buildkitd.toml | ||||
|           buildkitd-flags: --debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host | ||||
|           driver-opts: | | ||||
|             image=${{ matrix.buildkit_image }} | ||||
|             network=host | ||||
|       - | ||||
|         name: Login to Registry | ||||
|         if: github.event_name != 'pull_request' && (env.REGISTRY_USER || inputs.username_secret) != '' | ||||
|         uses: docker/login-action@v3 | ||||
|         with: | ||||
|           registry: ${{ env.REGISTRY_FQDN || inputs.registry }} | ||||
|           username: ${{ env.REGISTRY_USER || secrets[inputs.username_secret] }} | ||||
|           password: ${{ env.REGISTRY_PASSWORD || secrets[inputs.password_secret] }} | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/multi.Dockerfile | ||||
|           platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x | ||||
|           push: ${{ github.event_name != 'pull_request' }} | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|           cache-from: type=registry,ref=${{ env.REGISTRY_SLUG || inputs.slug }}:master | ||||
|           cache-to: type=inline | ||||
|       - | ||||
|         name: Inspect image | ||||
|         run: | | ||||
|           docker pull ${{ env.REGISTRY_SLUG || inputs.slug }}:${{ steps.meta.outputs.version }} | ||||
|           docker image inspect ${{ env.REGISTRY_SLUG || inputs.slug }}:${{ steps.meta.outputs.version }} | ||||
|       - | ||||
|         name: Check manifest | ||||
|         run: | | ||||
|           docker buildx imagetools inspect ${{ env.REGISTRY_SLUG || inputs.slug }}:${{ steps.meta.outputs.version }} --format '{{json .}}' | ||||
							
								
								
									
										588
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										588
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,9 @@ | ||||
| name: ci | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{ github.workflow }}-${{ github.ref }} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|     inputs: | ||||
| @@ -11,12 +15,13 @@ on: | ||||
|         description: 'BuildKit image' | ||||
|         default: 'moby/buildkit:buildx-stable-1' | ||||
|         required: false | ||||
|   schedule: | ||||
|     - cron: '0 10 * * *' | ||||
|   push: | ||||
|     branches: | ||||
|       - 'master' | ||||
|       - 'releases/v*' | ||||
|   pull_request: | ||||
|     branches: | ||||
|       - 'master' | ||||
|  | ||||
| env: | ||||
|   BUILDX_VERSION: latest | ||||
| @@ -28,12 +33,12 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|         with: | ||||
|           path: action | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -54,16 +59,16 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|         with: | ||||
|           path: action | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -103,16 +108,16 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|         with: | ||||
|           path: action | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -162,14 +167,14 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -199,16 +204,79 @@ jobs: | ||||
|             exit 1 | ||||
|           fi | ||||
|  | ||||
|   example: | ||||
|     runs-on: ubuntu-latest | ||||
|     env: | ||||
|       DOCKER_IMAGE: localhost:5000/name/app | ||||
|     services: | ||||
|       registry: | ||||
|         image: registry:2 | ||||
|         ports: | ||||
|           - 5000:5000 | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Docker meta | ||||
|         id: meta | ||||
|         uses: docker/metadata-action@v5 | ||||
|         with: | ||||
|           images: ${{ env.DOCKER_IMAGE }} | ||||
|           tags: | | ||||
|             type=schedule | ||||
|             type=ref,event=branch | ||||
|             type=ref,event=pr | ||||
|             type=semver,pattern={{version}} | ||||
|             type=semver,pattern={{major}}.{{minor}} | ||||
|             type=semver,pattern={{major}} | ||||
|             type=sha | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             network=host | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|       - | ||||
|         name: Build and export to Docker client | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/Dockerfile | ||||
|           load: true | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|       - | ||||
|         name: Build and push to local registry | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/Dockerfile | ||||
|           push: ${{ github.event_name != 'pull_request' }} | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|       - | ||||
|         name: Inspect image | ||||
|         run: | | ||||
|           docker image inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }} | ||||
|       - | ||||
|         name: Check manifest | ||||
|         if: github.event_name != 'pull_request' | ||||
|         run: | | ||||
|           docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }} --format '{{json .}}' | ||||
|  | ||||
|   error: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Stop docker | ||||
|         run: | | ||||
|           sudo systemctl stop docker | ||||
|           sudo systemctl stop docker docker.socket | ||||
|       - | ||||
|         name: Build | ||||
|         id: docker_build | ||||
| @@ -231,13 +299,13 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -272,7 +340,7 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Build | ||||
|         id: docker_build | ||||
| @@ -288,7 +356,7 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Build | ||||
|         uses: ./ | ||||
| @@ -307,10 +375,10 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -325,15 +393,40 @@ jobs: | ||||
|             MYSECRET=foo | ||||
|             INVALID_SECRET= | ||||
|  | ||||
|   secret-envs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|       - | ||||
|         name: Build | ||||
|         uses: ./ | ||||
|         env: | ||||
|           ENV_SECRET: foo | ||||
|         with: | ||||
|           context: . | ||||
|           file: ./test/secret.Dockerfile | ||||
|           secret-envs: | | ||||
|             MYSECRET=ENV_SECRET | ||||
|             INVALID_SECRET= | ||||
|  | ||||
|   network: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -354,10 +447,10 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -376,10 +469,10 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -401,10 +494,10 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -424,10 +517,10 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -444,38 +537,15 @@ jobs: | ||||
|             docker:10.180.0.1 | ||||
|             foo:10.0.0.1 | ||||
|  | ||||
|   build-contexts: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|       - | ||||
|         name: Build | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/buildcontext.Dockerfile | ||||
|           build-contexts: | | ||||
|             alpine=docker-image://debian:stable-slim | ||||
|           tags: name/app:latest | ||||
|  | ||||
|   no-cache-filters: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -506,10 +576,10 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ matrix.buildx }} | ||||
|           driver-opts: | | ||||
| @@ -528,19 +598,31 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         attrs: | ||||
|           - '' | ||||
|           - mode=max | ||||
|           - builder-id=foo | ||||
|           - false | ||||
|           - true | ||||
|         include: | ||||
|           - target: image | ||||
|             output: type=image,name=localhost:5000/name/app:latest,push=true | ||||
|             attr: mode=max | ||||
|           - target: image | ||||
|             output: type=image,name=localhost:5000/name/app:latest,push=true | ||||
|             attr: '' | ||||
|           - target: binary | ||||
|             output: /tmp/buildx-build | ||||
|             attr: mode=max | ||||
|           - target: binary | ||||
|             output: /tmp/buildx-build | ||||
|             attr: '' | ||||
|     services: | ||||
|       registry: | ||||
|         image: registry:2 | ||||
|         ports: | ||||
|           - 5000:5000 | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -552,11 +634,24 @@ jobs: | ||||
|         with: | ||||
|           context: ./test/go | ||||
|           file: ./test/go/Dockerfile | ||||
|           target: binary | ||||
|           outputs: type=oci,dest=/tmp/build.tar | ||||
|           provenance: ${{ matrix.attrs }} | ||||
|           cache-from: type=gha,scope=provenance | ||||
|           cache-to: type=gha,scope=provenance,mode=max | ||||
|           target: ${{ matrix.target }} | ||||
|           outputs: ${{ matrix.output }} | ||||
|           provenance: ${{ matrix.attr }} | ||||
|       - | ||||
|         name: Inspect Provenance | ||||
|         if: matrix.target == 'image' | ||||
|         run: | | ||||
|           docker buildx imagetools inspect localhost:5000/name/app:latest --format '{{json .Provenance}}' | ||||
|       - | ||||
|         name: Check output folder | ||||
|         if: matrix.target == 'binary' | ||||
|         run: | | ||||
|           tree /tmp/buildx-build | ||||
|       - | ||||
|         name: Print local Provenance | ||||
|         if: matrix.target == 'binary' | ||||
|         run: | | ||||
|           cat /tmp/buildx-build/provenance.json | jq | ||||
|  | ||||
|   sbom: | ||||
|     runs-on: ubuntu-latest | ||||
| @@ -576,10 +671,10 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -597,17 +692,17 @@ jobs: | ||||
|           cache-from: type=gha,scope=attests-${{ matrix.target }} | ||||
|           cache-to: type=gha,scope=attests-${{ matrix.target }},mode=max | ||||
|       - | ||||
|         name: Inspect image | ||||
|         name: Inspect SBOM | ||||
|         if: matrix.target == 'image' | ||||
|         run: | | ||||
|           docker buildx imagetools inspect localhost:5000/name/app:latest --format '{{json .}}' | ||||
|           docker buildx imagetools inspect localhost:5000/name/app:latest --format '{{json .SBOM}}' | ||||
|       - | ||||
|         name: Check output folder | ||||
|         if: matrix.target == 'binary' | ||||
|         run: | | ||||
|           tree /tmp/buildx-build | ||||
|       - | ||||
|         name: Print SBOM | ||||
|         name: Print local SBOM | ||||
|         if: matrix.target == 'binary' | ||||
|         run: | | ||||
|           cat /tmp/buildx-build/sbom.spdx.json | jq | ||||
| @@ -628,14 +723,14 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -689,12 +784,6 @@ jobs: | ||||
|           - driver: docker-container | ||||
|             load: true | ||||
|             push: true | ||||
|           - driver: docker | ||||
|             load: false | ||||
|             push: false | ||||
|           - driver: docker-container | ||||
|             load: false | ||||
|             push: false | ||||
|     services: | ||||
|       registry: | ||||
|         image: registry:2 | ||||
| @@ -703,10 +792,10 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver: ${{ matrix.driver }} | ||||
| @@ -728,9 +817,13 @@ jobs: | ||||
|           docker image ls --no-trunc | ||||
|       - | ||||
|         name: Check digest | ||||
|         if: ${{ matrix.push }} | ||||
|         run: | | ||||
|           if [ -z "${{ steps.docker_build.outputs.digest }}" ]; then | ||||
|           if [[ "${{ matrix.driver }}" = "docker-container" ]] && [[ "${{ matrix.load }}" = "false" ]] && [[ "${{ matrix.push }}" = "false" ]]; then | ||||
|             if [ -n "${{ steps.docker_build.outputs.digest }}" ]; then | ||||
|               echo "::error::Digest should be empty" | ||||
|               exit 1 | ||||
|             fi | ||||
|           elif [[ "${{ matrix.push }}" = "true" ]] && [[ -z "${{ steps.docker_build.outputs.digest }}" ]]; then | ||||
|             echo "::error::Digest should not be empty" | ||||
|             exit 1 | ||||
|           fi | ||||
| @@ -743,7 +836,12 @@ jobs: | ||||
|       - | ||||
|         name: Check image ID | ||||
|         run: | | ||||
|           if [ -z "${{ steps.docker_build.outputs.imageid }}" ]; then | ||||
|           if [[ "${{ matrix.driver }}" = "docker-container" ]] && [[ "${{ matrix.load }}" = "false" ]] && [[ "${{ matrix.push }}" = "false" ]]; then | ||||
|             if [ -n "${{ steps.docker_build.outputs.imageid }}" ]; then | ||||
|               echo "::error::Image ID should be empty" | ||||
|               exit 1 | ||||
|             fi | ||||
|           elif [ -z "${{ steps.docker_build.outputs.imageid }}" ]; then | ||||
|             echo "::error::Image ID should not be empty" | ||||
|             exit 1 | ||||
|           fi | ||||
| @@ -764,13 +862,13 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -813,13 +911,13 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -844,19 +942,80 @@ jobs: | ||||
|         run: | | ||||
|           docker buildx imagetools inspect localhost:5000/name/app:1.0.0 --format '{{json .}}' | ||||
|  | ||||
|   local-cache: | ||||
|     runs-on: ubuntu-latest | ||||
|     services: | ||||
|       registry: | ||||
|         image: registry:2 | ||||
|         ports: | ||||
|           - 5000:5000 | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             network=host | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|           buildkitd-flags: --debug | ||||
|       - | ||||
|         name: Cache Build | ||||
|         uses: actions/cache@v4 | ||||
|         with: | ||||
|           path: /tmp/.buildx-cache | ||||
|           key: ${{ runner.os }}-local-test-${{ github.sha }} | ||||
|           restore-keys: | | ||||
|             ${{ runner.os }}-local-test- | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/multi.Dockerfile | ||||
|           platforms: linux/amd64,linux/arm64 | ||||
|           push: true | ||||
|           tags: | | ||||
|             localhost:5000/name/app:latest | ||||
|             localhost:5000/name/app:1.0.0 | ||||
|           cache-from: type=local,src=/tmp/.buildx-cache | ||||
|           cache-to: type=local,dest=/tmp/.buildx-cache-new | ||||
|       - | ||||
|         name: Inspect | ||||
|         run: | | ||||
|           docker buildx imagetools inspect localhost:5000/name/app:1.0.0 --format '{{json .}}' | ||||
|       - | ||||
|         # Temp fix | ||||
|         # https://github.com/docker/build-push-action/issues/252 | ||||
|         # https://github.com/moby/buildkit/issues/1896 | ||||
|         name: Move cache | ||||
|         run: | | ||||
|           rm -rf /tmp/.buildx-cache | ||||
|           mv /tmp/.buildx-cache-new /tmp/.buildx-cache | ||||
|  | ||||
|   standalone: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Uninstall moby cli | ||||
|         name: Uninstall docker cli | ||||
|         run: | | ||||
|           sudo apt-get purge -y moby-cli moby-buildx | ||||
|           if dpkg -s "docker-ce" >/dev/null 2>&1; then | ||||
|             sudo dpkg -r --force-depends docker-ce-cli docker-buildx-plugin | ||||
|           else | ||||
|             sudo apt-get purge -y moby-cli moby-buildx | ||||
|           fi | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
| @@ -868,3 +1027,230 @@ jobs: | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/Dockerfile | ||||
|  | ||||
|   named-context-pin: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|       - | ||||
|         name: Build base image | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/named-context.Dockerfile | ||||
|           build-contexts: | | ||||
|             alpine=docker-image://alpine:edge | ||||
|  | ||||
|   named-context-docker: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver: docker | ||||
|       - | ||||
|         name: Build base image | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/named-context-base.Dockerfile | ||||
|           load: true | ||||
|           tags: my-base-image:local | ||||
|       - | ||||
|         name: Build | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/named-context.Dockerfile | ||||
|           build-contexts: | | ||||
|             base=docker-image://my-base-image:local | ||||
|  | ||||
|   named-context-container: | ||||
|     runs-on: ubuntu-latest | ||||
|     services: | ||||
|       registry: | ||||
|         image: registry:2 | ||||
|         ports: | ||||
|           - 5000:5000 | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|             network=host | ||||
|       - | ||||
|         name: Build base image | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/named-context-base.Dockerfile | ||||
|           tags: localhost:5000/my-base-image:latest | ||||
|           push: true | ||||
|       - | ||||
|         name: Build | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/named-context.Dockerfile | ||||
|           build-contexts: | | ||||
|             alpine=docker-image://localhost:5000/my-base-image:latest | ||||
|  | ||||
|   docker-config-malformed: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set malformed docker config | ||||
|         run: | | ||||
|           mkdir -p ~/.docker | ||||
|           echo 'foo_bar' >> ~/.docker/config.json | ||||
|       - | ||||
|         name: Build | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|  | ||||
|   proxy-docker-config: | ||||
|     runs-on: ubuntu-latest | ||||
|     services: | ||||
|       squid-proxy: | ||||
|         image: ubuntu/squid:latest | ||||
|         ports: | ||||
|           - 3128:3128 | ||||
|     steps: | ||||
|       - | ||||
|         name: Check proxy | ||||
|         run: | | ||||
|           netstat -aptn | ||||
|           curl --retry 5 --retry-all-errors --retry-delay 0 --connect-timeout 5 --proxy http://127.0.0.1:3128 -v --insecure --head https://www.google.com | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set proxy config | ||||
|         run: | | ||||
|           mkdir -p ~/.docker | ||||
|           echo '{"proxies":{"default":{"httpProxy":"http://127.0.0.1:3128","httpsProxy":"http://127.0.0.1:3128"}}}' > ~/.docker/config.json | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|             network=host | ||||
|           buildkitd-flags: --debug | ||||
|       - | ||||
|         name: Build | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/proxy.Dockerfile | ||||
|  | ||||
|   proxy-buildkitd: | ||||
|     runs-on: ubuntu-latest | ||||
|     services: | ||||
|       squid-proxy: | ||||
|         image: ubuntu/squid:latest | ||||
|         ports: | ||||
|           - 3128:3128 | ||||
|     steps: | ||||
|       - | ||||
|         name: Check proxy | ||||
|         run: | | ||||
|           netstat -aptn | ||||
|           curl --retry 5 --retry-all-errors --retry-delay 0 --connect-timeout 5 --proxy http://127.0.0.1:3128 -v --insecure --head https://www.google.com | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|             network=host | ||||
|             env.http_proxy=http://127.0.0.1:3128 | ||||
|             env.https_proxy=http://127.0.0.1:3128 | ||||
|           buildkitd-flags: --debug | ||||
|       - | ||||
|         name: Build | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/Dockerfile | ||||
|  | ||||
|   annotations: | ||||
|     runs-on: ubuntu-latest | ||||
|     env: | ||||
|       DOCKER_IMAGE: localhost:5000/name/app | ||||
|     services: | ||||
|       registry: | ||||
|         image: registry:2 | ||||
|         ports: | ||||
|           - 5000:5000 | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Docker meta | ||||
|         id: meta | ||||
|         uses: docker/metadata-action@v5 | ||||
|         with: | ||||
|           images: ${{ env.DOCKER_IMAGE }} | ||||
|           tags: | | ||||
|             type=schedule | ||||
|             type=ref,event=branch | ||||
|             type=ref,event=pr | ||||
|             type=semver,pattern={{version}} | ||||
|             type=semver,pattern={{major}}.{{minor}} | ||||
|             type=semver,pattern={{major}} | ||||
|             type=sha | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             network=host | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|       - | ||||
|         name: Build and push to local registry | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/Dockerfile | ||||
|           push: true | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           annotations: | | ||||
|             index:com.example.key=value | ||||
|             index:com.example.key2=value2 | ||||
|             manifest:com.example.key3=value3 | ||||
|       - | ||||
|         name: Check manifest | ||||
|         run: | | ||||
|           docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }} --format '{{json .}}' | ||||
|   | ||||
							
								
								
									
										125
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										125
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,123 +1,114 @@ | ||||
| name: e2e | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{ github.workflow }}-${{ github.ref }} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|     inputs: | ||||
|       buildx-version: | ||||
|         description: 'Buildx version or Git context' | ||||
|         default: 'latest' | ||||
|         required: false | ||||
|       buildkit-image: | ||||
|         description: 'BuildKit image' | ||||
|         default: 'moby/buildkit:buildx-stable-1' | ||||
|         required: false | ||||
|   schedule: | ||||
|     - cron: '0 10 * * *' | ||||
|   push: | ||||
|     branches: | ||||
|       - 'master' | ||||
|     tags: | ||||
|       - v* | ||||
|  | ||||
| env: | ||||
|   BUILDX_VERSION: latest | ||||
|   BUILDKIT_IMAGE: moby/buildkit:buildx-stable-1 | ||||
|       - 'v*' | ||||
|  | ||||
| jobs: | ||||
|   docker: | ||||
|     runs-on: ubuntu-latest | ||||
|   build: | ||||
|     uses: ./.github/workflows/.e2e-run.yml | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           - | ||||
|             name: Distribution | ||||
|             id: distribution | ||||
|             type: local | ||||
|           - | ||||
|             name: Docker Hub | ||||
|             registry: '' | ||||
|             slug: ghactionstest/ghactionstest | ||||
|             username_secret: DOCKERHUB_USERNAME | ||||
|             password_secret: DOCKERHUB_TOKEN | ||||
|             type: remote | ||||
|           - | ||||
|             name: GitHub | ||||
|             registry: ghcr.io | ||||
|             slug: ghcr.io/docker-ghactiontest/test | ||||
|             username_secret: GHCR_USERNAME | ||||
|             password_secret: GHCR_PAT | ||||
|             type: remote | ||||
|           - | ||||
|             name: GitLab | ||||
|             registry: registry.gitlab.com | ||||
|             slug: registry.gitlab.com/test1716/test | ||||
|             username_secret: GITLAB_USERNAME | ||||
|             password_secret: GITLAB_TOKEN | ||||
|             type: remote | ||||
|           - | ||||
|             name: AWS ECR | ||||
|             registry: 175142243308.dkr.ecr.us-east-2.amazonaws.com | ||||
|             slug: 175142243308.dkr.ecr.us-east-2.amazonaws.com/sandbox/test-docker-action | ||||
|             username_secret: AWS_ACCESS_KEY_ID | ||||
|             password_secret: AWS_SECRET_ACCESS_KEY | ||||
|             type: remote | ||||
|           - | ||||
|             name: AWS ECR Public | ||||
|             registry: public.ecr.aws | ||||
|             slug: public.ecr.aws/q3b5f1u4/test-docker-action | ||||
|             username_secret: AWS_ACCESS_KEY_ID | ||||
|             password_secret: AWS_SECRET_ACCESS_KEY | ||||
|             type: remote | ||||
|           - | ||||
|             name: Google Artifact Registry | ||||
|             registry: us-east4-docker.pkg.dev | ||||
|             slug: us-east4-docker.pkg.dev/sandbox-298914/docker-official-github-actions/test-docker-action | ||||
|             username_secret: GAR_USERNAME | ||||
|             password_secret: GAR_JSON_KEY | ||||
|             type: remote | ||||
|           - | ||||
|             name: Google Container Registry | ||||
|             registry: gcr.io | ||||
|             slug: gcr.io/sandbox-298914/test-docker-action | ||||
|             username_secret: GCR_USERNAME | ||||
|             password_secret: GCR_JSON_KEY | ||||
|             type: remote | ||||
|           - | ||||
|             name: Azure Container Registry | ||||
|             registry: officialgithubactions.azurecr.io | ||||
|             slug: officialgithubactions.azurecr.io/test-docker-action | ||||
|             username_secret: AZURE_CLIENT_ID | ||||
|             password_secret: AZURE_CLIENT_SECRET | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Docker meta | ||||
|         id: meta | ||||
|         uses: docker/metadata-action@v4 | ||||
|         with: | ||||
|           images: ${{ matrix.slug }} | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           version: ${{ inputs.buildx-version || env.BUILDX_VERSION }} | ||||
|           driver-opts: | | ||||
|             image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }} | ||||
|       - | ||||
|         name: Login to Registry | ||||
|         if: github.event_name != 'pull_request' | ||||
|         uses: docker/login-action@v2 | ||||
|         with: | ||||
|           registry: ${{ matrix.registry }} | ||||
|           username: ${{ secrets[matrix.username_secret] }} | ||||
|           password: ${{ secrets[matrix.password_secret] }} | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/multi.Dockerfile | ||||
|           platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x | ||||
|           push: ${{ github.event_name != 'pull_request' }} | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|           cache-from: type=registry,ref=${{ matrix.slug }}:master | ||||
|           cache-to: type=inline | ||||
|       - | ||||
|         name: Inspect image | ||||
|         if: github.event_name != 'pull_request' | ||||
|         run: | | ||||
|           docker pull ${{ matrix.slug }}:${{ steps.meta.outputs.version }} | ||||
|           docker image inspect ${{ matrix.slug }}:${{ steps.meta.outputs.version }} | ||||
|       - | ||||
|         name: Check manifest | ||||
|         if: github.event_name != 'pull_request' | ||||
|         run: | | ||||
|           docker buildx imagetools inspect ${{ matrix.slug }}:${{ steps.meta.outputs.version }} --format '{{json .}}' | ||||
|             type: remote | ||||
|           - | ||||
|             name: Quay | ||||
|             registry: quay.io | ||||
|             slug: quay.io/docker_build_team/ghactiontest | ||||
|             username_secret: QUAY_USERNAME | ||||
|             password_secret: QUAY_TOKEN | ||||
|             type: remote | ||||
| #          - | ||||
| #            name: Artifactory | ||||
| #            registry: sforzando-build-team-local.jfrog.io | ||||
| #            slug: sforzando-build-team-local.jfrog.io/build-push-action-e2e | ||||
| #            username_secret: ARTIFACTORY_USERNAME | ||||
| #            password_secret: ARTIFACTORY_TOKEN | ||||
| #            type: remote | ||||
|           - | ||||
|             name: Harbor | ||||
|             id: harbor | ||||
|             type: local | ||||
|           - | ||||
|             name: Nexus | ||||
|             id: nexus | ||||
|             type: local | ||||
|     with: | ||||
|       id: ${{ matrix.id }} | ||||
|       type: ${{ matrix.type }} | ||||
|       name: ${{ matrix.name }} | ||||
|       registry: ${{ matrix.registry }} | ||||
|       slug: ${{ matrix.slug }} | ||||
|       username_secret: ${{ matrix.username_secret }} | ||||
|       password_secret: ${{ matrix.password_secret }} | ||||
|     secrets: inherit | ||||
|   | ||||
							
								
								
									
										74
									
								
								.github/workflows/example.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										74
									
								
								.github/workflows/example.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,74 +0,0 @@ | ||||
| # This workflow is provided just as an example and not for repo testing/verification | ||||
| name: example | ||||
|  | ||||
| on: | ||||
|   schedule: | ||||
|     - cron: '0 10 * * 0' | ||||
|   push: | ||||
|     branches: | ||||
|       - '**' | ||||
|     tags: | ||||
|       - 'v*.*.*' | ||||
|   pull_request: | ||||
|  | ||||
| env: | ||||
|   DOCKER_IMAGE: localhost:5000/name/app | ||||
|  | ||||
| jobs: | ||||
|   docker: | ||||
|     runs-on: ubuntu-latest | ||||
|     services: | ||||
|       registry: | ||||
|         image: registry:2 | ||||
|         ports: | ||||
|           - 5000:5000 | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Docker meta | ||||
|         id: meta | ||||
|         uses: docker/metadata-action@v4 | ||||
|         with: | ||||
|           images: ${{ env.DOCKER_IMAGE }} | ||||
|           tags: | | ||||
|             type=schedule | ||||
|             type=ref,event=branch | ||||
|             type=ref,event=pr | ||||
|             type=semver,pattern={{version}} | ||||
|             type=semver,pattern={{major}}.{{minor}} | ||||
|             type=semver,pattern={{major}} | ||||
|             type=sha | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         with: | ||||
|           driver-opts: network=host | ||||
|       - | ||||
|         name: Build and export to Docker client | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/Dockerfile | ||||
|           load: true | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|       - | ||||
|         name: Build and push to local registry | ||||
|         uses: ./ | ||||
|         with: | ||||
|           context: ./test | ||||
|           file: ./test/Dockerfile | ||||
|           push: ${{ github.event_name != 'pull_request' }} | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|       - | ||||
|         name: Inspect image | ||||
|         run: | | ||||
|           docker image inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }} | ||||
|       - | ||||
|         name: Check manifest | ||||
|         if: github.event_name != 'pull_request' | ||||
|         run: | | ||||
|           docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }} --format '{{json .}}' | ||||
							
								
								
									
										19
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,12 +1,15 @@ | ||||
| name: test | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{ github.workflow }}-${{ github.ref }} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - 'master' | ||||
|       - 'releases/v*' | ||||
|   pull_request: | ||||
|     branches: | ||||
|       - 'master' | ||||
|  | ||||
| jobs: | ||||
|   test: | ||||
| @@ -14,19 +17,15 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|       - | ||||
|         name: Validate | ||||
|         uses: docker/bake-action@v2 | ||||
|         with: | ||||
|           targets: validate | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Test | ||||
|         uses: docker/bake-action@v2 | ||||
|         uses: docker/bake-action@v4 | ||||
|         with: | ||||
|           targets: test | ||||
|       - | ||||
|         name: Upload coverage | ||||
|         uses: codecov/codecov-action@v3 | ||||
|         uses: codecov/codecov-action@v4 | ||||
|         with: | ||||
|           file: ./coverage/clover.xml | ||||
|           token: ${{ secrets.CODECOV_TOKEN }} | ||||
|   | ||||
							
								
								
									
										45
									
								
								.github/workflows/validate.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								.github/workflows/validate.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| name: validate | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{ github.workflow }}-${{ github.ref }} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - 'master' | ||||
|       - 'releases/v*' | ||||
|   pull_request: | ||||
|  | ||||
| jobs: | ||||
|   prepare: | ||||
|     runs-on: ubuntu-latest | ||||
|     outputs: | ||||
|       targets: ${{ steps.targets.outputs.matrix }} | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Targets matrix | ||||
|         id: targets | ||||
|         run: | | ||||
|           echo "matrix=$(docker buildx bake validate --print | jq -cr '.group.validate.targets')" >> $GITHUB_OUTPUT | ||||
|  | ||||
|   validate: | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: | ||||
|       - prepare | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         target: ${{ fromJson(needs.prepare.outputs.targets) }} | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Validate | ||||
|         uses: docker/bake-action@v4 | ||||
|         with: | ||||
|           targets: ${{ matrix.target }} | ||||
							
								
								
									
										72
									
								
								.github/workflows/virtual-env.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										72
									
								
								.github/workflows/virtual-env.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,72 +0,0 @@ | ||||
| name: virtual-env | ||||
|  | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|   schedule: | ||||
|     - cron: '0 10 * * *' | ||||
|   push: | ||||
|     branches: | ||||
|       - 'master' | ||||
|     paths: | ||||
|       - '.github/workflows/virtual-env.yml' | ||||
|   pull_request: | ||||
|     branches: | ||||
|       - 'master' | ||||
|     paths: | ||||
|       - '.github/workflows/virtual-env.yml' | ||||
|  | ||||
| jobs: | ||||
|   os: | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: | ||||
|           - ubuntu-latest | ||||
|           - ubuntu-22.04 | ||||
|           - ubuntu-20.04 | ||||
|           - ubuntu-18.04 | ||||
|     steps: | ||||
|       - | ||||
|         name: File system | ||||
|         run: df -ah | ||||
|       - | ||||
|         name: Mounts | ||||
|         run: mount | ||||
|       - | ||||
|         name: Node info | ||||
|         run: node -p process | ||||
|       - | ||||
|         name: NPM version | ||||
|         run: npm version | ||||
|       - | ||||
|         name: List install packages | ||||
|         run: apt list --installed | ||||
|       - | ||||
|         name: Docker daemon conf | ||||
|         run: | | ||||
|           cat /etc/docker/daemon.json | ||||
|       - | ||||
|         name: Docker info | ||||
|         run: docker info | ||||
|       - | ||||
|         name: Docker version | ||||
|         run: docker version | ||||
|       - | ||||
|         name: Cgroups | ||||
|         run: | | ||||
|           sudo apt-get install -y cgroup-tools | ||||
|           lscgroup | ||||
|       - | ||||
|         name: buildx version | ||||
|         run: docker buildx version | ||||
|       - | ||||
|         name: containerd version | ||||
|         run: containerd --version | ||||
|       - | ||||
|         name: Docker images | ||||
|         run: docker image ls | ||||
|       - | ||||
|         name: Dump context | ||||
|         if: always() | ||||
|         uses: crazy-max/ghaction-dump-context@v1 | ||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,10 +1,6 @@ | ||||
| node_modules | ||||
| lib | ||||
|  | ||||
| # Jetbrains | ||||
| /.idea | ||||
| /*.iml | ||||
|  | ||||
| # Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore | ||||
| # Logs | ||||
| logs | ||||
|   | ||||
							
								
								
									
										55
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								README.md
									
									
									
									
									
								
							| @@ -19,6 +19,18 @@ ___ | ||||
|   * [Git context](#git-context) | ||||
|   * [Path context](#path-context) | ||||
| * [Examples](#examples) | ||||
|   * [Multi-platform image](https://docs.docker.com/build/ci/github-actions/multi-platform/) | ||||
|   * [Secrets](https://docs.docker.com/build/ci/github-actions/secrets/) | ||||
|   * [Push to multi-registries](https://docs.docker.com/build/ci/github-actions/push-multi-registries/) | ||||
|   * [Manage tags and labels](https://docs.docker.com/build/ci/github-actions/manage-tags-labels/) | ||||
|   * [Cache management](https://docs.docker.com/build/ci/github-actions/cache/) | ||||
|   * [Export to Docker](https://docs.docker.com/build/ci/github-actions/export-docker/) | ||||
|   * [Test before push](https://docs.docker.com/build/ci/github-actions/test-before-push/) | ||||
|   * [Local registry](https://docs.docker.com/build/ci/github-actions/local-registry/) | ||||
|   * [Share built image between jobs](https://docs.docker.com/build/ci/github-actions/share-image-jobs/) | ||||
|   * [Named contexts](https://docs.docker.com/build/ci/github-actions/named-contexts/) | ||||
|   * [Copy image between registries](https://docs.docker.com/build/ci/github-actions/copy-image-registries/) | ||||
|   * [Update Docker Hub repo description](https://docs.docker.com/build/ci/github-actions/update-dockerhub-desc/) | ||||
| * [Customizing](#customizing) | ||||
|   * [inputs](#inputs) | ||||
|   * [outputs](#outputs) | ||||
| @@ -62,19 +74,19 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|       - | ||||
|         name: Login to Docker Hub | ||||
|         uses: docker/login-action@v2 | ||||
|         uses: docker/login-action@v3 | ||||
|         with: | ||||
|           username: ${{ secrets.DOCKERHUB_USERNAME }} | ||||
|           password: ${{ secrets.DOCKERHUB_TOKEN }} | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: docker/build-push-action@v3 | ||||
|         uses: docker/build-push-action@v5 | ||||
|         with: | ||||
|           push: true | ||||
|           tags: user/app:latest | ||||
| @@ -96,10 +108,10 @@ to the default Git context: | ||||
|         # Setting up Docker Buildx with docker-container driver is required | ||||
|         # at the moment to be able to use a subdirectory with Git context | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: docker/build-push-action@v3 | ||||
|         uses: docker/build-push-action@v5 | ||||
|         with: | ||||
|           context: "{{defaultContext}}:mysubdir" | ||||
|           push: true | ||||
| @@ -116,13 +128,13 @@ to the default Git context: | ||||
|  | ||||
| Building from the current repository automatically uses the [GitHub Token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication), | ||||
| so it does not need to be passed. If you want to authenticate against another | ||||
| private repository, you have to use a [secret](https://docs.docker.com/build/ci/github-actions/examples/#secrets) | ||||
| private repository, you have to use a [secret](https://docs.docker.com/build/ci/github-actions/secrets) | ||||
| named `GIT_AUTH_TOKEN` to be able to authenticate against it with Buildx: | ||||
|  | ||||
| ```yaml | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: docker/build-push-action@v3 | ||||
|         uses: docker/build-push-action@v5 | ||||
|         with: | ||||
|           push: true | ||||
|           tags: user/app:latest | ||||
| @@ -146,22 +158,22 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|       - | ||||
|         name: Login to Docker Hub | ||||
|         uses: docker/login-action@v2 | ||||
|         uses: docker/login-action@v3 | ||||
|         with: | ||||
|           username: ${{ secrets.DOCKERHUB_USERNAME }} | ||||
|           password: ${{ secrets.DOCKERHUB_TOKEN }} | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: docker/build-push-action@v3 | ||||
|         uses: docker/build-push-action@v5 | ||||
|         with: | ||||
|           context: . | ||||
|           push: true | ||||
| @@ -170,7 +182,18 @@ jobs: | ||||
|  | ||||
| ## Examples | ||||
|  | ||||
| See https://docs.docker.com/build/ci/github-actions/examples/. | ||||
| * [Multi-platform image](https://docs.docker.com/build/ci/github-actions/multi-platform/) | ||||
| * [Secrets](https://docs.docker.com/build/ci/github-actions/secrets/) | ||||
| * [Push to multi-registries](https://docs.docker.com/build/ci/github-actions/push-multi-registries/) | ||||
| * [Manage tags and labels](https://docs.docker.com/build/ci/github-actions/manage-tags-labels/) | ||||
| * [Cache management](https://docs.docker.com/build/ci/github-actions/cache/) | ||||
| * [Export to Docker](https://docs.docker.com/build/ci/github-actions/export-docker/) | ||||
| * [Test before push](https://docs.docker.com/build/ci/github-actions/test-before-push/) | ||||
| * [Local registry](https://docs.docker.com/build/ci/github-actions/local-registry/) | ||||
| * [Share built image between jobs](https://docs.docker.com/build/ci/github-actions/share-image-jobs/) | ||||
| * [Named contexts](https://docs.docker.com/build/ci/github-actions/named-contexts/) | ||||
| * [Copy image between registries](https://docs.docker.com/build/ci/github-actions/copy-image-registries/) | ||||
| * [Update Docker Hub repo description](https://docs.docker.com/build/ci/github-actions/update-dockerhub-desc/) | ||||
|  | ||||
| ## Customizing | ||||
|  | ||||
| @@ -194,6 +217,7 @@ Following inputs can be used as `step.with` keys | ||||
| |--------------------|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||||
| | `add-hosts`        | List/CSV    | List of [customs host-to-IP mapping](https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host) (e.g., `docker:10.180.0.1`)      | | ||||
| | `allow`            | List/CSV    | List of [extra privileged entitlement](https://docs.docker.com/engine/reference/commandline/buildx_build/#allow) (e.g., `network.host,security.insecure`)                         | | ||||
| | `annotations`      | List        | List of annotation to set to the image                                                                                                                                            | | ||||
| | `attests`          | List        | List of [attestation](https://docs.docker.com/build/attestations/) parameters (e.g., `type=sbom,generator=image`)                                                                 |  | ||||
| | `builder`          | String      | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action)                                                                                       | | ||||
| | `build-args`       | List        | List of [build-time variables](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-arg)                                                                      | | ||||
| @@ -215,6 +239,7 @@ Following inputs can be used as `step.with` keys | ||||
| | `push`             | Bool        | [Push](https://docs.docker.com/engine/reference/commandline/buildx_build/#push) is a shorthand for `--output=type=registry` (default `false`)                                     | | ||||
| | `sbom`             | Bool/String | Generate [SBOM](https://docs.docker.com/build/attestations/sbom/) attestation for the build (shorthand for `--attest=type=sbom`)                                                  | | ||||
| | `secrets`          | List        | List of [secrets](https://docs.docker.com/engine/reference/commandline/buildx_build/#secret) to expose to the build (e.g., `key=string`, `GIT_AUTH_TOKEN=mytoken`)                | | ||||
| | `secret-envs`      | List/CSV    | List of [secret env vars](https://docs.docker.com/engine/reference/commandline/buildx_build/#secret) to expose to the build (e.g., `key=envname`, `MY_SECRET=MY_ENV_VAR`)         | | ||||
| | `secret-files`     | List        | List of [secret files](https://docs.docker.com/engine/reference/commandline/buildx_build/#secret) to expose to the build (e.g., `key=filename`, `MY_SECRET=./secret.txt`)         | | ||||
| | `shm-size`         | String      | Size of [`/dev/shm`](https://docs.docker.com/engine/reference/commandline/buildx_build/#shm-size) (e.g., `2g`)                                                                    | | ||||
| | `ssh`              | List        | List of [SSH agent socket or keys](https://docs.docker.com/engine/reference/commandline/buildx_build/#ssh) to expose to the build                                                 | | ||||
| @@ -229,7 +254,7 @@ Following inputs can be used as `step.with` keys | ||||
|  | ||||
| ### outputs | ||||
|  | ||||
| Following outputs are available | ||||
| The following outputs are available: | ||||
|  | ||||
| | Name       | Type    | Description           | | ||||
| |------------|---------|-----------------------| | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|   * [BuildKit container logs](#buildkit-container-logs) | ||||
|   * [With containerd](#with-containerd) | ||||
| * [`repository name must be lowercase`](#repository-name-must-be-lowercase) | ||||
| * [Image not loaded](#image-not-loaded) | ||||
|  | ||||
| ## Cannot push to a registry | ||||
|  | ||||
| @@ -44,13 +45,13 @@ jobs: | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|         with: | ||||
|           buildkitd-flags: --debug | ||||
|       - | ||||
| @@ -58,7 +59,7 @@ jobs: | ||||
|         uses: crazy-max/ghaction-setup-containerd@v2 | ||||
|       - | ||||
|         name: Build Docker image | ||||
|         uses: docker/build-push-action@v3 | ||||
|         uses: docker/build-push-action@v5 | ||||
|         with: | ||||
|           context: . | ||||
|           platforms: linux/amd64,linux/arm64 | ||||
| @@ -111,7 +112,7 @@ to generate sanitized tags: | ||||
|     tags: latest | ||||
|  | ||||
| - name: Build and push | ||||
|   uses: docker/build-push-action@v3 | ||||
|   uses: docker/build-push-action@v5 | ||||
|   with: | ||||
|     context: . | ||||
|     push: true | ||||
| @@ -129,9 +130,35 @@ Or a dedicated step to sanitize the slug: | ||||
|     script: return 'ghcr.io/${{ github.repository }}'.toLowerCase() | ||||
|  | ||||
| - name: Build and push | ||||
|   uses: docker/build-push-action@v3 | ||||
|   uses: docker/build-push-action@v5 | ||||
|   with: | ||||
|     context: . | ||||
|     push: true | ||||
|     tags: ${{ steps.repo_slug.outputs.result }}:latest | ||||
| ``` | ||||
|  | ||||
| ## Image not loaded | ||||
|  | ||||
| Sometimes when your workflows are heavy consumers of disk storage, it can happen that build-push-action declares that the built image is loaded, but then not found in the following workflow steps. | ||||
|  | ||||
| - You can use the following solution as workaround, to free space on disk before building docker image using the following workflow step | ||||
|  | ||||
| ```yaml | ||||
|       # Free disk space | ||||
|       - name: Free Disk space | ||||
|         shell: bash | ||||
|         run: | | ||||
|           sudo rm -rf /usr/local/lib/android  # will release about 10 GB if you don't need Android | ||||
|           sudo rm -rf /usr/share/dotnet # will release about 20GB if you don't need .NET | ||||
| ``` | ||||
|  | ||||
| - Another workaround can be to call `docker/setup-buildx-action` with docker driver | ||||
|  | ||||
| ```yaml | ||||
| name: Set up Docker Buildx | ||||
| uses: docker/setup-buildx-action@v3 | ||||
| with: | ||||
|   driver: docker | ||||
| ``` | ||||
|  | ||||
| More details in the [related issue](https://github.com/docker/build-push-action/issues/321) | ||||
|   | ||||
							
								
								
									
										207
									
								
								__mocks__/@actions/github.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								__mocks__/@actions/github.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,207 @@ | ||||
| import {jest} from '@jest/globals'; | ||||
|  | ||||
| export const context = { | ||||
|   repo: { | ||||
|     owner: 'docker', | ||||
|     repo: 'build-push-action' | ||||
|   }, | ||||
|   ref: 'refs/heads/master', | ||||
|   runId: 123456789, | ||||
|   payload: { | ||||
|     after: '860c1904a1ce19322e91ac35af1ab07466440c37', | ||||
|     base_ref: null, | ||||
|     before: '5f3331d7f7044c18ca9f12c77d961c4d7cf3276a', | ||||
|     commits: [ | ||||
|       { | ||||
|         author: { | ||||
|           email: 'crazy-max@users.noreply.github.com', | ||||
|           name: 'CrazyMax', | ||||
|           username: 'crazy-max' | ||||
|         }, | ||||
|         committer: { | ||||
|           email: 'crazy-max@users.noreply.github.com', | ||||
|           name: 'CrazyMax', | ||||
|           username: 'crazy-max' | ||||
|         }, | ||||
|         distinct: true, | ||||
|         id: '860c1904a1ce19322e91ac35af1ab07466440c37', | ||||
|         message: 'hello dev', | ||||
|         timestamp: '2022-04-19T11:27:24+02:00', | ||||
|         tree_id: 'd2c60af597e863787d2d27f569e30495b0b92820', | ||||
|         url: 'https://github.com/docker/test-docker-action/commit/860c1904a1ce19322e91ac35af1ab07466440c37' | ||||
|       } | ||||
|     ], | ||||
|     compare: 'https://github.com/docker/test-docker-action/compare/5f3331d7f704...860c1904a1ce', | ||||
|     created: false, | ||||
|     deleted: false, | ||||
|     forced: false, | ||||
|     head_commit: { | ||||
|       author: { | ||||
|         email: 'crazy-max@users.noreply.github.com', | ||||
|         name: 'CrazyMax', | ||||
|         username: 'crazy-max' | ||||
|       }, | ||||
|       committer: { | ||||
|         email: 'crazy-max@users.noreply.github.com', | ||||
|         name: 'CrazyMax', | ||||
|         username: 'crazy-max' | ||||
|       }, | ||||
|       distinct: true, | ||||
|       id: '860c1904a1ce19322e91ac35af1ab07466440c37', | ||||
|       message: 'hello dev', | ||||
|       timestamp: '2022-04-19T11:27:24+02:00', | ||||
|       tree_id: 'd2c60af597e863787d2d27f569e30495b0b92820', | ||||
|       url: 'https://github.com/docker/test-docker-action/commit/860c1904a1ce19322e91ac35af1ab07466440c37' | ||||
|     }, | ||||
|     organization: { | ||||
|       avatar_url: 'https://avatars.githubusercontent.com/u/5429470?v=4', | ||||
|       description: 'Docker helps developers bring their ideas to life by conquering the complexity of app development.', | ||||
|       events_url: 'https://api.github.com/orgs/docker/events', | ||||
|       hooks_url: 'https://api.github.com/orgs/docker/hooks', | ||||
|       id: 5429470, | ||||
|       issues_url: 'https://api.github.com/orgs/docker/issues', | ||||
|       login: 'docker', | ||||
|       members_url: 'https://api.github.com/orgs/docker/members{/member}', | ||||
|       node_id: 'MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=', | ||||
|       public_members_url: 'https://api.github.com/orgs/docker/public_members{/member}', | ||||
|       repos_url: 'https://api.github.com/orgs/docker/repos', | ||||
|       url: 'https://api.github.com/orgs/docker' | ||||
|     }, | ||||
|     pusher: { | ||||
|       email: 'github@crazymax.dev', | ||||
|       name: 'crazy-max' | ||||
|     }, | ||||
|     ref: 'refs/heads/dev', | ||||
|     repository: { | ||||
|       allow_forking: true, | ||||
|       archive_url: 'https://api.github.com/repos/docker/test-docker-action/{archive_format}{/ref}', | ||||
|       archived: false, | ||||
|       assignees_url: 'https://api.github.com/repos/docker/test-docker-action/assignees{/user}', | ||||
|       blobs_url: 'https://api.github.com/repos/docker/test-docker-action/git/blobs{/sha}', | ||||
|       branches_url: 'https://api.github.com/repos/docker/test-docker-action/branches{/branch}', | ||||
|       clone_url: 'https://github.com/docker/test-docker-action.git', | ||||
|       collaborators_url: 'https://api.github.com/repos/docker/test-docker-action/collaborators{/collaborator}', | ||||
|       comments_url: 'https://api.github.com/repos/docker/test-docker-action/comments{/number}', | ||||
|       commits_url: 'https://api.github.com/repos/docker/test-docker-action/commits{/sha}', | ||||
|       compare_url: 'https://api.github.com/repos/docker/test-docker-action/compare/{base}...{head}', | ||||
|       contents_url: 'https://api.github.com/repos/docker/test-docker-action/contents/{+path}', | ||||
|       contributors_url: 'https://api.github.com/repos/docker/test-docker-action/contributors', | ||||
|       created_at: 1596792180, | ||||
|       default_branch: 'master', | ||||
|       deployments_url: 'https://api.github.com/repos/docker/test-docker-action/deployments', | ||||
|       description: 'Test "Docker" Actions', | ||||
|       disabled: false, | ||||
|       downloads_url: 'https://api.github.com/repos/docker/test-docker-action/downloads', | ||||
|       events_url: 'https://api.github.com/repos/docker/test-docker-action/events', | ||||
|       fork: false, | ||||
|       forks: 1, | ||||
|       forks_count: 1, | ||||
|       forks_url: 'https://api.github.com/repos/docker/test-docker-action/forks', | ||||
|       full_name: 'docker/test-docker-action', | ||||
|       git_commits_url: 'https://api.github.com/repos/docker/test-docker-action/git/commits{/sha}', | ||||
|       git_refs_url: 'https://api.github.com/repos/docker/test-docker-action/git/refs{/sha}', | ||||
|       git_tags_url: 'https://api.github.com/repos/docker/test-docker-action/git/tags{/sha}', | ||||
|       git_url: 'git://github.com/docker/test-docker-action.git', | ||||
|       has_downloads: true, | ||||
|       has_issues: true, | ||||
|       has_pages: false, | ||||
|       has_projects: true, | ||||
|       has_wiki: true, | ||||
|       homepage: '', | ||||
|       hooks_url: 'https://api.github.com/repos/docker/test-docker-action/hooks', | ||||
|       html_url: 'https://github.com/docker/test-docker-action', | ||||
|       id: 285789493, | ||||
|       is_template: false, | ||||
|       issue_comment_url: 'https://api.github.com/repos/docker/test-docker-action/issues/comments{/number}', | ||||
|       issue_events_url: 'https://api.github.com/repos/docker/test-docker-action/issues/events{/number}', | ||||
|       issues_url: 'https://api.github.com/repos/docker/test-docker-action/issues{/number}', | ||||
|       keys_url: 'https://api.github.com/repos/docker/test-docker-action/keys{/key_id}', | ||||
|       labels_url: 'https://api.github.com/repos/docker/test-docker-action/labels{/name}', | ||||
|       language: 'JavaScript', | ||||
|       languages_url: 'https://api.github.com/repos/docker/test-docker-action/languages', | ||||
|       license: { | ||||
|         key: 'mit', | ||||
|         name: 'MIT License', | ||||
|         node_id: 'MDc6TGljZW5zZTEz', | ||||
|         spdx_id: 'MIT', | ||||
|         url: 'https://api.github.com/licenses/mit' | ||||
|       }, | ||||
|       master_branch: 'master', | ||||
|       merges_url: 'https://api.github.com/repos/docker/test-docker-action/merges', | ||||
|       milestones_url: 'https://api.github.com/repos/docker/test-docker-action/milestones{/number}', | ||||
|       mirror_url: null, | ||||
|       name: 'test-docker-action', | ||||
|       node_id: 'MDEwOlJlcG9zaXRvcnkyODU3ODk0OTM=', | ||||
|       notifications_url: 'https://api.github.com/repos/docker/test-docker-action/notifications{?since,all,participating}', | ||||
|       open_issues: 6, | ||||
|       open_issues_count: 6, | ||||
|       organization: 'docker', | ||||
|       owner: { | ||||
|         avatar_url: 'https://avatars.githubusercontent.com/u/5429470?v=4', | ||||
|         email: 'info@docker.com', | ||||
|         events_url: 'https://api.github.com/users/docker/events{/privacy}', | ||||
|         followers_url: 'https://api.github.com/users/docker/followers', | ||||
|         following_url: 'https://api.github.com/users/docker/following{/other_user}', | ||||
|         gists_url: 'https://api.github.com/users/docker/gists{/gist_id}', | ||||
|         gravatar_id: '', | ||||
|         html_url: 'https://github.com/docker', | ||||
|         id: 5429470, | ||||
|         login: 'docker', | ||||
|         name: 'docker', | ||||
|         node_id: 'MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=', | ||||
|         organizations_url: 'https://api.github.com/users/docker/orgs', | ||||
|         received_events_url: 'https://api.github.com/users/docker/received_events', | ||||
|         repos_url: 'https://api.github.com/users/docker/repos', | ||||
|         site_admin: false, | ||||
|         starred_url: 'https://api.github.com/users/docker/starred{/owner}{/repo}', | ||||
|         subscriptions_url: 'https://api.github.com/users/docker/subscriptions', | ||||
|         type: 'Organization', | ||||
|         url: 'https://api.github.com/users/docker' | ||||
|       }, | ||||
|       private: true, | ||||
|       pulls_url: 'https://api.github.com/repos/docker/test-docker-action/pulls{/number}', | ||||
|       pushed_at: 1650360446, | ||||
|       releases_url: 'https://api.github.com/repos/docker/test-docker-action/releases{/id}', | ||||
|       size: 796, | ||||
|       ssh_url: 'git@github.com:docker/test-docker-action.git', | ||||
|       stargazers: 0, | ||||
|       stargazers_count: 0, | ||||
|       stargazers_url: 'https://api.github.com/repos/docker/test-docker-action/stargazers', | ||||
|       statuses_url: 'https://api.github.com/repos/docker/test-docker-action/statuses/{sha}', | ||||
|       subscribers_url: 'https://api.github.com/repos/docker/test-docker-action/subscribers', | ||||
|       subscription_url: 'https://api.github.com/repos/docker/test-docker-action/subscription', | ||||
|       svn_url: 'https://github.com/docker/test-docker-action', | ||||
|       tags_url: 'https://api.github.com/repos/docker/test-docker-action/tags', | ||||
|       teams_url: 'https://api.github.com/repos/docker/test-docker-action/teams', | ||||
|       topics: [], | ||||
|       trees_url: 'https://api.github.com/repos/docker/test-docker-action/git/trees{/sha}', | ||||
|       updated_at: '2022-04-19T09:05:09Z', | ||||
|       url: 'https://github.com/docker/test-docker-action', | ||||
|       visibility: 'private', | ||||
|       watchers: 0, | ||||
|       watchers_count: 0 | ||||
|     }, | ||||
|     sender: { | ||||
|       avatar_url: 'https://avatars.githubusercontent.com/u/1951866?v=4', | ||||
|       events_url: 'https://api.github.com/users/crazy-max/events{/privacy}', | ||||
|       followers_url: 'https://api.github.com/users/crazy-max/followers', | ||||
|       following_url: 'https://api.github.com/users/crazy-max/following{/other_user}', | ||||
|       gists_url: 'https://api.github.com/users/crazy-max/gists{/gist_id}', | ||||
|       gravatar_id: '', | ||||
|       html_url: 'https://github.com/crazy-max', | ||||
|       id: 1951866, | ||||
|       login: 'crazy-max', | ||||
|       node_id: 'MDQ6VXNlcjE5NTE4NjY=', | ||||
|       organizations_url: 'https://api.github.com/users/crazy-max/orgs', | ||||
|       received_events_url: 'https://api.github.com/users/crazy-max/received_events', | ||||
|       repos_url: 'https://api.github.com/users/crazy-max/repos', | ||||
|       site_admin: false, | ||||
|       starred_url: 'https://api.github.com/users/crazy-max/starred{/owner}{/repo}', | ||||
|       subscriptions_url: 'https://api.github.com/users/crazy-max/subscriptions', | ||||
|       type: 'User', | ||||
|       url: 'https://api.github.com/users/crazy-max' | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| export const getOctokit = jest.fn(); | ||||
| @@ -1,146 +0,0 @@ | ||||
| import {describe, expect, it, jest, test} from '@jest/globals'; | ||||
| import * as fs from 'fs'; | ||||
| import * as path from 'path'; | ||||
| import * as semver from 'semver'; | ||||
| import * as exec from '@actions/exec'; | ||||
| import * as buildx from '../src/buildx'; | ||||
| import * as context from '../src/context'; | ||||
|  | ||||
| const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); | ||||
| const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9'; | ||||
| const metadata = `{ | ||||
|   "containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd", | ||||
|   "containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c" | ||||
| }`; | ||||
|  | ||||
| jest.spyOn(context, 'tmpDir').mockImplementation((): string => { | ||||
|   const tmpDir = path.join('/tmp/.docker-build-push-jest').split(path.sep).join(path.posix.sep); | ||||
|   if (!fs.existsSync(tmpDir)) { | ||||
|     fs.mkdirSync(tmpDir, {recursive: true}); | ||||
|   } | ||||
|   return tmpDir; | ||||
| }); | ||||
|  | ||||
| jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => { | ||||
|   return tmpNameSync; | ||||
| }); | ||||
|  | ||||
| describe('getImageID', () => { | ||||
|   it('matches', async () => { | ||||
|     const imageIDFile = await buildx.getImageIDFile(); | ||||
|     await fs.writeFileSync(imageIDFile, imageID); | ||||
|     const expected = await buildx.getImageID(); | ||||
|     expect(expected).toEqual(imageID); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('getMetadata', () => { | ||||
|   it('matches', async () => { | ||||
|     const metadataFile = await buildx.getMetadataFile(); | ||||
|     await fs.writeFileSync(metadataFile, metadata); | ||||
|     const expected = await buildx.getMetadata(); | ||||
|     expect(expected).toEqual(metadata); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('getDigest', () => { | ||||
|   it('matches', async () => { | ||||
|     const metadataFile = await buildx.getMetadataFile(); | ||||
|     await fs.writeFileSync(metadataFile, metadata); | ||||
|     const expected = await buildx.getDigest(metadata); | ||||
|     expect(expected).toEqual('sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c'); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('isLocalOrTarExporter', () => { | ||||
|   test.each([ | ||||
|     [['type=registry,ref=user/app'], false], | ||||
|     [['type=docker'], false], | ||||
|     [['type=local,dest=./release-out'], true], | ||||
|     [['type=tar,dest=/tmp/image.tar'], true], | ||||
|     [['type=docker', 'type=tar,dest=/tmp/image.tar'], true], | ||||
|     [['"type=tar","dest=/tmp/image.tar"'], true], | ||||
|     [['" type= local" , dest=./release-out'], true], | ||||
|     [['.'], true] | ||||
|   ])('given %p returns %p', async (outputs: Array<string>, expected: boolean) => { | ||||
|     expect(buildx.isLocalOrTarExporter(outputs)).toEqual(expected); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('isAvailable', () => { | ||||
|   const execSpy = jest.spyOn(exec, 'getExecOutput'); | ||||
|   buildx.isAvailable(); | ||||
|  | ||||
|   // eslint-disable-next-line jest/no-standalone-expect | ||||
|   expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], { | ||||
|     silent: true, | ||||
|     ignoreReturnCode: true | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('isAvailable standalone', () => { | ||||
|   const execSpy = jest.spyOn(exec, 'getExecOutput'); | ||||
|   buildx.isAvailable(true); | ||||
|  | ||||
|   // eslint-disable-next-line jest/no-standalone-expect | ||||
|   expect(execSpy).toHaveBeenCalledWith(`buildx`, [], { | ||||
|     silent: true, | ||||
|     ignoreReturnCode: true | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('getVersion', () => { | ||||
|   it('valid', async () => { | ||||
|     const version = await buildx.getVersion(); | ||||
|     expect(semver.valid(version)).not.toBeNull(); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('parseVersion', () => { | ||||
|   test.each([ | ||||
|     ['github.com/docker/buildx 0.4.1+azure bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'], | ||||
|     ['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'], | ||||
|     ['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'], | ||||
|     ['github.com/docker/buildx f117971 f11797113e5a9b86bd976329c5dbb8a8bfdfadfa', 'f117971'] | ||||
|   ])('given %p', async (stdout, expected) => { | ||||
|     expect(buildx.parseVersion(stdout)).toEqual(expected); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('satisfies', () => { | ||||
|   test.each([ | ||||
|     ['0.4.1', '>=0.3.2', true], | ||||
|     ['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false], | ||||
|     ['f117971', '>0.6.0', true] | ||||
|   ])('given %p', async (version, range, expected) => { | ||||
|     expect(buildx.satisfies(version, range)).toBe(expected); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('getSecret', () => { | ||||
|   test.each([ | ||||
|     ['A_SECRET=abcdef0123456789', false, 'A_SECRET', 'abcdef0123456789', false], | ||||
|     ['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', false, 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', false], | ||||
|     ['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', false, 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', false], | ||||
|     ['aaaaaaaa', false, '', '', true], | ||||
|     ['aaaaaaaa=', false, '', '', true], | ||||
|     ['=bbbbbbb', false, '', '', true], | ||||
|     [`foo=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`, true, 'foo', 'bar', false], | ||||
|     [`notfound=secret`, true, '', '', true] | ||||
|   ])('given %p key and %p secret', async (kvp, file, exKey, exValue, invalid) => { | ||||
|     try { | ||||
|       let secret: string; | ||||
|       if (file) { | ||||
|         secret = await buildx.getSecretFile(kvp); | ||||
|       } else { | ||||
|         secret = await buildx.getSecretString(kvp); | ||||
|       } | ||||
|       expect(true).toBe(!invalid); | ||||
|       expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`); | ||||
|       expect(fs.readFileSync(tmpNameSync, 'utf-8')).toEqual(exValue); | ||||
|     } catch (err) { | ||||
|       // eslint-disable-next-line jest/no-conditional-expect | ||||
|       expect(true).toBe(invalid); | ||||
|     } | ||||
|   }); | ||||
| }); | ||||
| @@ -1,134 +1,58 @@ | ||||
| import {beforeEach, describe, expect, it, jest, test} from '@jest/globals'; | ||||
| import {beforeEach, describe, expect, jest, test} from '@jest/globals'; | ||||
| import * as fs from 'fs'; | ||||
| import * as path from 'path'; | ||||
| import {Builder} from '@docker/actions-toolkit/lib/buildx/builder'; | ||||
| import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx'; | ||||
| import {Context} from '@docker/actions-toolkit/lib/context'; | ||||
| import {Docker} from '@docker/actions-toolkit/lib/docker/docker'; | ||||
| import {GitHub} from '@docker/actions-toolkit/lib/github'; | ||||
| import {Toolkit} from '@docker/actions-toolkit/lib/toolkit'; | ||||
| import {BuilderInfo} from '@docker/actions-toolkit/lib/types/builder'; | ||||
| import {GitHubRepo} from '@docker/actions-toolkit/lib/types/github'; | ||||
|  | ||||
| import * as buildx from '../src/buildx'; | ||||
| import * as context from '../src/context'; | ||||
|  | ||||
| const pgp = `-----BEGIN PGP PRIVATE KEY BLOCK----- | ||||
| const tmpDir = path.join('/tmp', '.docker-build-push-jest'); | ||||
| const tmpName = path.join(tmpDir, '.tmpname-jest'); | ||||
|  | ||||
| lQdGBF6tzaABEACjFbX7PFEG6vDPN2MPyxYW7/3o/sonORj4HXUFjFxxJxktJ3x3 | ||||
| N1ayHPJ1lqIeoiY7jVbq0ZdEVGkd3YsKG9ZMdZkzGzY6PQPC/+M8OnzOiOPwUdWc | ||||
| +Tdhh115LvVz0MMKYiab6Sn9cgxj9On3LCQKpjvMDpPo9Ttf6v2GQIw8h2ACvdzQ | ||||
| 71LtIELS/I+dLbfZiwpUu2fhQT13EJkEnYMOYwM5jNUd66P9itUc7MrOWjkicrKP | ||||
| oF1dQaCM+tuKuxvD8WLdiwU5x60NoGkJHHUehKQXl2dVzjpqEqHKEBJt9tfJ9lpE | ||||
| YIisgwB8o3pes0fgCehjW2zI95/o9+ayJ6nl4g5+mSvWRXEu66h71nwM0Yuvquk8 | ||||
| 3me7qhYfDrDdCwcxS5BS1hwakTgUQLD99FZjbx1j8sq96I65O0GRdyU2PR8KIjwu | ||||
| JrkTH4ZlKxK3FQghUhFoA5GkiDb+eClmRMSni5qg+81T4XChmUkEprA3eWCHL+Ma | ||||
| xRNNxLS+r6hH9HG5JBxpV3iaTI9HHpnQKhEeaLXqsUTDZliN9hP7Ywo8bpUB8j2d | ||||
| oWYwDV4dPyMKr6Fb8RDCh2q5gJGbVp8w/NmmBTeL+IP2fFggJkRfyumv3Ul7x66L | ||||
| tBFQ4rYo4JUUrGweSTneG6REIgxH66hIrNl6Vo/D1ZyknTe1dMOu/BTkkQARAQAB | ||||
| /gcDAqra8KO+h3bfyu90vxTL1ro4x/x9il7VBcWlIR4cBP7Imgxv+T4hwPIu8P1x | ||||
| lOlxLNWegFOV0idoTy1o3VLLBev/F+IlspX4A+2XEIddR6nZnKFi0Lv2L4TKgE9E | ||||
| VJJTszmviDIRLMLN9dWzDfA8hj5tR5Inot92CHRF414AS22JHvlhbFSLQnjqsN+C | ||||
| n1cQpNOJhkxsSfZsxjnFa/70y/u8v0o8mzyLZmk9HpzRHGzoz8IfpLp8OTqBR9u6 | ||||
| zzoKLy16zZO55OKbj7h8uVZvDUq9l8iDICpqWMdZqBJIl56MBexYKgYxh3YO/8v2 | ||||
| oXli+8Xuaq5QLiCN3yT7IbKoYzplnFfaJwFiMh7R1iPLXaYAZ0qdRijlbtseTK1m | ||||
| oHNkwUbxVzjkh4LfE8UpmMwZn5ZjWni3230SoiXuKy0OHkGvwGvWWAL1mEuoYuUI | ||||
| mFMcH5MnixP8oQYZKDj2IR/yEeOpdU6B/tr3Tk1NidLf7pUMqG7Ff1NU6dAUeBpa | ||||
| 9xahITMjHvrhgMISY4IYZep5cEnVw8lQTpUJtW/ePMzrFhu3sA7oNdj9joW/VMfz | ||||
| H7MHwwavtICsYqoqV3lnjX4EC9dW6o8PTUg2u956dmtK7KAyUK/+w2aLNGT28ChN | ||||
| jhRYHvHzB9Kw5asqI/lTM49eqslBqYQMTTjdBphkYuSZQzNMf291j/ZmoLhD1A1a | ||||
| S8tUnNygKV4D1cJYgSXfzhFoU8ib/0SPo+KqQ+CzGS+wxXg6WNBA6wepTjpnVVx3 | ||||
| 4JADP8IJcDC3P0iwAreWjSy15F1cvemFFB0SLNUkyZGzsxtKzbM1+8khl68+eazC | ||||
| LzRj0rxfIF5znWjX1QFhKxCk6eF0IWDY0+b3DBkmChME9YDXJ3TthcqA7JgcX4JI | ||||
| M4/wdqhgerJYOmj+i2Q0M+Bu02icOJYMwTMMsDVl7XGHkaCuRgZ54eZAUH7JFwUm | ||||
| 1Ct3tcaqiTMmz0ngHVqBTauzgqKDvzwdVqdfg05H364nJMay/3omR6GayIb5CwSo | ||||
| xdNVwG3myPPradT9MP09mDr4ys2zcnQmCkvTVBF6cMZ1Eh6PQQ8CyQWv0zkaBnqj | ||||
| JrM1hRpgW4ZlRosSIjCaaJjolN5QDcXBM9TbW9ww+ZYstazN2bV1ZQ7BEjlHQPa1 | ||||
| BhzMsvqkbETHsIpDNF52gZKn3Q9eIX05BeadzpHUb5/XOheIHVIdhSaTlgl/qQW5 | ||||
| hQgPGSzSV6KhXEY7aevTdvOgq++WiELkjfz2f2lQFesTjFoQWEvxVDUmLxHtEhaN | ||||
| DOuh4H3mX5Opn3pLQmqWVhJTbFdx+g5qQd0NCW4mDaTFWTRLFLZQsSJxDSeg9xrY | ||||
| gmaii8NhMZRwquADW+6iU6KfraBhngi7HRz4TfqPr9ma/KUY464cqim1fnwXejyx | ||||
| jsb5YHR9R66i+F6P/ysF5w+QuVdDt1fnf9GLay0r6qxpA8ft2vGPcDs4806Huj+7 | ||||
| Aq5VeJaNkCuh3GR3xVnCFAz/7AtkO6xKuZm8B3q904UuMdSmkhWbaobIuF/B2B6S | ||||
| eawIXQHEOplK3ic26d8Ckf4gbjeORfELcMAEi5nGXpTThCdmxQApCLxAYYnTfQT1 | ||||
| xhlDwT9xPEabo98mIwJJsAU5VsTDYW+qfo4qIx8gYoSKc9Xu3yVh3n+9k43Gcm5V | ||||
| 9lvK1slijf+TzODZt/jsmkF8mPjXyP5KOI+xQp/m4PxW3pp57YrYj/Rnwga+8DKX | ||||
| jMsW7mLAAZ/e+PY6z/s3x1Krfk+Bb5Ph4mI0zjw5weQdtyEToRgveda0GEpvZSBU | ||||
| ZXN0ZXIgPGpvZUBmb28uYmFyPokCNgQQAQgAIAUCXq3NoAYLCQcIAwIEFQgKAgQW | ||||
| AgEAAhkBAhsDAh4BAAoJEH2FHrctc72gxtQP/AulaClIcn/kDt43mhYnyLglPfbo | ||||
| AqPlU26chXolBg0Wo0frFY3aIs5SrcWEf8aR4XLwCFGyi3vya0CUxjghN5tZBYqo | ||||
| vswbT00zP3ohxxlJFCRRR9bc7OZXCgTddtfVf6EKrUAzIkbWyAhaJnwJy/1UGpSw | ||||
| SEO/KpastrVKf3sv1wqOeFQ4DFyjaNda+xv3dVWS8db7KogqJiPFZXrQK3FKVIxS | ||||
| fxRSmKaYN7//d+xwVAEY++RrnL/o8B2kV6N68cCpQWJELyYnJzis9LBcWd/3wiYh | ||||
| efTyY+ePKUjcB+kEZnyJfLc7C2hll2e7UJ0fxv+k8vHReRhrNWmGRXsjNRxiw3U0 | ||||
| hfvxD/C8nyqAbeTHp4XDX78Tc3XCysAqIYboIL+RyewDMjjLj5vzUYAdUdtyNaD7 | ||||
| C6M2R6pN1GAt52CJmC/Z6F7W7GFGoYOdEkVdMQDsjCwScyEUNlGj9Zagw5M2EgSe | ||||
| 6gaHgMgTzsMzCc4W6WV5RcS55cfDNOXtxPsMJTt4FmXrjl11prBzpMfpU5a9zxDZ | ||||
| oi54ZZ8VPE6jsT4Lzw3sni3c83wm28ArM20AzZ1vh7fk3Sfd0u4Yaz7s9JlEm5+D | ||||
| 34tEyli28+QjCQc18EfQUiJqiYEJRxJXJ3esvMHfYi45pV/Eh5DgRW1305fUJV/6 | ||||
| +rGpg0NejsHoZdZPnQdGBF6tzaABEAC4mVXTkVk6Kdfa4r5zlzsoIrR27laUlMkb | ||||
| OBMt+aokqS+BEbmTnMg6xIAmcUT5uvGAc8S/WhrPoYfc15fTUyHIz8ZbDoAg0LO6 | ||||
| 0Io4VkAvNJNEnsSV9VdLBh/XYlc4K49JqKyWTL4/FJFAGbsmHY3b+QU90AS6FYRv | ||||
| KeBAoiyebrjx0vmzb8E8h3xthVLN+AfMlR1ickY62zvnpkbncSMY/skur1D2KfbF | ||||
| 3sFprty2pEtjFcyB5+18l2IyyHGOlEUw1PZdOAV4/Myh1EZRgYBPs80lYTJALCVF | ||||
| IdOakH33WJCImtNZB0AbDTABG+JtMjQGscOa0qzf1Y/7tlhgCrynBBdaIJTx95TD | ||||
| 21BUHcHOu5yTIS6Ulysxfkv611+BiOKHgdq7DVGP78VuzA7bCjlP1+vHqIt3cnIa | ||||
| t2tEyuZ/XF4uc3/i4g0uP9r7AmtET7Z6SKECWjpVv+UEgLx5Cv+ql+LSKYQMvU9a | ||||
| i3B1F9fatn3FSLVYrL4aRxu4TSw9POb0/lgDNmN3lGQOsjGCZPibkHjgPEVxKuiq | ||||
| 9Oi38/VTQ0ZKAmHwBTq1WTZIrPrCW0/YMQ6yIJZulwQ9Yx1cgzYzEfg04fPXlXMi | ||||
| vkvNpKbYIICzqj0/DVztz9wgpW6mnd0A2VX2dqbMM0fJUCHA6pj8AvXY4R+9Q4rj | ||||
| eWRK9ycInQARAQAB/gcDApjt7biRO0PEyrrAiUwDMsJL4/CVMu11qUWEPjKe2Grh | ||||
| ZTW3N+m3neKPRULu+LUtndUcEdVWUCoDzAJ7MwihZtV5vKST/5Scd2inonOaJqoA | ||||
| nS3wnEMN/Sc93HAZiZnFx3NKjQVNCwbuEs45mXkkcjLm2iadrTL8fL4acsu5IsvD | ||||
| LbDwVOPeNnHKl6Hr20e39fK0FuJEyH49JM6U3B1/8385sJB8+E24+hvSF81aMddh | ||||
| Ne4Bc3ZYiYaKxe1quPNKC0CQhAZiT7LsMfkInXr0hY1I+kISNXEJ1dPYOEWiv0Ze | ||||
| jD5Pupn34okKNEeBCx+dK8BmUCi6Jgs7McUA7hN0D/YUS++5fuR55UQq2j8Ui0tS | ||||
| P8GDr86upH3PgEL0STh9fYfJ7TesxurwonWjlmmT62Myl4Pr+RmpS6PXOnhtcADm | ||||
| eGLpzhTveFj4JBLMpyYHgBTqcs12zfprATOpsI/89kmQoGCZpG6+AbfSHqNNPdy2 | ||||
| eqUCBhOZlIIda1z/cexmU3f/gBqyflFf8fkvmlO4AvI8aMH3OpgHdWnzh+AB51xj | ||||
| kmdD/oWel9v7Dz4HoZUfwFaLZ0fE3P9voD8e+sCwqQwVqRY4L/BOYPD5noVOKgOj | ||||
| ABNKu5uKrobj6rFUi6DTUCjFGcmoF1Sc06xFNaagUNggRbmlC/dz22RWdDUYv5ra | ||||
| N6TxIDkGC0cK6ujyK0nes3DN0aHjgwWuMXDYkN3UckiebI4Cv/eF9jvUKOSiIcy1 | ||||
| RtxdazZS4dYg2LBMeJKVkPi5elsNyw2812nEY3du/nEkQYXfYgWOF27OR+g4Y9Yw | ||||
| 1BiqJ1TTjbQnd/khOCrrbzDH1mw00+1XVsT6wjObuYqqxPPS87UrqmMf6OdoYfPm | ||||
| zEOnNLBnsJ5VQM3A3pcT40RfdBrZRO8LjGhzKTreyq3C+jz0RLa5HNE8GgOhGyck | ||||
| ME4h+RhXlE8KGM+tTo6PA1NJSrEt+8kZzxjP4rIEn0aVthCkNXK12inuXtnHm0ao | ||||
| iLUlQOsfPFEnzl0TUPd7+z7j/wB+XiKU/AyEUuB0mvdxdKtqXvajahOyhLjzHQhz | ||||
| ZnNlgANGtiqcSoJmkJ8yAvhrtQX51fQLftxbArRW1RYk/5l+Gy3azR+gUC17M6JN | ||||
| jrUYxn0zlAxDGFH7gACHUONwVekcuEffHzgu2lk7MyO1Y+lPnwabqjG0eWWHuU00 | ||||
| hskJlXyhj7DeR12bwjYkyyjG62GvOH02g3OMvUgNGH+K321Dz539csCh/xwtg7Wt | ||||
| U3YAphU7htQ1dPDfk1IRs7DQo2L+ZTE57vmL5m0l6fTataEWBPUXkygfQFUJOM6Q | ||||
| yY76UEZww1OSDujNeY171NSTzXCVkUeAdAMXgjaHXWLK2QUQUoXbYX/Kr7Vvt9Fu | ||||
| Jh6eGjjp7dSjQ9+DW8CAB8vxd93gsQQGWYjmGu8khkEmx6OdZhmSbDbe915LQTb9 | ||||
| sPhk2s5/Szsvr5W2JJ2321JI6KXBJMZvPC5jEBWmRzOYkRd2vloft+CSMfXF+Zfd | ||||
| nYtc6R3dvb9vcjo+a9wFtfcoDsO0MaPSM+9GB25MamdatmGX6iLOy9Re1UABwUi/ | ||||
| VhTWNkP5uzqx0sDwHEIa2rYOwxpIZDwwjM3oOASCW1DDBQ0BI9KNjfIeL3ubx2mS | ||||
| 2x8hFU9qSK4umoDNbzOqGPSlkdbiPcNjF2ZcSN1qQZiYdwLL5dw6APNyBVjxTN1J | ||||
| gkCdJ/HwAY+r93Lbl5g8gz8d0vJEyfn//34sn9u+toSTw55GcG9Ks1kSKIeDNh0h | ||||
| MiPm3HmJAh8EGAEIAAkFAl6tzaACGwwACgkQfYUety1zvaBV9hAAgliX36pXJ59g | ||||
| 3I9/4R68e/fGg0FMM6D+01yCeiKApOYRrJ0cYKn7ITDYmHhlGGpBAie90UsqX12h | ||||
| hdLP7LoQx7sjTyzQt6JmpA8krIwi2ON7FKBkdYb8IYx4mE/5vKnYT4/SFnwTmnZY | ||||
| +m+NzK2U/qmhq8JyO8gozdAKJUcgz49IVv2Ij0tQ4qaPbyPwQxIDyKnT758nJhB1 | ||||
| jTqo+oWtER8q3okzIlqcArqn5rDaNJx+DRYL4E/IddyHQAiUWUka8usIUqeW5reu | ||||
| zoPUE2CCfOJSGArkqHQQqMx0WEzjQTwAPaHrQbera4SbiV/o4CLCV/u5p1Qnig+Q | ||||
| iUsakmlD299t//125LIQEa5qzd9hRC7u1uJS7VdW8eGIEcZ0/XT/sr+z23z0kpZH | ||||
| D3dXPX0BwM4IP9xu31CNg10x0rKwjbxy8VaskFEelpqpu+gpAnxqMd1evpeUHcOd | ||||
| r5RgPgkNFfba9Nbxf7uEX+HOmsOM+kdtSmdGIvsBZjVnW31nnoDMp49jG4OynjrH | ||||
| cRuoM9sxdr6UDqb22CZ3/e0YN4UaZM3YDWMVaP/QBVgvIFcdByqNWezpd9T4ZUII | ||||
| MZlaV1uRnHg6B/zTzhIdMM80AXz6Uv6kw4S+Lt7HlbrnMT7uKLuvzH7cle0hcIUa | ||||
| PejgXO0uIRolYQ3sz2tMGhx1MfBqH64= | ||||
| =WbwB | ||||
| -----END PGP PRIVATE KEY BLOCK-----`; | ||||
|  | ||||
| jest.spyOn(context, 'defaultContext').mockImplementation((): string => { | ||||
|   return 'https://github.com/docker/build-push-action.git#refs/heads/test-jest'; | ||||
| import repoFixture from './fixtures/github-repo.json'; | ||||
| jest.spyOn(GitHub.prototype, 'repoData').mockImplementation((): Promise<GitHubRepo> => { | ||||
|   return <Promise<GitHubRepo>>(repoFixture as unknown); | ||||
| }); | ||||
|  | ||||
| jest.spyOn(context, 'tmpDir').mockImplementation((): string => { | ||||
|   const tmpDir = path.join('/tmp/.docker-build-push-jest').split(path.sep).join(path.posix.sep); | ||||
| jest.spyOn(Context, 'tmpDir').mockImplementation((): string => { | ||||
|   if (!fs.existsSync(tmpDir)) { | ||||
|     fs.mkdirSync(tmpDir, {recursive: true}); | ||||
|   } | ||||
|   return tmpDir; | ||||
| }); | ||||
|  | ||||
| jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => { | ||||
|   return path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); | ||||
| jest.spyOn(Context, 'tmpName').mockImplementation((): string => { | ||||
|   return tmpName; | ||||
| }); | ||||
|  | ||||
| jest.spyOn(buildx, 'satisfiesBuildKitVersion').mockResolvedValueOnce(true); | ||||
| jest.spyOn(Docker, 'isAvailable').mockImplementation(async (): Promise<boolean> => { | ||||
|   return true; | ||||
| }); | ||||
|  | ||||
| jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<BuilderInfo> => { | ||||
|   return { | ||||
|     name: 'builder2', | ||||
|     driver: 'docker-container', | ||||
|     lastActivity: new Date('2023-01-16 09:45:23 +0000 UTC'), | ||||
|     nodes: [ | ||||
|       { | ||||
|         buildkit: 'v0.11.0', | ||||
|         'buildkitd-flags': '--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|         'driver-opts': ['BUILDKIT_STEP_LOG_MAX_SIZE=10485760', 'BUILDKIT_STEP_LOG_MAX_SPEED=10485760', 'JAEGER_TRACE=localhost:6831', 'image=moby/buildkit:latest', 'network=host'], | ||||
|         endpoint: 'unix:///var/run/docker.sock', | ||||
|         name: 'builder20', | ||||
|         platforms: 'linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6', | ||||
|         status: 'running' | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
| }); | ||||
|  | ||||
| describe('getArgs', () => { | ||||
|   beforeEach(() => { | ||||
| @@ -154,7 +78,7 @@ describe('getArgs', () => { | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -177,8 +101,8 @@ ccc"`], | ||||
|         '--build-arg', 'MY_ARG=val1,val2,val3', | ||||
|         '--build-arg', 'ARG=val', | ||||
|         '--build-arg', `MULTILINE=aaaa\nbbbb\nccc`, | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest' | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @@ -193,10 +117,10 @@ ccc"`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--tag', 'name/app:7.4', | ||||
|         '--tag', 'name/app:latest', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest' | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @@ -248,7 +172,7 @@ ccc"`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -265,8 +189,8 @@ ccc"`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -284,8 +208,8 @@ ccc"`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--output', '.', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest' | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @@ -306,9 +230,9 @@ ccc"`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--platform', 'linux/amd64,linux/arm64', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--push', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
| @@ -340,12 +264,12 @@ ccc"`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--platform', 'linux/amd64,linux/arm64', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '--secret', `id=MYSECRET,src=${tmpName}`, | ||||
|         '--secret', `id=FOO,src=${tmpName}`, | ||||
|         '--secret', `id=EMPTYLINE,src=${tmpName}`, | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--push', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
| @@ -377,12 +301,12 @@ ccc`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--platform', 'linux/amd64,linux/arm64', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '--secret', `id=MYSECRET,src=${tmpName}`, | ||||
|         '--secret', `id=FOO,src=${tmpName}`, | ||||
|         '--secret', `id=EMPTYLINE,src=${tmpName}`, | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--push', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
| @@ -394,7 +318,7 @@ ccc`], | ||||
|       new Map<string, string>([ | ||||
|         ['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'], | ||||
|         ['tag', 'localhost:5000/name/app:latest'], | ||||
|         ['secret-files', `MY_SECRET=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`], | ||||
|         ['secret-files', `MY_SECRET=${path.join(__dirname, 'fixtures', 'secret.txt')}`], | ||||
|         ['file', './test/Dockerfile'], | ||||
|         ['builder', 'builder-git-context-2'], | ||||
|         ['network', 'host'], | ||||
| @@ -406,8 +330,8 @@ ccc`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--secret', `id=MY_SECRET,src=${tmpName}`, | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--network', 'host', | ||||
|         '--push', | ||||
| @@ -453,8 +377,8 @@ ccc`], | ||||
|         '--add-host', 'docker:10.180.0.1', | ||||
|         '--add-host', 'foo:10.0.0.1', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '--network', 'host', | ||||
|         '--push', | ||||
|         '.' | ||||
| @@ -482,11 +406,11 @@ nproc=3`], | ||||
|         '--add-host', 'foo:10.0.0.1', | ||||
|         '--cgroup-parent', 'foo', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--shm-size', '2g', | ||||
|         '--ulimit', 'nofile=1024:1024', | ||||
|         '--ulimit', 'nproc=3', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -502,9 +426,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest:docker' | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master:docker' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @@ -520,10 +444,10 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest:subdir' | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master:subdir' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @@ -539,8 +463,8 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -556,9 +480,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         "--provenance", 'false', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -575,9 +499,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", `builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -594,9 +518,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", `mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -613,9 +537,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", 'false', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -632,9 +556,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", 'builder-id=foo', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -651,9 +575,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--output", 'type=docker', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @@ -669,183 +593,156 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         "--load", | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--load', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       25, | ||||
|       '0.10.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
|         ['build-args', `FOO=bar#baz`], | ||||
|         ['load', 'true'], | ||||
|         ['no-cache', 'false'], | ||||
|         ['push', 'false'], | ||||
|         ['pull', 'false'], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--build-arg', 'FOO=bar#baz', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--load', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       25, | ||||
|       '0.10.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
|         ['no-cache', 'false'], | ||||
|         ['load', 'true'], | ||||
|         ['push', 'false'], | ||||
|         ['pull', 'false'], | ||||
|         ['secret-envs', `MY_SECRET=MY_SECRET_ENV | ||||
| ANOTHER_SECRET=ANOTHER_SECRET_ENV`] | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--secret', 'id=MY_SECRET,env=MY_SECRET_ENV', | ||||
|         '--secret', 'id=ANOTHER_SECRET,env=ANOTHER_SECRET_ENV', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--load', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       26, | ||||
|       '0.10.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
|         ['no-cache', 'false'], | ||||
|         ['load', 'true'], | ||||
|         ['push', 'false'], | ||||
|         ['pull', 'false'], | ||||
|         ['secret-envs', 'MY_SECRET=MY_SECRET_ENV,ANOTHER_SECRET=ANOTHER_SECRET_ENV'] | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--secret', 'id=MY_SECRET,env=MY_SECRET_ENV', | ||||
|         '--secret', 'id=ANOTHER_SECRET,env=ANOTHER_SECRET_ENV', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--load', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       27, | ||||
|       '0.11.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
|         ['annotations', 'example1=www\nindex:example2=xxx\nmanifest:example3=yyy\nmanifest-descriptor[linux/amd64]:example4=zzz'], | ||||
|         ['outputs', 'type=local,dest=./release-out'], | ||||
|         ['load', 'false'], | ||||
|         ['no-cache', 'false'], | ||||
|         ['push', 'false'], | ||||
|         ['pull', 'false'], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--output', 'type=local,dest=./release-out', | ||||
|         "--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       28, | ||||
|       '0.12.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
|         ['annotations', 'example1=www\nindex:example2=xxx\nmanifest:example3=yyy\nmanifest-descriptor[linux/amd64]:example4=zzz'], | ||||
|         ['outputs', 'type=local,dest=./release-out'], | ||||
|         ['load', 'false'], | ||||
|         ['no-cache', 'false'], | ||||
|         ['push', 'false'], | ||||
|         ['pull', 'false'], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--annotation', 'example1=www', | ||||
|         '--annotation', 'index:example2=xxx', | ||||
|         '--annotation', 'manifest:example3=yyy', | ||||
|         '--annotation', 'manifest-descriptor[linux/amd64]:example4=zzz', | ||||
|         '--output', 'type=local,dest=./release-out', | ||||
|         "--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       29, | ||||
|       '0.12.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
|         ['outputs', `type=image,"name=localhost:5000/name/app:latest,localhost:5000/name/app:foo",push-by-digest=true,name-canonical=true,push=true`], | ||||
|         ['load', 'false'], | ||||
|         ['no-cache', 'false'], | ||||
|         ['push', 'false'], | ||||
|         ['pull', 'false'], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--output", `type=image,"name=localhost:5000/name/app:latest,localhost:5000/name/app:foo",push-by-digest=true,name-canonical=true,push=true`, | ||||
|         "--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ] | ||||
|   ])( | ||||
|     '[%d] given %p with %p as inputs, returns %p', | ||||
|     async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => { | ||||
|       inputs.forEach((value: string, name: string) => { | ||||
|         setInput(name, value); | ||||
|       }); | ||||
|       const defContext = context.defaultContext(); | ||||
|       const inp = await context.getInputs(defContext); | ||||
|       const res = await context.getArgs(inp, defContext, buildxVersion); | ||||
|       const toolkit = new Toolkit(); | ||||
|       jest.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => { | ||||
|         return buildxVersion; | ||||
|       }); | ||||
|       const inp = await context.getInputs(); | ||||
|       const res = await context.getArgs(inp, toolkit); | ||||
|       expect(res).toEqual(expected); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| describe('getInputList', () => { | ||||
|   it('single line correctly', async () => { | ||||
|     await setInput('foo', 'bar'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar']); | ||||
|   }); | ||||
|  | ||||
|   it('multiline correctly', async () => { | ||||
|     setInput('foo', 'bar\nbaz'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
|  | ||||
|   it('empty lines correctly', async () => { | ||||
|     setInput('foo', 'bar\n\nbaz'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
|  | ||||
|   it('comma correctly', async () => { | ||||
|     setInput('foo', 'bar,baz'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
|  | ||||
|   it('empty result correctly', async () => { | ||||
|     setInput('foo', 'bar,baz,'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
|  | ||||
|   it('different new lines correctly', async () => { | ||||
|     setInput('foo', 'bar\r\nbaz'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
|  | ||||
|   it('different new lines and comma correctly', async () => { | ||||
|     setInput('foo', 'bar\r\nbaz,bat'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz', 'bat']); | ||||
|   }); | ||||
|  | ||||
|   it('multiline and ignoring comma correctly', async () => { | ||||
|     setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir'); | ||||
|     const res = await context.getInputList('cache-from', true); | ||||
|     expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']); | ||||
|   }); | ||||
|  | ||||
|   it('different new lines and ignoring comma correctly', async () => { | ||||
|     setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir'); | ||||
|     const res = await context.getInputList('cache-from', true); | ||||
|     expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']); | ||||
|   }); | ||||
|  | ||||
|   it('multiline values', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789 | ||||
| "MYSECRET=aaaaaaaa | ||||
| bbbbbbb | ||||
| ccccccccc" | ||||
| FOO=bar` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual([ | ||||
|       'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', | ||||
|       `MYSECRET=aaaaaaaa | ||||
| bbbbbbb | ||||
| ccccccccc`, | ||||
|       'FOO=bar' | ||||
|     ]); | ||||
|   }); | ||||
|  | ||||
|   it('multiline values with empty lines', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789 | ||||
| "MYSECRET=aaaaaaaa | ||||
| bbbbbbb | ||||
| ccccccccc" | ||||
| FOO=bar | ||||
| "EMPTYLINE=aaaa | ||||
|  | ||||
| bbbb | ||||
| ccc"` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual([ | ||||
|       'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', | ||||
|       `MYSECRET=aaaaaaaa | ||||
| bbbbbbb | ||||
| ccccccccc`, | ||||
|       'FOO=bar', | ||||
|       `EMPTYLINE=aaaa | ||||
|  | ||||
| bbbb | ||||
| ccc` | ||||
|     ]); | ||||
|   }); | ||||
|  | ||||
|   it('multiline values without quotes', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789 | ||||
| MYSECRET=aaaaaaaa | ||||
| bbbbbbb | ||||
| ccccccccc | ||||
| FOO=bar` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']); | ||||
|   }); | ||||
|  | ||||
|   it('large multiline values', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `"GPG_KEY=${pgp}" | ||||
| FOO=bar` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']); | ||||
|   }); | ||||
|  | ||||
|   it('multiline values escape quotes', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789 | ||||
| "MYSECRET=aaaaaaaa | ||||
| bbbb""bbb | ||||
| ccccccccc" | ||||
| FOO=bar` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual([ | ||||
|       'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', | ||||
|       `MYSECRET=aaaaaaaa | ||||
| bbbb"bbb | ||||
| ccccccccc`, | ||||
|       'FOO=bar' | ||||
|     ]); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('asyncForEach', () => { | ||||
|   it('executes async tasks sequentially', async () => { | ||||
|     const testValues = [1, 2, 3, 4, 5]; | ||||
|     const results: number[] = []; | ||||
|  | ||||
|     await context.asyncForEach(testValues, async value => { | ||||
|       results.push(value); | ||||
|     }); | ||||
|  | ||||
|     expect(results).toEqual(testValues); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| // See: https://github.com/actions/toolkit/blob/a1b068ec31a042ff1e10a522d8fdf0b8869d53ca/packages/core/src/core.ts#L89 | ||||
| function getInputName(name: string): string { | ||||
|   return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`; | ||||
|   | ||||
| @@ -1,16 +0,0 @@ | ||||
| import {describe, expect, it, jest} from '@jest/globals'; | ||||
| import * as docker from '../src/docker'; | ||||
| import * as exec from '@actions/exec'; | ||||
|  | ||||
| describe('isAvailable', () => { | ||||
|   it('cli', () => { | ||||
|     const execSpy = jest.spyOn(exec, 'getExecOutput'); | ||||
|     docker.isAvailable(); | ||||
|  | ||||
|     // eslint-disable-next-line jest/no-standalone-expect | ||||
|     expect(execSpy).toHaveBeenCalledWith(`docker`, undefined, { | ||||
|       silent: true, | ||||
|       ignoreReturnCode: true | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										362
									
								
								__tests__/fixtures/github-repo.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										362
									
								
								__tests__/fixtures/github-repo.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,362 @@ | ||||
| { | ||||
|   "id": 1296269, | ||||
|   "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", | ||||
|   "name": "Hello-World", | ||||
|   "full_name": "octocat/Hello-World", | ||||
|   "owner": { | ||||
|     "login": "octocat", | ||||
|     "id": 1, | ||||
|     "node_id": "MDQ6VXNlcjE=", | ||||
|     "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|     "gravatar_id": "", | ||||
|     "url": "https://api.github.com/users/octocat", | ||||
|     "html_url": "https://github.com/octocat", | ||||
|     "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|     "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|     "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|     "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|     "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|     "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|     "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|     "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|     "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|     "type": "User", | ||||
|     "site_admin": false | ||||
|   }, | ||||
|   "private": false, | ||||
|   "html_url": "https://github.com/octocat/Hello-World", | ||||
|   "description": "This your first repo!", | ||||
|   "fork": false, | ||||
|   "url": "https://api.github.com/repos/octocat/Hello-World", | ||||
|   "archive_url": "http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", | ||||
|   "assignees_url": "http://api.github.com/repos/octocat/Hello-World/assignees{/user}", | ||||
|   "blobs_url": "http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", | ||||
|   "branches_url": "http://api.github.com/repos/octocat/Hello-World/branches{/branch}", | ||||
|   "collaborators_url": "http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", | ||||
|   "comments_url": "http://api.github.com/repos/octocat/Hello-World/comments{/number}", | ||||
|   "commits_url": "http://api.github.com/repos/octocat/Hello-World/commits{/sha}", | ||||
|   "compare_url": "http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", | ||||
|   "contents_url": "http://api.github.com/repos/octocat/Hello-World/contents/{+path}", | ||||
|   "contributors_url": "http://api.github.com/repos/octocat/Hello-World/contributors", | ||||
|   "deployments_url": "http://api.github.com/repos/octocat/Hello-World/deployments", | ||||
|   "downloads_url": "http://api.github.com/repos/octocat/Hello-World/downloads", | ||||
|   "events_url": "http://api.github.com/repos/octocat/Hello-World/events", | ||||
|   "forks_url": "http://api.github.com/repos/octocat/Hello-World/forks", | ||||
|   "git_commits_url": "http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", | ||||
|   "git_refs_url": "http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", | ||||
|   "git_tags_url": "http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", | ||||
|   "git_url": "git:github.com/octocat/Hello-World.git", | ||||
|   "issue_comment_url": "http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", | ||||
|   "issue_events_url": "http://api.github.com/repos/octocat/Hello-World/issues/events{/number}", | ||||
|   "issues_url": "http://api.github.com/repos/octocat/Hello-World/issues{/number}", | ||||
|   "keys_url": "http://api.github.com/repos/octocat/Hello-World/keys{/key_id}", | ||||
|   "labels_url": "http://api.github.com/repos/octocat/Hello-World/labels{/name}", | ||||
|   "languages_url": "http://api.github.com/repos/octocat/Hello-World/languages", | ||||
|   "merges_url": "http://api.github.com/repos/octocat/Hello-World/merges", | ||||
|   "milestones_url": "http://api.github.com/repos/octocat/Hello-World/milestones{/number}", | ||||
|   "notifications_url": "http://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", | ||||
|   "pulls_url": "http://api.github.com/repos/octocat/Hello-World/pulls{/number}", | ||||
|   "releases_url": "http://api.github.com/repos/octocat/Hello-World/releases{/id}", | ||||
|   "ssh_url": "git@github.com:octocat/Hello-World.git", | ||||
|   "stargazers_url": "http://api.github.com/repos/octocat/Hello-World/stargazers", | ||||
|   "statuses_url": "http://api.github.com/repos/octocat/Hello-World/statuses/{sha}", | ||||
|   "subscribers_url": "http://api.github.com/repos/octocat/Hello-World/subscribers", | ||||
|   "subscription_url": "http://api.github.com/repos/octocat/Hello-World/subscription", | ||||
|   "tags_url": "http://api.github.com/repos/octocat/Hello-World/tags", | ||||
|   "teams_url": "http://api.github.com/repos/octocat/Hello-World/teams", | ||||
|   "trees_url": "http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", | ||||
|   "clone_url": "https://github.com/octocat/Hello-World.git", | ||||
|   "mirror_url": "git:git.example.com/octocat/Hello-World", | ||||
|   "hooks_url": "http://api.github.com/repos/octocat/Hello-World/hooks", | ||||
|   "svn_url": "https://svn.github.com/octocat/Hello-World", | ||||
|   "homepage": "https://github.com", | ||||
|   "language": null, | ||||
|   "forks_count": 9, | ||||
|   "stargazers_count": 80, | ||||
|   "watchers_count": 80, | ||||
|   "size": 108, | ||||
|   "default_branch": "master", | ||||
|   "open_issues_count": 0, | ||||
|   "is_template": true, | ||||
|   "topics": [ | ||||
|     "octocat", | ||||
|     "atom", | ||||
|     "electron", | ||||
|     "api" | ||||
|   ], | ||||
|   "has_issues": true, | ||||
|   "has_projects": true, | ||||
|   "has_wiki": true, | ||||
|   "has_pages": false, | ||||
|   "has_downloads": true, | ||||
|   "archived": false, | ||||
|   "disabled": false, | ||||
|   "visibility": "public", | ||||
|   "pushed_at": "2011-01-26T19:06:43Z", | ||||
|   "created_at": "2011-01-26T19:01:12Z", | ||||
|   "updated_at": "2011-01-26T19:14:43Z", | ||||
|   "permissions": { | ||||
|     "pull": true, | ||||
|     "triage": true, | ||||
|     "push": false, | ||||
|     "maintain": false, | ||||
|     "admin": false | ||||
|   }, | ||||
|   "allow_rebase_merge": true, | ||||
|   "template_repository": null, | ||||
|   "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", | ||||
|   "allow_squash_merge": true, | ||||
|   "delete_branch_on_merge": true, | ||||
|   "allow_merge_commit": true, | ||||
|   "subscribers_count": 42, | ||||
|   "network_count": 0, | ||||
|   "license": { | ||||
|     "key": "mit", | ||||
|     "name": "MIT License", | ||||
|     "spdx_id": "MIT", | ||||
|     "url": "https://api.github.com/licenses/mit", | ||||
|     "node_id": "MDc6TGljZW5zZW1pdA==" | ||||
|   }, | ||||
|   "organization": { | ||||
|     "login": "octocat", | ||||
|     "id": 1, | ||||
|     "node_id": "MDQ6VXNlcjE=", | ||||
|     "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|     "gravatar_id": "", | ||||
|     "url": "https://api.github.com/users/octocat", | ||||
|     "html_url": "https://github.com/octocat", | ||||
|     "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|     "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|     "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|     "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|     "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|     "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|     "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|     "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|     "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|     "type": "Organization", | ||||
|     "site_admin": false | ||||
|   }, | ||||
|   "parent": { | ||||
|     "id": 1296269, | ||||
|     "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", | ||||
|     "name": "Hello-World", | ||||
|     "full_name": "octocat/Hello-World", | ||||
|     "owner": { | ||||
|       "login": "octocat", | ||||
|       "id": 1, | ||||
|       "node_id": "MDQ6VXNlcjE=", | ||||
|       "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|       "gravatar_id": "", | ||||
|       "url": "https://api.github.com/users/octocat", | ||||
|       "html_url": "https://github.com/octocat", | ||||
|       "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|       "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|       "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|       "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|       "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|       "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|       "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|       "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|       "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|       "type": "User", | ||||
|       "site_admin": false | ||||
|     }, | ||||
|     "private": false, | ||||
|     "html_url": "https://github.com/octocat/Hello-World", | ||||
|     "description": "This your first repo!", | ||||
|     "fork": false, | ||||
|     "url": "https://api.github.com/repos/octocat/Hello-World", | ||||
|     "archive_url": "http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", | ||||
|     "assignees_url": "http://api.github.com/repos/octocat/Hello-World/assignees{/user}", | ||||
|     "blobs_url": "http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", | ||||
|     "branches_url": "http://api.github.com/repos/octocat/Hello-World/branches{/branch}", | ||||
|     "collaborators_url": "http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", | ||||
|     "comments_url": "http://api.github.com/repos/octocat/Hello-World/comments{/number}", | ||||
|     "commits_url": "http://api.github.com/repos/octocat/Hello-World/commits{/sha}", | ||||
|     "compare_url": "http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", | ||||
|     "contents_url": "http://api.github.com/repos/octocat/Hello-World/contents/{+path}", | ||||
|     "contributors_url": "http://api.github.com/repos/octocat/Hello-World/contributors", | ||||
|     "deployments_url": "http://api.github.com/repos/octocat/Hello-World/deployments", | ||||
|     "downloads_url": "http://api.github.com/repos/octocat/Hello-World/downloads", | ||||
|     "events_url": "http://api.github.com/repos/octocat/Hello-World/events", | ||||
|     "forks_url": "http://api.github.com/repos/octocat/Hello-World/forks", | ||||
|     "git_commits_url": "http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", | ||||
|     "git_refs_url": "http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", | ||||
|     "git_tags_url": "http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", | ||||
|     "git_url": "git:github.com/octocat/Hello-World.git", | ||||
|     "issue_comment_url": "http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", | ||||
|     "issue_events_url": "http://api.github.com/repos/octocat/Hello-World/issues/events{/number}", | ||||
|     "issues_url": "http://api.github.com/repos/octocat/Hello-World/issues{/number}", | ||||
|     "keys_url": "http://api.github.com/repos/octocat/Hello-World/keys{/key_id}", | ||||
|     "labels_url": "http://api.github.com/repos/octocat/Hello-World/labels{/name}", | ||||
|     "languages_url": "http://api.github.com/repos/octocat/Hello-World/languages", | ||||
|     "merges_url": "http://api.github.com/repos/octocat/Hello-World/merges", | ||||
|     "milestones_url": "http://api.github.com/repos/octocat/Hello-World/milestones{/number}", | ||||
|     "notifications_url": "http://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", | ||||
|     "pulls_url": "http://api.github.com/repos/octocat/Hello-World/pulls{/number}", | ||||
|     "releases_url": "http://api.github.com/repos/octocat/Hello-World/releases{/id}", | ||||
|     "ssh_url": "git@github.com:octocat/Hello-World.git", | ||||
|     "stargazers_url": "http://api.github.com/repos/octocat/Hello-World/stargazers", | ||||
|     "statuses_url": "http://api.github.com/repos/octocat/Hello-World/statuses/{sha}", | ||||
|     "subscribers_url": "http://api.github.com/repos/octocat/Hello-World/subscribers", | ||||
|     "subscription_url": "http://api.github.com/repos/octocat/Hello-World/subscription", | ||||
|     "tags_url": "http://api.github.com/repos/octocat/Hello-World/tags", | ||||
|     "teams_url": "http://api.github.com/repos/octocat/Hello-World/teams", | ||||
|     "trees_url": "http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", | ||||
|     "clone_url": "https://github.com/octocat/Hello-World.git", | ||||
|     "mirror_url": "git:git.example.com/octocat/Hello-World", | ||||
|     "hooks_url": "http://api.github.com/repos/octocat/Hello-World/hooks", | ||||
|     "svn_url": "https://svn.github.com/octocat/Hello-World", | ||||
|     "homepage": "https://github.com", | ||||
|     "language": null, | ||||
|     "forks_count": 9, | ||||
|     "stargazers_count": 80, | ||||
|     "watchers_count": 80, | ||||
|     "size": 108, | ||||
|     "default_branch": "master", | ||||
|     "open_issues_count": 0, | ||||
|     "is_template": true, | ||||
|     "topics": [ | ||||
|       "octocat", | ||||
|       "atom", | ||||
|       "electron", | ||||
|       "api" | ||||
|     ], | ||||
|     "has_issues": true, | ||||
|     "has_projects": true, | ||||
|     "has_wiki": true, | ||||
|     "has_pages": false, | ||||
|     "has_downloads": true, | ||||
|     "archived": false, | ||||
|     "disabled": false, | ||||
|     "visibility": "public", | ||||
|     "pushed_at": "2011-01-26T19:06:43Z", | ||||
|     "created_at": "2011-01-26T19:01:12Z", | ||||
|     "updated_at": "2011-01-26T19:14:43Z", | ||||
|     "permissions": { | ||||
|       "admin": false, | ||||
|       "push": false, | ||||
|       "pull": true | ||||
|     }, | ||||
|     "allow_rebase_merge": true, | ||||
|     "template_repository": null, | ||||
|     "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", | ||||
|     "allow_squash_merge": true, | ||||
|     "delete_branch_on_merge": true, | ||||
|     "allow_merge_commit": true, | ||||
|     "subscribers_count": 42, | ||||
|     "network_count": 0 | ||||
|   }, | ||||
|   "source": { | ||||
|     "id": 1296269, | ||||
|     "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", | ||||
|     "name": "Hello-World", | ||||
|     "full_name": "octocat/Hello-World", | ||||
|     "owner": { | ||||
|       "login": "octocat", | ||||
|       "id": 1, | ||||
|       "node_id": "MDQ6VXNlcjE=", | ||||
|       "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|       "gravatar_id": "", | ||||
|       "url": "https://api.github.com/users/octocat", | ||||
|       "html_url": "https://github.com/octocat", | ||||
|       "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|       "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|       "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|       "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|       "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|       "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|       "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|       "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|       "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|       "type": "User", | ||||
|       "site_admin": false | ||||
|     }, | ||||
|     "private": false, | ||||
|     "html_url": "https://github.com/octocat/Hello-World", | ||||
|     "description": "This your first repo!", | ||||
|     "fork": false, | ||||
|     "url": "https://api.github.com/repos/octocat/Hello-World", | ||||
|     "archive_url": "http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", | ||||
|     "assignees_url": "http://api.github.com/repos/octocat/Hello-World/assignees{/user}", | ||||
|     "blobs_url": "http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", | ||||
|     "branches_url": "http://api.github.com/repos/octocat/Hello-World/branches{/branch}", | ||||
|     "collaborators_url": "http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", | ||||
|     "comments_url": "http://api.github.com/repos/octocat/Hello-World/comments{/number}", | ||||
|     "commits_url": "http://api.github.com/repos/octocat/Hello-World/commits{/sha}", | ||||
|     "compare_url": "http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", | ||||
|     "contents_url": "http://api.github.com/repos/octocat/Hello-World/contents/{+path}", | ||||
|     "contributors_url": "http://api.github.com/repos/octocat/Hello-World/contributors", | ||||
|     "deployments_url": "http://api.github.com/repos/octocat/Hello-World/deployments", | ||||
|     "downloads_url": "http://api.github.com/repos/octocat/Hello-World/downloads", | ||||
|     "events_url": "http://api.github.com/repos/octocat/Hello-World/events", | ||||
|     "forks_url": "http://api.github.com/repos/octocat/Hello-World/forks", | ||||
|     "git_commits_url": "http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", | ||||
|     "git_refs_url": "http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", | ||||
|     "git_tags_url": "http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", | ||||
|     "git_url": "git:github.com/octocat/Hello-World.git", | ||||
|     "issue_comment_url": "http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", | ||||
|     "issue_events_url": "http://api.github.com/repos/octocat/Hello-World/issues/events{/number}", | ||||
|     "issues_url": "http://api.github.com/repos/octocat/Hello-World/issues{/number}", | ||||
|     "keys_url": "http://api.github.com/repos/octocat/Hello-World/keys{/key_id}", | ||||
|     "labels_url": "http://api.github.com/repos/octocat/Hello-World/labels{/name}", | ||||
|     "languages_url": "http://api.github.com/repos/octocat/Hello-World/languages", | ||||
|     "merges_url": "http://api.github.com/repos/octocat/Hello-World/merges", | ||||
|     "milestones_url": "http://api.github.com/repos/octocat/Hello-World/milestones{/number}", | ||||
|     "notifications_url": "http://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", | ||||
|     "pulls_url": "http://api.github.com/repos/octocat/Hello-World/pulls{/number}", | ||||
|     "releases_url": "http://api.github.com/repos/octocat/Hello-World/releases{/id}", | ||||
|     "ssh_url": "git@github.com:octocat/Hello-World.git", | ||||
|     "stargazers_url": "http://api.github.com/repos/octocat/Hello-World/stargazers", | ||||
|     "statuses_url": "http://api.github.com/repos/octocat/Hello-World/statuses/{sha}", | ||||
|     "subscribers_url": "http://api.github.com/repos/octocat/Hello-World/subscribers", | ||||
|     "subscription_url": "http://api.github.com/repos/octocat/Hello-World/subscription", | ||||
|     "tags_url": "http://api.github.com/repos/octocat/Hello-World/tags", | ||||
|     "teams_url": "http://api.github.com/repos/octocat/Hello-World/teams", | ||||
|     "trees_url": "http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", | ||||
|     "clone_url": "https://github.com/octocat/Hello-World.git", | ||||
|     "mirror_url": "git:git.example.com/octocat/Hello-World", | ||||
|     "hooks_url": "http://api.github.com/repos/octocat/Hello-World/hooks", | ||||
|     "svn_url": "https://svn.github.com/octocat/Hello-World", | ||||
|     "homepage": "https://github.com", | ||||
|     "language": null, | ||||
|     "forks_count": 9, | ||||
|     "stargazers_count": 80, | ||||
|     "watchers_count": 80, | ||||
|     "size": 108, | ||||
|     "default_branch": "master", | ||||
|     "open_issues_count": 0, | ||||
|     "is_template": true, | ||||
|     "topics": [ | ||||
|       "octocat", | ||||
|       "atom", | ||||
|       "electron", | ||||
|       "api" | ||||
|     ], | ||||
|     "has_issues": true, | ||||
|     "has_projects": true, | ||||
|     "has_wiki": true, | ||||
|     "has_pages": false, | ||||
|     "has_downloads": true, | ||||
|     "archived": false, | ||||
|     "disabled": false, | ||||
|     "visibility": "public", | ||||
|     "pushed_at": "2011-01-26T19:06:43Z", | ||||
|     "created_at": "2011-01-26T19:01:12Z", | ||||
|     "updated_at": "2011-01-26T19:14:43Z", | ||||
|     "permissions": { | ||||
|       "admin": false, | ||||
|       "push": false, | ||||
|       "pull": true | ||||
|     }, | ||||
|     "allow_rebase_merge": true, | ||||
|     "template_repository": null, | ||||
|     "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", | ||||
|     "allow_squash_merge": true, | ||||
|     "delete_branch_on_merge": true, | ||||
|     "allow_merge_commit": true, | ||||
|     "subscribers_count": 42, | ||||
|     "network_count": 0 | ||||
|   } | ||||
| } | ||||
| @@ -13,6 +13,9 @@ inputs: | ||||
|   allow: | ||||
|     description: "List of extra privileged entitlement (e.g., network.host,security.insecure)" | ||||
|     required: false | ||||
|   annotations: | ||||
|     description: "List of annotation to set to the image" | ||||
|     required: false | ||||
|   attests: | ||||
|     description: "List of attestation parameters (e.g., type=sbom,generator=image)" | ||||
|     required: false | ||||
| @@ -80,6 +83,9 @@ inputs: | ||||
|   secrets: | ||||
|     description: "List of secrets to expose to the build (e.g., key=string, GIT_AUTH_TOKEN=mytoken)" | ||||
|     required: false | ||||
|   secret-envs: | ||||
|     description: "List of secret env vars to expose to the build (e.g., key=envname, MY_SECRET=MY_ENV_VAR)" | ||||
|     required: false | ||||
|   secret-files: | ||||
|     description: "List of secret files to expose to the build (e.g., key=filename, MY_SECRET=./secret.txt)" | ||||
|     required: false | ||||
| @@ -112,6 +118,6 @@ outputs: | ||||
|     description: 'Build result metadata' | ||||
|  | ||||
| runs: | ||||
|   using: 'node16' | ||||
|   using: 'node20' | ||||
|   main: 'dist/index.js' | ||||
|   post: 'dist/index.js' | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| # syntax=docker/dockerfile:1 | ||||
|  | ||||
| ARG NODE_VERSION=16 | ||||
| ARG DOCKER_VERSION=20.10.13 | ||||
| ARG BUILDX_VERSION=0.8.0 | ||||
| ARG NODE_VERSION=20 | ||||
|  | ||||
| FROM node:${NODE_VERSION}-alpine AS base | ||||
| RUN apk add --no-cache cpio findutils git | ||||
| @@ -62,15 +60,10 @@ RUN --mount=type=bind,target=.,rw \ | ||||
|   --mount=type=cache,target=/src/node_modules \ | ||||
|   yarn run lint | ||||
|  | ||||
| FROM docker:${DOCKER_VERSION} as docker | ||||
| FROM docker/buildx-bin:${BUILDX_VERSION} as buildx | ||||
|  | ||||
| FROM deps AS test | ||||
| RUN --mount=type=bind,target=.,rw \ | ||||
|   --mount=type=cache,target=/src/node_modules \ | ||||
|   --mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \ | ||||
|   --mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \ | ||||
|   yarn run test --coverageDirectory=/tmp/coverage | ||||
|   yarn run test --coverage --coverageDirectory=/tmp/coverage | ||||
|  | ||||
| FROM scratch AS test-coverage | ||||
| COPY --from=test /tmp/coverage / | ||||
|   | ||||
							
								
								
									
										26
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/index.js.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/index.js.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1082
									
								
								dist/licenses.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1082
									
								
								dist/licenses.txt
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/sourcemap-register.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/sourcemap-register.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,3 +1,3 @@ | ||||
| # Cache | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#cache) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/cache/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Copy images between registries | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#copy-images-between-registries) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/copy-image-registries/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Update Docker Hub repo description | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#update-docker-hub-repository-description) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/update-dockerhub-desc/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Export image to Docker | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#export-image-to-docker) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/export-docker/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Local registry | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#local-registry) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/local-registry/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Multi-platform image | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#multi-platform-images) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/multi-platform/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Named contexts | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#named-contexts) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/named-contexts/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Push to multi-registries | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#push-to-multi-registries) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/push-multi-registries/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Secrets | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#secrets) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/secrets/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Share built image between jobs | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#share-built-image-between-jobs) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/share-image-jobs/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Handle tags and labels | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#manage-tags-and-labels) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/manage-tags-labels/) | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| # Test your image before pushing it | ||||
|  | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/examples/#test-your-image-before-pushing-it) | ||||
| This page has moved to [Docker Docs website](https://docs.docker.com/build/ci/github-actions/test-before-push/) | ||||
|   | ||||
| @@ -1,8 +1,14 @@ | ||||
| import fs from 'fs'; | ||||
| import os from 'os'; | ||||
| import path from 'path'; | ||||
|  | ||||
| const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-build-push-action-')); | ||||
|  | ||||
| process.env = Object.assign({}, process.env, { | ||||
|   RUNNER_TEMP: '/tmp/github_runner', | ||||
|   RUNNER_TOOL_CACHE: '/tmp/github_tool_cache', | ||||
|   TEMP: tmpDir, | ||||
|   GITHUB_REPOSITORY: 'docker/build-push-action', | ||||
|   GITHUB_RUN_ID: '123456789' | ||||
|   RUNNER_TEMP: path.join(tmpDir, 'runner-temp'), | ||||
|   RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache') | ||||
| }) as { | ||||
|   [key: string]: string; | ||||
| }; | ||||
| @@ -11,7 +17,6 @@ module.exports = { | ||||
|   clearMocks: false, | ||||
|   testEnvironment: 'node', | ||||
|   moduleFileExtensions: ['js', 'ts'], | ||||
|   setupFiles: ['dotenv/config'], | ||||
|   testMatch: ['**/*.test.ts'], | ||||
|   transform: { | ||||
|     '^.+\\.ts$': 'ts-jest' | ||||
| @@ -19,5 +24,7 @@ module.exports = { | ||||
|   moduleNameMapper: { | ||||
|     '^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs' | ||||
|   }, | ||||
|   collectCoverageFrom: ['src/**/{!(main.ts),}.ts'], | ||||
|   coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__mocks__/', '__tests__/'], | ||||
|   verbose: true | ||||
| }; | ||||
|   | ||||
							
								
								
									
										58
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								package.json
									
									
									
									
									
								
							| @@ -4,9 +4,13 @@ | ||||
|   "main": "lib/main.js", | ||||
|   "scripts": { | ||||
|     "build": "ncc build src/main.ts --source-map --minify --license licenses.txt", | ||||
|     "lint": "eslint src/**/*.ts __tests__/**/*.ts", | ||||
|     "format": "eslint --fix src/**/*.ts __tests__/**/*.ts", | ||||
|     "test": "jest --coverage", | ||||
|     "lint": "yarn run prettier && yarn run eslint", | ||||
|     "format": "yarn run prettier:fix && yarn run eslint:fix", | ||||
|     "eslint": "eslint --max-warnings=0 .", | ||||
|     "eslint:fix": "eslint --fix .", | ||||
|     "prettier": "prettier --check \"./**/*.ts\"", | ||||
|     "prettier:fix": "prettier --write \"./**/*.ts\"", | ||||
|     "test": "jest", | ||||
|     "all": "yarn run build && yarn run format && yarn test" | ||||
|   }, | ||||
|   "repository": { | ||||
| @@ -19,41 +23,27 @@ | ||||
|     "build", | ||||
|     "push" | ||||
|   ], | ||||
|   "author": "Docker", | ||||
|   "contributors": [ | ||||
|     { | ||||
|       "name": "CrazyMax", | ||||
|       "url": "https://crazymax.dev" | ||||
|     } | ||||
|   ], | ||||
|   "author": "Docker Inc.", | ||||
|   "license": "Apache-2.0", | ||||
|   "dependencies": { | ||||
|     "@actions/core": "^1.10.0", | ||||
|     "@actions/exec": "^1.1.1", | ||||
|     "@actions/github": "^5.1.1", | ||||
|     "csv-parse": "^5.3.3", | ||||
|     "handlebars": "^4.7.7", | ||||
|     "jwt-decode": "^3.1.2", | ||||
|     "semver": "^7.3.7", | ||||
|     "tmp": "^0.2.1" | ||||
|     "@actions/core": "^1.10.1", | ||||
|     "@docker/actions-toolkit": "0.18.0", | ||||
|     "handlebars": "^4.7.7" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/csv-parse": "^1.2.2", | ||||
|     "@types/node": "^16.11.26", | ||||
|     "@types/semver": "^7.3.9", | ||||
|     "@types/tmp": "^0.2.3", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.14.0", | ||||
|     "@typescript-eslint/parser": "^5.14.0", | ||||
|     "@vercel/ncc": "^0.33.3", | ||||
|     "dotenv": "^16.0.0", | ||||
|     "eslint": "^8.11.0", | ||||
|     "eslint-config-prettier": "^8.5.0", | ||||
|     "eslint-plugin-jest": "^26.1.1", | ||||
|     "eslint-plugin-prettier": "^4.0.0", | ||||
|     "jest": "^27.2.5", | ||||
|     "prettier": "^2.3.1", | ||||
|     "ts-jest": "^27.1.2", | ||||
|     "ts-node": "^10.7.0", | ||||
|     "typescript": "^4.4.4" | ||||
|     "@types/node": "^20.5.9", | ||||
|     "@typescript-eslint/eslint-plugin": "^6.6.0", | ||||
|     "@typescript-eslint/parser": "^6.6.0", | ||||
|     "@vercel/ncc": "^0.38.0", | ||||
|     "eslint": "^8.48.0", | ||||
|     "eslint-config-prettier": "^9.0.0", | ||||
|     "eslint-plugin-jest": "^27.2.3", | ||||
|     "eslint-plugin-prettier": "^5.0.0", | ||||
|     "jest": "^29.6.4", | ||||
|     "prettier": "^3.0.3", | ||||
|     "ts-jest": "^29.1.1", | ||||
|     "ts-node": "^10.9.1", | ||||
|     "typescript": "^5.2.2" | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										282
									
								
								src/buildx.ts
									
									
									
									
									
								
							
							
						
						
									
										282
									
								
								src/buildx.ts
									
									
									
									
									
								
							| @@ -1,282 +0,0 @@ | ||||
| import {parse} from 'csv-parse/sync'; | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import * as semver from 'semver'; | ||||
| import * as exec from '@actions/exec'; | ||||
| import * as context from './context'; | ||||
|  | ||||
| export type Builder = { | ||||
|   name?: string; | ||||
|   driver?: string; | ||||
|   nodes: Node[]; | ||||
| }; | ||||
|  | ||||
| export type Node = { | ||||
|   name?: string; | ||||
|   endpoint?: string; | ||||
|   'driver-opts'?: Array<string>; | ||||
|   status?: string; | ||||
|   'buildkitd-flags'?: string; | ||||
|   buildkit?: string; | ||||
|   platforms?: string; | ||||
| }; | ||||
|  | ||||
| export async function getImageIDFile(): Promise<string> { | ||||
|   return path.join(context.tmpDir(), 'iidfile').split(path.sep).join(path.posix.sep); | ||||
| } | ||||
|  | ||||
| export async function getImageID(): Promise<string | undefined> { | ||||
|   const iidFile = await getImageIDFile(); | ||||
|   if (!fs.existsSync(iidFile)) { | ||||
|     return undefined; | ||||
|   } | ||||
|   return fs.readFileSync(iidFile, {encoding: 'utf-8'}).trim(); | ||||
| } | ||||
|  | ||||
| export async function getMetadataFile(): Promise<string> { | ||||
|   return path.join(context.tmpDir(), 'metadata-file').split(path.sep).join(path.posix.sep); | ||||
| } | ||||
|  | ||||
| export async function getMetadata(): Promise<string | undefined> { | ||||
|   const metadataFile = await getMetadataFile(); | ||||
|   if (!fs.existsSync(metadataFile)) { | ||||
|     return undefined; | ||||
|   } | ||||
|   const content = fs.readFileSync(metadataFile, {encoding: 'utf-8'}).trim(); | ||||
|   if (content === 'null') { | ||||
|     return undefined; | ||||
|   } | ||||
|   return content; | ||||
| } | ||||
|  | ||||
| export async function getDigest(metadata: string | undefined): Promise<string | undefined> { | ||||
|   if (metadata === undefined) { | ||||
|     return undefined; | ||||
|   } | ||||
|   const metadataJSON = JSON.parse(metadata); | ||||
|   if (metadataJSON['containerimage.digest']) { | ||||
|     return metadataJSON['containerimage.digest']; | ||||
|   } | ||||
|   return undefined; | ||||
| } | ||||
|  | ||||
| export async function getSecretString(kvp: string): Promise<string> { | ||||
|   return getSecret(kvp, false); | ||||
| } | ||||
|  | ||||
| export async function getSecretFile(kvp: string): Promise<string> { | ||||
|   return getSecret(kvp, true); | ||||
| } | ||||
|  | ||||
| export async function getSecret(kvp: string, file: boolean): Promise<string> { | ||||
|   const delimiterIndex = kvp.indexOf('='); | ||||
|   const key = kvp.substring(0, delimiterIndex); | ||||
|   let value = kvp.substring(delimiterIndex + 1); | ||||
|   if (key.length == 0 || value.length == 0) { | ||||
|     throw new Error(`${kvp} is not a valid secret`); | ||||
|   } | ||||
|  | ||||
|   if (file) { | ||||
|     if (!fs.existsSync(value)) { | ||||
|       throw new Error(`secret file ${value} not found`); | ||||
|     } | ||||
|     value = fs.readFileSync(value, {encoding: 'utf-8'}); | ||||
|   } | ||||
|  | ||||
|   const secretFile = context.tmpNameSync({ | ||||
|     tmpdir: context.tmpDir() | ||||
|   }); | ||||
|   fs.writeFileSync(secretFile, value); | ||||
|  | ||||
|   return `id=${key},src=${secretFile}`; | ||||
| } | ||||
|  | ||||
| export function isLocalOrTarExporter(outputs: string[]): boolean { | ||||
|   const records = parse(outputs.join(`\n`), { | ||||
|     delimiter: ',', | ||||
|     trim: true, | ||||
|     columns: false, | ||||
|     relaxColumnCount: true | ||||
|   }); | ||||
|   for (const record of records) { | ||||
|     // Local if no type is defined | ||||
|     // https://github.com/docker/buildx/blob/d2bf42f8b4784d83fde17acb3ed84703ddc2156b/build/output.go#L29-L43 | ||||
|     if (record.length == 1 && !record[0].startsWith('type=')) { | ||||
|       return true; | ||||
|     } | ||||
|     for (const [key, value] of record.map(chunk => chunk.split('=').map(item => item.trim()))) { | ||||
|       if (key == 'type' && (value == 'local' || value == 'tar')) { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| export function hasGitAuthToken(secrets: string[]): boolean { | ||||
|   for (const secret of secrets) { | ||||
|     if (secret.startsWith('GIT_AUTH_TOKEN=')) { | ||||
|       return true; | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| export async function isAvailable(standalone?: boolean): Promise<boolean> { | ||||
|   const cmd = getCommand([], standalone); | ||||
|   return await exec | ||||
|     .getExecOutput(cmd.command, cmd.args, { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         return false; | ||||
|       } | ||||
|       return res.exitCode == 0; | ||||
|     }) | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||||
|     .catch(error => { | ||||
|       return false; | ||||
|     }); | ||||
| } | ||||
|  | ||||
| export async function satisfiesBuildKitVersion(builderName: string, range: string, standalone?: boolean): Promise<boolean> { | ||||
|   const builderInspect = await inspect(builderName, standalone); | ||||
|   for (const node of builderInspect.nodes) { | ||||
|     if (!node.buildkit) { | ||||
|       return false; | ||||
|     } | ||||
|     // BuildKit version reported by moby is in the format of `v0.11.0-moby` | ||||
|     if (builderInspect.driver == 'docker' && !node.buildkit.endsWith('-moby')) { | ||||
|       return false; | ||||
|     } | ||||
|     const version = node.buildkit.replace(/-moby$/, ''); | ||||
|     if (!semver.satisfies(version, range)) { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| async function inspect(name: string, standalone?: boolean): Promise<Builder> { | ||||
|   const cmd = getCommand(['inspect', name], standalone); | ||||
|   return await exec | ||||
|     .getExecOutput(cmd.command, cmd.args, { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(res.stderr.trim()); | ||||
|       } | ||||
|       return parseInspect(res.stdout); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| async function parseInspect(data: string): Promise<Builder> { | ||||
|   const builder: Builder = { | ||||
|     nodes: [] | ||||
|   }; | ||||
|   let node: Node = {}; | ||||
|   for (const line of data.trim().split(`\n`)) { | ||||
|     const [key, ...rest] = line.split(':'); | ||||
|     const value = rest.map(v => v.trim()).join(':'); | ||||
|     if (key.length == 0 || value.length == 0) { | ||||
|       continue; | ||||
|     } | ||||
|     switch (key.toLowerCase()) { | ||||
|       case 'name': { | ||||
|         if (builder.name == undefined) { | ||||
|           builder.name = value; | ||||
|         } else { | ||||
|           if (Object.keys(node).length > 0) { | ||||
|             builder.nodes.push(node); | ||||
|             node = {}; | ||||
|           } | ||||
|           node.name = value; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case 'driver': { | ||||
|         builder.driver = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'endpoint': { | ||||
|         node.endpoint = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'driver options': { | ||||
|         node['driver-opts'] = (value.match(/(\w+)="([^"]*)"/g) || []).map(v => v.replace(/^(.*)="(.*)"$/g, '$1=$2')); | ||||
|         break; | ||||
|       } | ||||
|       case 'status': { | ||||
|         node.status = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'flags': { | ||||
|         node['buildkitd-flags'] = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'buildkit': { | ||||
|         node.buildkit = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'platforms': { | ||||
|         let platforms: Array<string> = []; | ||||
|         // if a preferred platform is being set then use only these | ||||
|         // https://docs.docker.com/engine/reference/commandline/buildx_inspect/#get-information-about-a-builder-instance | ||||
|         if (value.includes('*')) { | ||||
|           for (const platform of value.split(', ')) { | ||||
|             if (platform.includes('*')) { | ||||
|               platforms.push(platform.replace('*', '')); | ||||
|             } | ||||
|           } | ||||
|         } else { | ||||
|           // otherwise set all platforms available | ||||
|           platforms = value.split(', '); | ||||
|         } | ||||
|         node.platforms = platforms.join(','); | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if (Object.keys(node).length > 0) { | ||||
|     builder.nodes.push(node); | ||||
|   } | ||||
|   return builder; | ||||
| } | ||||
|  | ||||
| export async function getVersion(standalone?: boolean): Promise<string> { | ||||
|   const cmd = getCommand(['version'], standalone); | ||||
|   return await exec | ||||
|     .getExecOutput(cmd.command, cmd.args, { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(res.stderr.trim()); | ||||
|       } | ||||
|       return parseVersion(res.stdout.trim()); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| export function parseVersion(stdout: string): string { | ||||
|   const matches = /\sv?([0-9a-f]{7}|[0-9.]+)/.exec(stdout); | ||||
|   if (!matches) { | ||||
|     throw new Error(`Cannot parse buildx version`); | ||||
|   } | ||||
|   return matches[1]; | ||||
| } | ||||
|  | ||||
| export function satisfies(version: string, range: string): boolean { | ||||
|   return semver.satisfies(version, range) || /^[0-9a-f]{7}$/.exec(version) !== null; | ||||
| } | ||||
|  | ||||
| export function getCommand(args: Array<string>, standalone?: boolean) { | ||||
|   return { | ||||
|     command: standalone ? 'buildx' : 'docker', | ||||
|     args: standalone ? args : ['buildx', ...args] | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										284
									
								
								src/context.ts
									
									
									
									
									
								
							
							
						
						
									
										284
									
								
								src/context.ts
									
									
									
									
									
								
							| @@ -1,18 +1,15 @@ | ||||
| import * as fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import * as tmp from 'tmp'; | ||||
| import * as buildx from './buildx'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as github from '@actions/github'; | ||||
| import {parse} from 'csv-parse/sync'; | ||||
| import * as handlebars from 'handlebars'; | ||||
|  | ||||
| let _defaultContext, _tmpDir: string; | ||||
| import {Context} from '@docker/actions-toolkit/lib/context'; | ||||
| import {GitHub} from '@docker/actions-toolkit/lib/github'; | ||||
| import {Inputs as BuildxInputs} from '@docker/actions-toolkit/lib/buildx/inputs'; | ||||
| import {Toolkit} from '@docker/actions-toolkit/lib/toolkit'; | ||||
| import {Util} from '@docker/actions-toolkit/lib/util'; | ||||
|  | ||||
| export interface Inputs { | ||||
|   addHosts: string[]; | ||||
|   allow: string[]; | ||||
|   annotations: string[]; | ||||
|   attests: string[]; | ||||
|   buildArgs: string[]; | ||||
|   buildContexts: string[]; | ||||
| @@ -34,6 +31,7 @@ export interface Inputs { | ||||
|   push: boolean; | ||||
|   sbom: string; | ||||
|   secrets: string[]; | ||||
|   secretEnvs: string[]; | ||||
|   secretFiles: string[]; | ||||
|   shmSize: string; | ||||
|   ssh: string[]; | ||||
| @@ -43,181 +41,179 @@ export interface Inputs { | ||||
|   githubToken: string; | ||||
| } | ||||
|  | ||||
| export function defaultContext(): string { | ||||
|   if (!_defaultContext) { | ||||
|     let ref = github.context.ref; | ||||
|     if (github.context.sha && ref && !ref.startsWith('refs/')) { | ||||
|       ref = `refs/heads/${github.context.ref}`; | ||||
|     } | ||||
|     if (github.context.sha && !ref.startsWith(`refs/pull/`)) { | ||||
|       ref = github.context.sha; | ||||
|     } | ||||
|     _defaultContext = `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${github.context.repo.repo}.git#${ref}`; | ||||
|   } | ||||
|   return _defaultContext; | ||||
| } | ||||
|  | ||||
| export function tmpDir(): string { | ||||
|   if (!_tmpDir) { | ||||
|     _tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-build-push-')).split(path.sep).join(path.posix.sep); | ||||
|   } | ||||
|   return _tmpDir; | ||||
| } | ||||
|  | ||||
| export function tmpNameSync(options?: tmp.TmpNameOptions): string { | ||||
|   return tmp.tmpNameSync(options); | ||||
| } | ||||
|  | ||||
| export function provenanceBuilderID(): string { | ||||
|   return `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`; | ||||
| } | ||||
|  | ||||
| export async function getInputs(defaultContext: string): Promise<Inputs> { | ||||
| export async function getInputs(): Promise<Inputs> { | ||||
|   return { | ||||
|     addHosts: await getInputList('add-hosts'), | ||||
|     allow: await getInputList('allow'), | ||||
|     attests: await getInputList('attests', true), | ||||
|     buildArgs: await getInputList('build-args', true), | ||||
|     buildContexts: await getInputList('build-contexts', true), | ||||
|     addHosts: Util.getInputList('add-hosts'), | ||||
|     allow: Util.getInputList('allow'), | ||||
|     annotations: Util.getInputList('annotations', {ignoreComma: true}), | ||||
|     attests: Util.getInputList('attests', {ignoreComma: true}), | ||||
|     buildArgs: Util.getInputList('build-args', {ignoreComma: true}), | ||||
|     buildContexts: Util.getInputList('build-contexts', {ignoreComma: true}), | ||||
|     builder: core.getInput('builder'), | ||||
|     cacheFrom: await getInputList('cache-from', true), | ||||
|     cacheTo: await getInputList('cache-to', true), | ||||
|     cacheFrom: Util.getInputList('cache-from', {ignoreComma: true}), | ||||
|     cacheTo: Util.getInputList('cache-to', {ignoreComma: true}), | ||||
|     cgroupParent: core.getInput('cgroup-parent'), | ||||
|     context: core.getInput('context') || defaultContext, | ||||
|     context: core.getInput('context') || Context.gitContext(), | ||||
|     file: core.getInput('file'), | ||||
|     labels: await getInputList('labels', true), | ||||
|     labels: Util.getInputList('labels', {ignoreComma: true}), | ||||
|     load: core.getBooleanInput('load'), | ||||
|     network: core.getInput('network'), | ||||
|     noCache: core.getBooleanInput('no-cache'), | ||||
|     noCacheFilters: await getInputList('no-cache-filters'), | ||||
|     outputs: await getInputList('outputs', true), | ||||
|     platforms: await getInputList('platforms'), | ||||
|     provenance: getProvenanceInput('provenance'), | ||||
|     noCacheFilters: Util.getInputList('no-cache-filters'), | ||||
|     outputs: Util.getInputList('outputs', {ignoreComma: true, quote: false}), | ||||
|     platforms: Util.getInputList('platforms'), | ||||
|     provenance: BuildxInputs.getProvenanceInput('provenance'), | ||||
|     pull: core.getBooleanInput('pull'), | ||||
|     push: core.getBooleanInput('push'), | ||||
|     sbom: core.getInput('sbom'), | ||||
|     secrets: await getInputList('secrets', true), | ||||
|     secretFiles: await getInputList('secret-files', true), | ||||
|     secrets: Util.getInputList('secrets', {ignoreComma: true}), | ||||
|     secretEnvs: Util.getInputList('secret-envs'), | ||||
|     secretFiles: Util.getInputList('secret-files', {ignoreComma: true}), | ||||
|     shmSize: core.getInput('shm-size'), | ||||
|     ssh: await getInputList('ssh'), | ||||
|     tags: await getInputList('tags'), | ||||
|     ssh: Util.getInputList('ssh'), | ||||
|     tags: Util.getInputList('tags'), | ||||
|     target: core.getInput('target'), | ||||
|     ulimit: await getInputList('ulimit', true), | ||||
|     ulimit: Util.getInputList('ulimit', {ignoreComma: true}), | ||||
|     githubToken: core.getInput('github-token') | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string, standalone?: boolean): Promise<Array<string>> { | ||||
|   const context = handlebars.compile(inputs.context)({defaultContext}); | ||||
| export async function getArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> { | ||||
|   const context = handlebars.compile(inputs.context)({ | ||||
|     defaultContext: Context.gitContext() | ||||
|   }); | ||||
|   // prettier-ignore | ||||
|   return [ | ||||
|     ...await getBuildArgs(inputs, defaultContext, context, buildxVersion, standalone), | ||||
|     ...await getCommonArgs(inputs, buildxVersion), | ||||
|     ...await getBuildArgs(inputs, context, toolkit), | ||||
|     ...await getCommonArgs(inputs, toolkit), | ||||
|     context | ||||
|   ]; | ||||
| } | ||||
|  | ||||
| async function getBuildArgs(inputs: Inputs, defaultContext: string, context: string, buildxVersion: string, standalone?: boolean): Promise<Array<string>> { | ||||
| async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit): Promise<Array<string>> { | ||||
|   const args: Array<string> = ['build']; | ||||
|   await asyncForEach(inputs.addHosts, async addHost => { | ||||
|   await Util.asyncForEach(inputs.addHosts, async addHost => { | ||||
|     args.push('--add-host', addHost); | ||||
|   }); | ||||
|   if (inputs.allow.length > 0) { | ||||
|     args.push('--allow', inputs.allow.join(',')); | ||||
|   } | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.10.0')) { | ||||
|     await asyncForEach(inputs.attests, async attest => { | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.10.0')) { | ||||
|     await Util.asyncForEach(inputs.attests, async attest => { | ||||
|       args.push('--attest', attest); | ||||
|     }); | ||||
|   } else if (inputs.attests.length > 0) { | ||||
|     core.warning("Attestations are only supported by buildx >= 0.10.0; the input 'attests' is ignored."); | ||||
|   } | ||||
|   await asyncForEach(inputs.buildArgs, async buildArg => { | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.12.0')) { | ||||
|     await Util.asyncForEach(inputs.annotations, async annotation => { | ||||
|       args.push('--annotation', annotation); | ||||
|     }); | ||||
|   } else if (inputs.annotations.length > 0) { | ||||
|     core.warning("Annotations are only supported by buildx >= 0.12.0; the input 'annotations' is ignored."); | ||||
|   } | ||||
|   await Util.asyncForEach(inputs.buildArgs, async buildArg => { | ||||
|     args.push('--build-arg', buildArg); | ||||
|   }); | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.8.0')) { | ||||
|     await asyncForEach(inputs.buildContexts, async buildContext => { | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.8.0')) { | ||||
|     await Util.asyncForEach(inputs.buildContexts, async buildContext => { | ||||
|       args.push('--build-context', buildContext); | ||||
|     }); | ||||
|   } else if (inputs.buildContexts.length > 0) { | ||||
|     core.warning("Build contexts are only supported by buildx >= 0.8.0; the input 'build-contexts' is ignored."); | ||||
|   } | ||||
|   await asyncForEach(inputs.cacheFrom, async cacheFrom => { | ||||
|   await Util.asyncForEach(inputs.cacheFrom, async cacheFrom => { | ||||
|     args.push('--cache-from', cacheFrom); | ||||
|   }); | ||||
|   await asyncForEach(inputs.cacheTo, async cacheTo => { | ||||
|   await Util.asyncForEach(inputs.cacheTo, async cacheTo => { | ||||
|     args.push('--cache-to', cacheTo); | ||||
|   }); | ||||
|   if (inputs.cgroupParent) { | ||||
|     args.push('--cgroup-parent', inputs.cgroupParent); | ||||
|   } | ||||
|   await Util.asyncForEach(inputs.secretEnvs, async secretEnv => { | ||||
|     try { | ||||
|       args.push('--secret', BuildxInputs.resolveBuildSecretEnv(secretEnv)); | ||||
|     } catch (err) { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   }); | ||||
|   if (inputs.file) { | ||||
|     args.push('--file', inputs.file); | ||||
|   } | ||||
|   if (!buildx.isLocalOrTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || buildx.satisfies(buildxVersion, '>=0.4.2'))) { | ||||
|     args.push('--iidfile', await buildx.getImageIDFile()); | ||||
|   if (!BuildxInputs.hasLocalExporter(inputs.outputs) && !BuildxInputs.hasTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || (await toolkit.buildx.versionSatisfies('>=0.4.2')))) { | ||||
|     args.push('--iidfile', BuildxInputs.getBuildImageIDFilePath()); | ||||
|   } | ||||
|   await asyncForEach(inputs.labels, async label => { | ||||
|   await Util.asyncForEach(inputs.labels, async label => { | ||||
|     args.push('--label', label); | ||||
|   }); | ||||
|   await asyncForEach(inputs.noCacheFilters, async noCacheFilter => { | ||||
|   await Util.asyncForEach(inputs.noCacheFilters, async noCacheFilter => { | ||||
|     args.push('--no-cache-filter', noCacheFilter); | ||||
|   }); | ||||
|   await asyncForEach(inputs.outputs, async output => { | ||||
|   await Util.asyncForEach(inputs.outputs, async output => { | ||||
|     args.push('--output', output); | ||||
|   }); | ||||
|   if (inputs.platforms.length > 0) { | ||||
|     args.push('--platform', inputs.platforms.join(',')); | ||||
|   } | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.10.0')) { | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.10.0')) { | ||||
|     if (inputs.provenance) { | ||||
|       args.push('--provenance', inputs.provenance); | ||||
|     } else if ((await buildx.satisfiesBuildKitVersion(inputs.builder, '>=0.11.0', standalone)) && !hasDockerExport(inputs)) { | ||||
|       // If provenance not specified but BuildKit version compatible for | ||||
|       // attestation, disable provenance anyway. Also needs to make sure user | ||||
|     } else if ((await toolkit.buildkit.versionSatisfies(inputs.builder, '>=0.11.0')) && !BuildxInputs.hasDockerExporter(inputs.outputs, inputs.load)) { | ||||
|       // if provenance not specified and BuildKit version compatible for | ||||
|       // attestation, set default provenance. Also needs to make sure user | ||||
|       // doesn't want to explicitly load the image to docker. | ||||
|       // While this action successfully pushes OCI compliant images to | ||||
|       // well-known registries, some runtimes (e.g. Google Cloud Run and AWS | ||||
|       // Lambda) are not able to pull resulting image from their own registry... | ||||
|       // See also https://github.com/docker/buildx/issues/1533 | ||||
|       args.push('--provenance', 'false'); | ||||
|       if (GitHub.context.payload.repository?.private ?? false) { | ||||
|         // if this is a private repository, we set the default provenance | ||||
|         // attributes being set in buildx: https://github.com/docker/buildx/blob/fb27e3f919dcbf614d7126b10c2bc2d0b1927eb6/build/build.go#L603 | ||||
|         args.push('--provenance', BuildxInputs.resolveProvenanceAttrs(`mode=min,inline-only=true`)); | ||||
|       } else { | ||||
|         // for a public repository, we set max provenance mode. | ||||
|         args.push('--provenance', BuildxInputs.resolveProvenanceAttrs(`mode=max`)); | ||||
|       } | ||||
|     } | ||||
|     if (inputs.sbom) { | ||||
|       args.push('--sbom', inputs.sbom); | ||||
|     } | ||||
|   } else if (inputs.provenance || inputs.sbom) { | ||||
|     core.warning("Attestations are only supported by buildx >= 0.10.0; the inputs 'provenance' and 'sbom' are ignored."); | ||||
|   } | ||||
|   await asyncForEach(inputs.secrets, async secret => { | ||||
|   await Util.asyncForEach(inputs.secrets, async secret => { | ||||
|     try { | ||||
|       args.push('--secret', await buildx.getSecretString(secret)); | ||||
|       args.push('--secret', BuildxInputs.resolveBuildSecretString(secret)); | ||||
|     } catch (err) { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   }); | ||||
|   await asyncForEach(inputs.secretFiles, async secretFile => { | ||||
|   await Util.asyncForEach(inputs.secretFiles, async secretFile => { | ||||
|     try { | ||||
|       args.push('--secret', await buildx.getSecretFile(secretFile)); | ||||
|       args.push('--secret', BuildxInputs.resolveBuildSecretFile(secretFile)); | ||||
|     } catch (err) { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   }); | ||||
|   if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && context.startsWith(defaultContext)) { | ||||
|     args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); | ||||
|   if (inputs.githubToken && !BuildxInputs.hasGitAuthTokenSecret(inputs.secrets) && context.startsWith(Context.gitContext())) { | ||||
|     args.push('--secret', BuildxInputs.resolveBuildSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); | ||||
|   } | ||||
|   if (inputs.shmSize) { | ||||
|     args.push('--shm-size', inputs.shmSize); | ||||
|   } | ||||
|   await asyncForEach(inputs.ssh, async ssh => { | ||||
|   await Util.asyncForEach(inputs.ssh, async ssh => { | ||||
|     args.push('--ssh', ssh); | ||||
|   }); | ||||
|   await asyncForEach(inputs.tags, async tag => { | ||||
|   await Util.asyncForEach(inputs.tags, async tag => { | ||||
|     args.push('--tag', tag); | ||||
|   }); | ||||
|   if (inputs.target) { | ||||
|     args.push('--target', inputs.target); | ||||
|   } | ||||
|   await asyncForEach(inputs.ulimit, async ulimit => { | ||||
|   await Util.asyncForEach(inputs.ulimit, async ulimit => { | ||||
|     args.push('--ulimit', ulimit); | ||||
|   }); | ||||
|   return args; | ||||
| } | ||||
|  | ||||
| async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> { | ||||
| async function getCommonArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> { | ||||
|   const args: Array<string> = []; | ||||
|   if (inputs.builder) { | ||||
|     args.push('--builder', inputs.builder); | ||||
| @@ -225,8 +221,8 @@ async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Arr | ||||
|   if (inputs.load) { | ||||
|     args.push('--load'); | ||||
|   } | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.6.0')) { | ||||
|     args.push('--metadata-file', await buildx.getMetadataFile()); | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.6.0')) { | ||||
|     args.push('--metadata-file', BuildxInputs.getBuildMetadataFilePath()); | ||||
|   } | ||||
|   if (inputs.network) { | ||||
|     args.push('--network', inputs.network); | ||||
| @@ -242,99 +238,3 @@ async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Arr | ||||
|   } | ||||
|   return args; | ||||
| } | ||||
|  | ||||
| export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> { | ||||
|   const res: Array<string> = []; | ||||
|  | ||||
|   const items = core.getInput(name); | ||||
|   if (items == '') { | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   const records = await parse(items, { | ||||
|     columns: false, | ||||
|     relaxQuotes: true, | ||||
|     relaxColumnCount: true, | ||||
|     skipEmptyLines: true | ||||
|   }); | ||||
|  | ||||
|   for (const record of records as Array<string[]>) { | ||||
|     if (record.length == 1) { | ||||
|       res.push(record[0]); | ||||
|       continue; | ||||
|     } else if (!ignoreComma) { | ||||
|       res.push(...record); | ||||
|       continue; | ||||
|     } | ||||
|     res.push(record.join(',')); | ||||
|   } | ||||
|  | ||||
|   return res.filter(item => item).map(pat => pat.trim()); | ||||
| } | ||||
|  | ||||
| export const asyncForEach = async (array, callback) => { | ||||
|   for (let index = 0; index < array.length; index++) { | ||||
|     await callback(array[index], index, array); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| function getProvenanceInput(name: string): string { | ||||
|   const input = core.getInput(name); | ||||
|   if (!input) { | ||||
|     // if input is not set, default values will be set later. | ||||
|     return input; | ||||
|   } | ||||
|   const builderID = provenanceBuilderID(); | ||||
|   try { | ||||
|     return core.getBooleanInput(name) ? `builder-id=${builderID}` : 'false'; | ||||
|   } catch (err) { | ||||
|     // not a valid boolean, so we assume it's a string | ||||
|     return getProvenanceAttrs(input); | ||||
|   } | ||||
| } | ||||
|  | ||||
| function getProvenanceAttrs(input: string): string { | ||||
|   const builderID = provenanceBuilderID(); | ||||
|   // parse attributes from input | ||||
|   const fields = parse(input, { | ||||
|     relaxColumnCount: true, | ||||
|     skipEmptyLines: true | ||||
|   })[0]; | ||||
|   // check if builder-id attribute exists in the input | ||||
|   for (const field of fields) { | ||||
|     const parts = field | ||||
|       .toString() | ||||
|       .split(/(?<=^[^=]+?)=/) | ||||
|       .map(item => item.trim()); | ||||
|     if (parts[0] == 'builder-id') { | ||||
|       return input; | ||||
|     } | ||||
|   } | ||||
|   // if not add builder-id attribute | ||||
|   return `${input},builder-id=${builderID}`; | ||||
| } | ||||
|  | ||||
| function hasDockerExport(inputs: Inputs): boolean { | ||||
|   if (inputs.load) { | ||||
|     return true; | ||||
|   } | ||||
|   for (const output of inputs.outputs) { | ||||
|     const fields = parse(output, { | ||||
|       relaxColumnCount: true, | ||||
|       skipEmptyLines: true | ||||
|     })[0]; | ||||
|     for (const field of fields) { | ||||
|       const parts = field | ||||
|         .toString() | ||||
|         .split(/(?<=^[^=]+?)=/) | ||||
|         .map(item => item.trim()); | ||||
|       if (parts.length != 2) { | ||||
|         continue; | ||||
|       } | ||||
|       if (parts[0] == 'type' && parts[1] == 'docker') { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
|   | ||||
| @@ -1,19 +0,0 @@ | ||||
| import * as exec from '@actions/exec'; | ||||
|  | ||||
| export async function isAvailable(): Promise<boolean> { | ||||
|   return await exec | ||||
|     .getExecOutput('docker', undefined, { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         return false; | ||||
|       } | ||||
|       return res.exitCode == 0; | ||||
|     }) | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||||
|     .catch(error => { | ||||
|       return false; | ||||
|     }); | ||||
| } | ||||
| @@ -1,9 +0,0 @@ | ||||
| import jwt_decode, {JwtPayload} from 'jwt-decode'; | ||||
|  | ||||
| interface Jwt extends JwtPayload { | ||||
|   ac?: string; | ||||
| } | ||||
|  | ||||
| export const parseRuntimeToken = (token: string): Jwt => { | ||||
|   return jwt_decode<Jwt>(token); | ||||
| }; | ||||
							
								
								
									
										152
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								src/main.ts
									
									
									
									
									
								
							| @@ -1,71 +1,97 @@ | ||||
| import * as fs from 'fs'; | ||||
| import * as buildx from './buildx'; | ||||
| import * as context from './context'; | ||||
| import * as docker from './docker'; | ||||
| import * as github from './github'; | ||||
| import * as path from 'path'; | ||||
| import * as stateHelper from './state-helper'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as exec from '@actions/exec'; | ||||
| import * as actionsToolkit from '@docker/actions-toolkit'; | ||||
| import {Context} from '@docker/actions-toolkit/lib/context'; | ||||
| import {Docker} from '@docker/actions-toolkit/lib/docker/docker'; | ||||
| import {Exec} from '@docker/actions-toolkit/lib/exec'; | ||||
| import {GitHub} from '@docker/actions-toolkit/lib/github'; | ||||
| import {Inputs as BuildxInputs} from '@docker/actions-toolkit/lib/buildx/inputs'; | ||||
| import {Toolkit} from '@docker/actions-toolkit/lib/toolkit'; | ||||
| import {ConfigFile} from '@docker/actions-toolkit/lib/types/docker'; | ||||
|  | ||||
| async function run(): Promise<void> { | ||||
|   try { | ||||
|     const defContext = context.defaultContext(); | ||||
|     const inputs: context.Inputs = await context.getInputs(defContext); | ||||
| import * as context from './context'; | ||||
|  | ||||
|     // standalone if docker cli not available | ||||
|     const standalone = !(await docker.isAvailable()); | ||||
| actionsToolkit.run( | ||||
|   // main | ||||
|   async () => { | ||||
|     const inputs: context.Inputs = await context.getInputs(); | ||||
|     core.debug(`inputs: ${JSON.stringify(inputs)}`); | ||||
|  | ||||
|     await core.group(`GitHub Actions runtime token access controls`, async () => { | ||||
|       const actionsRuntimeToken = process.env['ACTIONS_RUNTIME_TOKEN']; | ||||
|       if (actionsRuntimeToken) { | ||||
|         core.info(JSON.stringify(JSON.parse(github.parseRuntimeToken(actionsRuntimeToken).ac as string), undefined, 2)); | ||||
|       } else { | ||||
|         core.info(`ACTIONS_RUNTIME_TOKEN not set`); | ||||
|     const toolkit = new Toolkit(); | ||||
|  | ||||
|     await core.group(`GitHub Actions runtime token ACs`, async () => { | ||||
|       try { | ||||
|         await GitHub.printActionsRuntimeTokenACs(); | ||||
|       } catch (e) { | ||||
|         core.warning(e.message); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     core.startGroup(`Docker info`); | ||||
|     if (standalone) { | ||||
|       core.info(`Docker info skipped in standalone mode`); | ||||
|     } else { | ||||
|       await exec.exec('docker', ['version'], { | ||||
|         failOnStdErr: false | ||||
|       }); | ||||
|       await exec.exec('docker', ['info'], { | ||||
|         failOnStdErr: false | ||||
|       }); | ||||
|     } | ||||
|     core.endGroup(); | ||||
|     await core.group(`Docker info`, async () => { | ||||
|       try { | ||||
|         await Docker.printVersion(); | ||||
|         await Docker.printInfo(); | ||||
|       } catch (e) { | ||||
|         core.info(e.message); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     if (!(await buildx.isAvailable(standalone))) { | ||||
|     await core.group(`Proxy configuration`, async () => { | ||||
|       let dockerConfig: ConfigFile | undefined; | ||||
|       let dockerConfigMalformed = false; | ||||
|       try { | ||||
|         dockerConfig = await Docker.configFile(); | ||||
|       } catch (e) { | ||||
|         dockerConfigMalformed = true; | ||||
|         core.warning(`Unable to parse config file ${path.join(Docker.configDir, 'config.json')}: ${e}`); | ||||
|       } | ||||
|       if (dockerConfig && dockerConfig.proxies) { | ||||
|         for (const host in dockerConfig.proxies) { | ||||
|           let prefix = ''; | ||||
|           if (Object.keys(dockerConfig.proxies).length > 1) { | ||||
|             prefix = '  '; | ||||
|             core.info(host); | ||||
|           } | ||||
|           for (const key in dockerConfig.proxies[host]) { | ||||
|             core.info(`${prefix}${key}: ${dockerConfig.proxies[host][key]}`); | ||||
|           } | ||||
|         } | ||||
|       } else if (!dockerConfigMalformed) { | ||||
|         core.info('No proxy configuration found'); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     if (!(await toolkit.buildx.isAvailable())) { | ||||
|       core.setFailed(`Docker buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`); | ||||
|       return; | ||||
|     } | ||||
|     stateHelper.setTmpDir(context.tmpDir()); | ||||
|  | ||||
|     const buildxVersion = await buildx.getVersion(standalone); | ||||
|     stateHelper.setTmpDir(Context.tmpDir()); | ||||
|  | ||||
|     await core.group(`Buildx version`, async () => { | ||||
|       const versionCmd = buildx.getCommand(['version'], standalone); | ||||
|       await exec.exec(versionCmd.command, versionCmd.args, { | ||||
|         failOnStdErr: false | ||||
|       }); | ||||
|       await toolkit.buildx.printVersion(); | ||||
|     }); | ||||
|  | ||||
|     const args: string[] = await context.getArgs(inputs, defContext, buildxVersion, standalone); | ||||
|     const buildCmd = buildx.getCommand(args, standalone); | ||||
|     await exec | ||||
|       .getExecOutput(buildCmd.command, buildCmd.args, { | ||||
|         ignoreReturnCode: true | ||||
|       }) | ||||
|       .then(res => { | ||||
|         if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|           throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`); | ||||
|         } | ||||
|       }); | ||||
|     const args: string[] = await context.getArgs(inputs, toolkit); | ||||
|     core.debug(`context.getArgs: ${JSON.stringify(args)}`); | ||||
|  | ||||
|     const imageID = await buildx.getImageID(); | ||||
|     const metadata = await buildx.getMetadata(); | ||||
|     const digest = await buildx.getDigest(metadata); | ||||
|     const buildCmd = await toolkit.buildx.getCommand(args); | ||||
|     core.debug(`buildCmd.command: ${buildCmd.command}`); | ||||
|     core.debug(`buildCmd.args: ${JSON.stringify(buildCmd.args)}`); | ||||
|  | ||||
|     await Exec.getExecOutput(buildCmd.command, buildCmd.args, { | ||||
|       ignoreReturnCode: true | ||||
|     }).then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     const imageID = BuildxInputs.resolveBuildImageID(); | ||||
|     const metadata = BuildxInputs.resolveBuildMetadata(); | ||||
|     const digest = BuildxInputs.resolveDigest(); | ||||
|  | ||||
|     if (imageID) { | ||||
|       await core.group(`ImageID`, async () => { | ||||
| @@ -85,21 +111,13 @@ async function run(): Promise<void> { | ||||
|         core.setOutput('metadata', metadata); | ||||
|       }); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     core.setFailed(error.message); | ||||
|   }, | ||||
|   // post | ||||
|   async () => { | ||||
|     if (stateHelper.tmpDir.length > 0) { | ||||
|       await core.group(`Removing temp folder ${stateHelper.tmpDir}`, async () => { | ||||
|         fs.rmSync(stateHelper.tmpDir, {recursive: true}); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| async function cleanup(): Promise<void> { | ||||
|   if (stateHelper.tmpDir.length > 0) { | ||||
|     core.startGroup(`Removing temp folder ${stateHelper.tmpDir}`); | ||||
|     fs.rmSync(stateHelper.tmpDir, {recursive: true}); | ||||
|     core.endGroup(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| if (!stateHelper.IsPost) { | ||||
|   run(); | ||||
| } else { | ||||
|   cleanup(); | ||||
| } | ||||
| ); | ||||
|   | ||||
| @@ -1,12 +1,7 @@ | ||||
| import * as core from '@actions/core'; | ||||
|  | ||||
| export const IsPost = !!process.env['STATE_isPost']; | ||||
| export const tmpDir = process.env['STATE_tmpDir'] || ''; | ||||
|  | ||||
| export function setTmpDir(tmpDir: string) { | ||||
|   core.saveState('tmpDir', tmpDir); | ||||
| } | ||||
|  | ||||
| if (!IsPost) { | ||||
|   core.saveState('isPost', 'true'); | ||||
| } | ||||
|   | ||||
| @@ -1,16 +1,19 @@ | ||||
| FROM golang:1.19-alpine AS base | ||||
| # syntax=docker/dockerfile:1 | ||||
|  | ||||
| FROM golang:alpine AS base | ||||
| ENV CGO_ENABLED=0 | ||||
| RUN apk add --no-cache file git | ||||
| WORKDIR /src | ||||
|  | ||||
| FROM base as build | ||||
| COPY go.mod go.sum ./ | ||||
| RUN go mod download -x | ||||
| COPY . . | ||||
| RUN go build -ldflags "-s -w" -o /usr/bin/app . | ||||
| FROM base AS build | ||||
| RUN --mount=type=bind,target=/src \ | ||||
|     --mount=type=cache,target=/root/.cache/go-build \ | ||||
|     go build -ldflags "-s -w" -o /usr/bin/app . | ||||
|  | ||||
| FROM scratch AS binary | ||||
| COPY --from=build /usr/bin/app /bin/app | ||||
|  | ||||
| FROM alpine:3.17 AS image | ||||
| FROM alpine AS image | ||||
| COPY --from=build /usr/bin/app /bin/app | ||||
| EXPOSE 8080 | ||||
| ENTRYPOINT ["/bin/app"] | ||||
|   | ||||
| @@ -1,19 +1,3 @@ | ||||
| module github.com/docker/build-push-action/test/go | ||||
|  | ||||
| go 1.18 | ||||
|  | ||||
| require github.com/labstack/echo/v4 v4.9.1 | ||||
|  | ||||
| require ( | ||||
| 	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect | ||||
| 	github.com/labstack/gommon v0.4.0 // indirect | ||||
| 	github.com/mattn/go-colorable v0.1.11 // indirect | ||||
| 	github.com/mattn/go-isatty v0.0.14 // indirect | ||||
| 	github.com/valyala/bytebufferpool v1.0.0 // indirect | ||||
| 	github.com/valyala/fasttemplate v1.2.1 // indirect | ||||
| 	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect | ||||
| 	golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect | ||||
| 	golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect | ||||
| 	golang.org/x/text v0.3.7 // indirect | ||||
| 	golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect | ||||
| ) | ||||
|   | ||||
| @@ -1,38 +0,0 @@ | ||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= | ||||
| github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= | ||||
| github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y= | ||||
| github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo= | ||||
| github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= | ||||
| github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= | ||||
| github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= | ||||
| github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= | ||||
| github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= | ||||
| github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= | ||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||||
| github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= | ||||
| github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||||
| github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= | ||||
| github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= | ||||
| golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= | ||||
| golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||
| golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY= | ||||
| golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4= | ||||
| golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= | ||||
| golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||||
| golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= | ||||
| golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= | ||||
| gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| @@ -1,31 +1,14 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/labstack/echo/v4" | ||||
| 	"github.com/labstack/echo/v4/middleware" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	e := echo.New() | ||||
|  | ||||
| 	e.Use(middleware.Logger()) | ||||
| 	e.Use(middleware.Recover()) | ||||
|  | ||||
| 	e.GET("/", func(c echo.Context) error { | ||||
| 		return c.HTML(http.StatusOK, "Hello World") | ||||
| 	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		fmt.Fprintf(w, "Hello, Go!") | ||||
| 	}) | ||||
|  | ||||
| 	e.GET("/ping", func(c echo.Context) error { | ||||
| 		return c.JSON(http.StatusOK, struct{ Status string }{Status: "OK"}) | ||||
| 	}) | ||||
|  | ||||
| 	httpPort := os.Getenv("HTTP_PORT") | ||||
| 	if httpPort == "" { | ||||
| 		httpPort = "8080" | ||||
| 	} | ||||
|  | ||||
| 	e.Logger.Fatal(e.Start(":" + httpPort)) | ||||
| 	log.Fatal(http.ListenAndServe(":8080", nil)) | ||||
| } | ||||
|   | ||||
							
								
								
									
										4
									
								
								test/named-context-base.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								test/named-context-base.Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| # syntax=docker/dockerfile:1 | ||||
|  | ||||
| FROM debian | ||||
| RUN echo "Hello debian!" | ||||
| @@ -1,3 +1,4 @@ | ||||
| # syntax=docker/dockerfile:1 | ||||
| 
 | ||||
| FROM alpine | ||||
| RUN cat /etc/*release | ||||
							
								
								
									
										9
									
								
								test/proxy.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/proxy.Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| # syntax=docker/dockerfile:1 | ||||
| FROM alpine | ||||
| RUN apk add --no-cache curl net-tools | ||||
| ARG HTTP_PROXY | ||||
| ARG HTTPS_PROXY | ||||
| RUN printenv HTTP_PROXY | ||||
| RUN printenv HTTPS_PROXY | ||||
| RUN netstat -aptn | ||||
| RUN curl --retry 5 --retry-all-errors --retry-delay 0 --connect-timeout 5 --proxy $HTTP_PROXY -v --insecure --head https://www.google.com | ||||
| @@ -1,19 +1,22 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "esModuleInterop": true, | ||||
|     "target": "es6", | ||||
|     "module": "commonjs", | ||||
|     "strict": true, | ||||
|     "newLine": "lf", | ||||
|     "outDir": "./lib", | ||||
|     "rootDir": "./src", | ||||
|     "esModuleInterop": true, | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "strict": true, | ||||
|     "noImplicitAny": false, | ||||
|     "resolveJsonModule": true, | ||||
|     "useUnknownInCatchVariables": false, | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "./__mocks__/**/*", | ||||
|     "./__tests__/**/*", | ||||
|     "./lib/**/*", | ||||
|     "node_modules", | ||||
|     "**/*.test.ts", | ||||
|     "jest.config.ts" | ||||
|   ] | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user