Compare commits
	
		
			529 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					14487ce63c | ||
| 
						 | 
					0ec91264d8 | ||
| 
						 | 
					b749522b90 | ||
| 
						 | 
					c566248492 | ||
| 
						 | 
					13275dd76e | ||
| 
						 | 
					67dc78bbaf | ||
| 
						 | 
					0760504437 | ||
| 
						 | 
					1c198f4467 | ||
| 
						 | 
					288d9e2e4a | ||
| 
						 | 
					88844b95d8 | ||
| 
						 | 
					1be4244e8d | ||
| 
						 | 
					094d2bc0cd | ||
| 
						 | 
					548776e8d0 | ||
| 
						 | 
					91838c2ba3 | ||
| 
						 | 
					1332e65dc3 | ||
| 
						 | 
					66147ca503 | ||
| 
						 | 
					8ea72f78e8 | ||
| 
						 | 
					6481840af9 | ||
| 
						 | 
					84ad562665 | ||
| 
						 | 
					9bea05fc44 | ||
| 
						 | 
					471d1dc4e0 | ||
| 
						 | 
					b89ff0a6f2 | ||
| 
						 | 
					1e3ae3a4d3 | ||
| 
						 | 
					b16f42f92a | ||
| 
						 | 
					dc0fea5e62 | ||
| 
						 | 
					0adf995921 | ||
| 
						 | 
					d88cd289df | ||
| 
						 | 
					3d09a6bd70 | ||
| 
						 | 
					ca877d9245 | ||
| 
						 | 
					d2fe919bb5 | ||
| 
						 | 
					f0fc9ece82 | ||
| 
						 | 
					67a2d409c0 | ||
| 
						 | 
					0b1b1c9c43 | ||
| 
						 | 
					b6a7c2c4ee | ||
| 
						 | 
					31ca4e5d51 | ||
| 
						 | 
					e613db9d5a | ||
| 
						 | 
					b32b51a8ed | ||
| 
						 | 
					594bf46f0f | ||
| 
						 | 
					fd37bd55af | ||
| 
						 | 
					e6478a2405 | ||
| 
						 | 
					78785bddff | ||
| 
						 | 
					128779fed7 | ||
| 
						 | 
					7e094594be | ||
| 
						 | 
					32ee877a58 | ||
| 
						 | 
					d1a4129c41 | ||
| 
						 | 
					49c623eaf8 | ||
| 
						 | 
					bcc9f4afe7 | ||
| 
						 | 
					da5b6c75b9 | ||
| 
						 | 
					11be14d908 | ||
| 
						 | 
					f5a8591a7f | ||
| 
						 | 
					8796455d32 | ||
| 
						 | 
					750f367828 | ||
| 
						 | 
					48aba3b46d | ||
| 
						 | 
					678328cf8e | ||
| 
						 | 
					cdf0a37e6f | ||
| 
						 | 
					d719b79de1 | ||
| 
						 | 
					c333dfd43d | ||
| 
						 | 
					6b56a4c3f8 | ||
| 
						 | 
					92fb0d73b6 | ||
| 
						 | 
					40532c5d6f | ||
| 
						 | 
					70dd953427 | ||
| 
						 | 
					41b4e8020e | ||
| 
						 | 
					22cd91d73b | ||
| 
						 | 
					6bdcc4fb8c | ||
| 
						 | 
					b5e932e401 | ||
| 
						 | 
					325a8bf0f1 | ||
| 
						 | 
					0259cb088b | ||
| 
						 | 
					1b8e4efb78 | ||
| 
						 | 
					75ffdcce88 | ||
| 
						 | 
					73b7dbf5d4 | ||
| 
						 | 
					f79ca49284 | ||
| 
						 | 
					5e99dacf67 | ||
| 
						 | 
					b249570060 | ||
| 
						 | 
					4f58ea7922 | ||
| 
						 | 
					49b5ea61c6 | ||
| 
						 | 
					13c9fddd72 | ||
| 
						 | 
					e44afff359 | ||
| 
						 | 
					67ebad331f | ||
| 
						 | 
					32945a3392 | ||
| 
						 | 
					e0fe9cf0f2 | ||
| 
						 | 
					8f1ff6bf9a | ||
| 
						 | 
					5cd11c3a4c | ||
| 
						 | 
					0aba704831 | ||
| 
						 | 
					23c657a01f | ||
| 
						 | 
					16ebe778df | ||
| 
						 | 
					646a62b4f2 | ||
| 
						 | 
					d92ab1347f | ||
| 
						 | 
					4f7cdeb0f0 | ||
| 
						 | 
					ad3cd774a4 | ||
| 
						 | 
					3efbc13366 | ||
| 
						 | 
					2dbe91db48 | ||
| 
						 | 
					7de3854c4c | ||
| 
						 | 
					175aa53a3f | ||
| 
						 | 
					806a2a461f | ||
| 
						 | 
					a8d35412fb | ||
| 
						 | 
					1672e74297 | ||
| 
						 | 
					a04f51d3b4 | ||
| 
						 | 
					5176d81f87 | ||
| 
						 | 
					ec10ae8f96 | ||
| 
						 | 
					597e8fc414 | ||
| 
						 | 
					e050dfa622 | ||
| 
						 | 
					d1fcdb6ee0 | ||
| 
						 | 
					a6067b9a1a | ||
| 
						 | 
					1ca370b3a9 | ||
| 
						 | 
					2c95ebed5c | ||
| 
						 | 
					d189d0ef33 | ||
| 
						 | 
					a254f8ca60 | ||
| 
						 | 
					94dae62c78 | ||
| 
						 | 
					267a69d6cc | ||
| 
						 | 
					f23fb2a7cb | ||
| 
						 | 
					ef76d100ee | ||
| 
						 | 
					522345f555 | ||
| 
						 | 
					1a162644f9 | ||
| 
						 | 
					9eea548195 | ||
| 
						 | 
					11c2faaa9e | ||
| 
						 | 
					de2365af33 | ||
| 
						 | 
					bca5082da7 | ||
| 
						 | 
					e7aab408d9 | ||
| 
						 | 
					63eb7590c6 | ||
| 
						 | 
					53ec48606f | ||
| 
						 | 
					fe9d9f1d0c | ||
| 
						 | 
					ad37ba1ad0 | ||
| 
						 | 
					aabbd3f4d7 | ||
| 
						 | 
					9c7c277413 | ||
| 
						 | 
					987902144c | ||
| 
						 | 
					709dde20a7 | ||
| 
						 | 
					ec2d640ea6 | ||
| 
						 | 
					3dc0757c66 | ||
| 
						 | 
					dcb0699155 | ||
| 
						 | 
					a3c06e8698 | ||
| 
						 | 
					e75138d857 | ||
| 
						 | 
					9552610e81 | ||
| 
						 | 
					99c83871c1 | ||
| 
						 | 
					af64c4e18f | ||
| 
						 | 
					6fdff4fb09 | ||
| 
						 | 
					9e59c61762 | ||
| 
						 | 
					49351df2b7 | ||
| 
						 | 
					723ff6ffad | ||
| 
						 | 
					15560696de | ||
| 
						 | 
					57e1d34ac3 | ||
| 
						 | 
					309982ebc9 | ||
| 
						 | 
					9476c25b2a | ||
| 
						 | 
					97be5a4928 | ||
| 
						 | 
					9cac6c8ea0 | ||
| 
						 | 
					31159d49c0 | ||
| 
						 | 
					07e1c3e148 | ||
| 
						 | 
					f7febd621d | ||
| 
						 | 
					f6010ea701 | ||
| 
						 | 
					c0a6b9680f | ||
| 
						 | 
					0dfe9c3d41 | ||
| 
						 | 
					94f8f8c2ee | ||
| 
						 | 
					22f4433c58 | ||
| 
						 | 
					6721c56015 | ||
| 
						 | 
					4367da978b | ||
| 
						 | 
					0883ebe52d | ||
| 
						 | 
					76e5c2d6ea | ||
| 
						 | 
					29d67824d8 | ||
| 
						 | 
					c382f710d3 | ||
| 
						 | 
					5a5b70d974 | ||
| 
						 | 
					dc24cf9e25 | ||
| 
						 | 
					667cb22c52 | ||
| 
						 | 
					d880b1964b | ||
| 
						 | 
					e51051ad0b | ||
| 
						 | 
					86c2bd0031 | ||
| 
						 | 
					268d2b1611 | ||
| 
						 | 
					2b8dc7f529 | ||
| 
						 | 
					840c12be17 | ||
| 
						 | 
					26368743c0 | ||
| 
						 | 
					cfed4e995e | ||
| 
						 | 
					dca03ca8fd | ||
| 
						 | 
					e030091ff4 | ||
| 
						 | 
					84354d3b32 | ||
| 
						 | 
					de5408fe94 | ||
| 
						 | 
					cfc1555281 | ||
| 
						 | 
					f6a172d30e | ||
| 
						 | 
					ca052bb54a | ||
| 
						 | 
					025c2051f3 | ||
| 
						 | 
					12076d2fb1 | ||
| 
						 | 
					ef6cba3353 | ||
| 
						 | 
					4c16cf906a | ||
| 
						 | 
					a3118a86c8 | ||
| 
						 | 
					c86eb8b0f7 | ||
| 
						 | 
					2a53c6ccda | ||
| 
						 | 
					ccef1f210d | ||
| 
						 | 
					79117b6ea5 | ||
| 
						 | 
					df19a799eb | ||
| 
						 | 
					0e2ab16cd2 | ||
| 
						 | 
					54d0f58d64 | ||
| 
						 | 
					563a2f55e4 | ||
| 
						 | 
					6003d3266a | ||
| 
						 | 
					e1e22cdde8 | ||
| 
						 | 
					fc15b64049 | ||
| 
						 | 
					6c58ea3670 | ||
| 
						 | 
					729f7f4926 | ||
| 
						 | 
					99d83235bc | ||
| 
						 | 
					1d5307d7af | ||
| 
						 | 
					cf8d130912 | ||
| 
						 | 
					8804d8e2ac | ||
| 
						 | 
					1984549052 | ||
| 
						 | 
					5bc9e2e9b9 | ||
| 
						 | 
					eb539f44b1 | ||
| 
						 | 
					b6ff9e5753 | ||
| 
						 | 
					929fba6cce | ||
| 
						 | 
					7f1f43ba33 | ||
| 
						 | 
					40d6a900e0 | ||
| 
						 | 
					d56be63626 | ||
| 
						 | 
					eb3cfeaf00 | ||
| 
						 | 
					d0fc12d8a4 | ||
| 
						 | 
					68615d5b67 | ||
| 
						 | 
					c3b570184c | ||
| 
						 | 
					7e6f77677b | ||
| 
						 | 
					2ce6beaad4 | ||
| 
						 | 
					4c8d1e6826 | ||
| 
						 | 
					b0312962ef | ||
| 
						 | 
					96acf63e4c | ||
| 
						 | 
					f8bc7f4600 | ||
| 
						 | 
					c2064be02c | ||
| 
						 | 
					4f02f34098 | ||
| 
						 | 
					090ca155fc | ||
| 
						 | 
					ec4854f780 | ||
| 
						 | 
					2cdde995de | ||
| 
						 | 
					008747aa03 | ||
| 
						 | 
					1580753126 | ||
| 
						 | 
					2a7db1d68a | ||
| 
						 | 
					35e7dd5921 | ||
| 
						 | 
					af5a7ed5ba | ||
| 
						 | 
					2a85189a6c | ||
| 
						 | 
					6c2079483e | ||
| 
						 | 
					afdf0c0a67 | ||
| 
						 | 
					00ae31ab6e | ||
| 
						 | 
					701942b6e5 | ||
| 
						 | 
					90e54d0b1d | ||
| 
						 | 
					831ca179d3 | ||
| 
						 | 
					6bd0e5492f | ||
| 
						 | 
					b3eddbb94c | ||
| 
						 | 
					ffd798c1f1 | ||
| 
						 | 
					62d8db0960 | ||
| 
						 | 
					8ab81cb898 | ||
| 
						 | 
					d47e7c357d | ||
| 
						 | 
					4976231911 | ||
| 
						 | 
					d236adc992 | ||
| 
						 | 
					94d76d3bc1 | ||
| 
						 | 
					2b28f2a854 | ||
| 
						 | 
					9f6f8c940b | ||
| 
						 | 
					8411d080ee | ||
| 
						 | 
					4a13e500e5 | ||
| 
						 | 
					7416668686 | ||
| 
						 | 
					b4f76a5dc6 | ||
| 
						 | 
					b7feb766fa | ||
| 
						 | 
					fae8018297 | ||
| 
						 | 
					b625868b13 | ||
| 
						 | 
					5193ef1da6 | ||
| 
						 | 
					d3afd779e4 | ||
| 
						 | 
					7a786bb2b9 | ||
| 
						 | 
					c66ae3adcf | ||
| 
						 | 
					248131c7bf | ||
| 
						 | 
					b425c4cd5a | ||
| 
						 | 
					9834ce5b4d | ||
| 
						 | 
					fdf7f43ecf | ||
| 
						 | 
					e3a4c332fb | ||
| 
						 | 
					c48d200483 | ||
| 
						 | 
					8d2cf95286 | ||
| 
						 | 
					3c7915695f | ||
| 
						 | 
					0a283b683f | ||
| 
						 | 
					c544b50d70 | ||
| 
						 | 
					dd31262fa7 | ||
| 
						 | 
					5f01267817 | ||
| 
						 | 
					0f847266c3 | ||
| 
						 | 
					ea8499618b | ||
| 
						 | 
					4c1b68d83a | ||
| 
						 | 
					5909c5bffe | ||
| 
						 | 
					285730d174 | ||
| 
						 | 
					4bbe0177ef | ||
| 
						 | 
					cc4d1d4d5f | ||
| 
						 | 
					e7d3750abc | ||
| 
						 | 
					4556201a14 | ||
| 
						 | 
					9fa62cfa91 | ||
| 
						 | 
					8026f009fc | ||
| 
						 | 
					6b35a7a7f1 | ||
| 
						 | 
					c6e64b478a | ||
| 
						 | 
					e2505c6383 | ||
| 
						 | 
					0565240e2d | ||
| 
						 | 
					3ab07f8801 | ||
| 
						 | 
					b9e7e4daec | ||
| 
						 | 
					04d1a3b049 | ||
| 
						 | 
					1a4d1a13fb | ||
| 
						 | 
					675965c0e1 | ||
| 
						 | 
					58ee34cb6b | ||
| 
						 | 
					c97c4060bd | ||
| 
						 | 
					47d5369e0b | ||
| 
						 | 
					8895c7468f | ||
| 
						 | 
					59ba712c53 | ||
| 
						 | 
					0c20fff10d | ||
| 
						 | 
					0a97817b6a | ||
| 
						 | 
					ec39ef320c | ||
| 
						 | 
					f46044b799 | ||
| 
						 | 
					4e4ee680f6 | ||
| 
						 | 
					e86cf554b6 | ||
| 
						 | 
					daa0106f78 | ||
| 
						 | 
					ce51e905a6 | ||
| 
						 | 
					1fde16337d | ||
| 
						 | 
					ae311c520f | ||
| 
						 | 
					9311bf5263 | ||
| 
						 | 
					b1654941ef | ||
| 
						 | 
					12a9f89349 | ||
| 
						 | 
					2036a561be | ||
| 
						 | 
					b1d46f11a2 | ||
| 
						 | 
					e5b2fc7017 | ||
| 
						 | 
					24216ba114 | ||
| 
						 | 
					eb33afda71 | ||
| 
						 | 
					9407ba1305 | ||
| 
						 | 
					429cdb70ad | ||
| 
						 | 
					74a34eff3a | ||
| 
						 | 
					6787bde0a6 | ||
| 
						 | 
					56932deb0a | ||
| 
						 | 
					0681013357 | ||
| 
						 | 
					be4bf1099e | ||
| 
						 | 
					9ec154c4b6 | ||
| 
						 | 
					380260b6c7 | ||
| 
						 | 
					ac790be09a | ||
| 
						 | 
					dc0a85b056 | ||
| 
						 | 
					aca01f02d5 | ||
| 
						 | 
					4b0752a2b1 | ||
| 
						 | 
					be06a9da57 | ||
| 
						 | 
					19184b90ca | ||
| 
						 | 
					57e90a56ab | ||
| 
						 | 
					4fad532b9f | ||
| 
						 | 
					413aee355f | ||
| 
						 | 
					f05b754b57 | ||
| 
						 | 
					2f3765570b | ||
| 
						 | 
					68d0dc20df | ||
| 
						 | 
					1fd7f72e60 | ||
| 
						 | 
					ea907fb0a4 | ||
| 
						 | 
					2eb1c1961a | ||
| 
						 | 
					27376fe2fc | ||
| 
						 | 
					c9330004c2 | ||
| 
						 | 
					dac08d41ad | ||
| 
						 | 
					44ea916f6c | ||
| 
						 | 
					0167eef179 | ||
| 
						 | 
					91bf8bfc4d | ||
| 
						 | 
					a799b4decf | ||
| 
						 | 
					87480bdf69 | ||
| 
						 | 
					f9efed53cc | ||
| 
						 | 
					3580b78e04 | ||
| 
						 | 
					91df6b874e | ||
| 
						 | 
					ea92b18afb | ||
| 
						 | 
					6f91eb31f7 | ||
| 
						 | 
					eafaea8d0f | ||
| 
						 | 
					ddd2a92197 | ||
| 
						 | 
					a54198e85a | ||
| 
						 | 
					7e3a79c50d | ||
| 
						 | 
					4a730ce64b | ||
| 
						 | 
					817ed59f97 | ||
| 
						 | 
					a3646c08f8 | ||
| 
						 | 
					5c3465b033 | ||
| 
						 | 
					e9c0697e5b | ||
| 
						 | 
					e090350180 | ||
| 
						 | 
					f2a1d5e99d | ||
| 
						 | 
					81f5252b54 | ||
| 
						 | 
					b3435979d1 | ||
| 
						 | 
					80def7c74e | ||
| 
						 | 
					35434f557a | ||
| 
						 | 
					d63c96254b | ||
| 
						 | 
					21fe05ff59 | ||
| 
						 | 
					097a3e23ac | ||
| 
						 | 
					d8823bfaed | ||
| 
						 | 
					3a3620ed49 | ||
| 
						 | 
					8082ebc6ea | ||
| 
						 | 
					a3ae207c14 | ||
| 
						 | 
					4858a31f84 | ||
| 
						 | 
					d10433366f | ||
| 
						 | 
					ee5cabd9e3 | ||
| 
						 | 
					7944f9a25b | ||
| 
						 | 
					c088e12d82 | ||
| 
						 | 
					e941dc0149 | ||
| 
						 | 
					0d6f3e8936 | ||
| 
						 | 
					c779d8500d | ||
| 
						 | 
					b651cf69a6 | ||
| 
						 | 
					0db6129a57 | ||
| 
						 | 
					70cc701b9c | ||
| 
						 | 
					af7537dc3e | ||
| 
						 | 
					2d8166c4b9 | ||
| 
						 | 
					6a8fbf0dbc | ||
| 
						 | 
					f74fd039f3 | ||
| 
						 | 
					695ee8547d | ||
| 
						 | 
					fd7264830a | ||
| 
						 | 
					6842956e83 | ||
| 
						 | 
					9d1b8fa4e2 | ||
| 
						 | 
					17c742ea85 | ||
| 
						 | 
					916f6873ae | ||
| 
						 | 
					a3f7a443f9 | ||
| 
						 | 
					05e89e68aa | ||
| 
						 | 
					d16cc0b66f | ||
| 
						 | 
					306a0a9f50 | ||
| 
						 | 
					55a3485913 | ||
| 
						 | 
					71e9aaaf29 | ||
| 
						 | 
					3b5e8027fc | ||
| 
						 | 
					02d3266a89 | ||
| 
						 | 
					f403dafe18 | ||
| 
						 | 
					1104d47137 | ||
| 
						 | 
					838bf90c88 | ||
| 
						 | 
					337a09d182 | ||
| 
						 | 
					37abcedcc1 | ||
| 
						 | 
					67109bc4b2 | ||
| 
						 | 
					d1b0eb0a29 | ||
| 
						 | 
					a0635fe7cd | ||
| 
						 | 
					f834265449 | ||
| 
						 | 
					0191543e0b | ||
| 
						 | 
					2a16835223 | ||
| 
						 | 
					9b96801525 | ||
| 
						 | 
					6afac853c9 | ||
| 
						 | 
					3bfdd83cd7 | ||
| 
						 | 
					316d5eb8b3 | ||
| 
						 | 
					1d910c8aa2 | ||
| 
						 | 
					f9ccca010f | ||
| 
						 | 
					c40bf0fdf6 | ||
| 
						 | 
					223ed1ebd4 | ||
| 
						 | 
					fdafae777b | ||
| 
						 | 
					0cb700ffba | ||
| 
						 | 
					ee7989df81 | ||
| 
						 | 
					74f883a069 | ||
| 
						 | 
					0149503e26 | ||
| 
						 | 
					26ce4f3617 | ||
| 
						 | 
					ed2672fc33 | ||
| 
						 | 
					472ccddef1 | ||
| 
						 | 
					d235d2d5ea | ||
| 
						 | 
					2f519a7883 | ||
| 
						 | 
					4eb68bb2ac | ||
| 
						 | 
					b4755849f0 | ||
| 
						 | 
					ade1a6afe3 | ||
| 
						 | 
					21d6059e1e | ||
| 
						 | 
					c2c50190db | ||
| 
						 | 
					a154a68da0 | ||
| 
						 | 
					4ac90f5dca | ||
| 
						 | 
					175d02bffe | ||
| 
						 | 
					546378e7fb | ||
| 
						 | 
					ffe65bfc27 | ||
| 
						 | 
					d4c14fd006 | ||
| 
						 | 
					6e95f19fb8 | ||
| 
						 | 
					2a752d5a63 | ||
| 
						 | 
					c56af95754 | ||
| 
						 | 
					75aaa63262 | ||
| 
						 | 
					f97d6e2850 | ||
| 
						 | 
					47c00d78bf | ||
| 
						 | 
					871b930e7a | ||
| 
						 | 
					105bf59b00 | ||
| 
						 | 
					48888e0b13 | ||
| 
						 | 
					6b820ad47e | ||
| 
						 | 
					e1a10350ee | ||
| 
						 | 
					0f5a7d48d5 | ||
| 
						 | 
					6a6e8c7c14 | ||
| 
						 | 
					e189a1cb78 | ||
| 
						 | 
					2cf0d6fbdc | ||
| 
						 | 
					3cde535b0c | ||
| 
						 | 
					83a00fb5e6 | ||
| 
						 | 
					1d5915004a | ||
| 
						 | 
					2e87529dad | ||
| 
						 | 
					e27bcee4eb | ||
| 
						 | 
					71d260c49a | ||
| 
						 | 
					965c6a410d | ||
| 
						 | 
					08aa123a28 | ||
| 
						 | 
					1527803881 | ||
| 
						 | 
					a49d9ab751 | ||
| 
						 | 
					cbb574ee73 | ||
| 
						 | 
					8b56e74b48 | ||
| 
						 | 
					a5024d816a | ||
| 
						 | 
					2235b57edd | ||
| 
						 | 
					15b9e74b95 | ||
| 
						 | 
					48daa618bd | ||
| 
						 | 
					c84f382811 | ||
| 
						 | 
					cd5d0b79ea | ||
| 
						 | 
					30a32246ba | ||
| 
						 | 
					1f19633b92 | ||
| 
						 | 
					67af6dc1d3 | ||
| 
						 | 
					988cb093f2 | ||
| 
						 | 
					1cb9d22b93 | ||
| 
						 | 
					5ffbca1432 | ||
| 
						 | 
					a8d76c070a | ||
| 
						 | 
					12b1e419c2 | ||
| 
						 | 
					2a60beff0d | ||
| 
						 | 
					5268745b5f | ||
| 
						 | 
					a2a27346c0 | ||
| 
						 | 
					05d9e522ae | ||
| 
						 | 
					42863b1282 | ||
| 
						 | 
					c372f73edc | ||
| 
						 | 
					d17cab8f42 | ||
| 
						 | 
					4c2810ab91 | ||
| 
						 | 
					307a009589 | ||
| 
						 | 
					f2c26aa560 | ||
| 
						 | 
					a806b8fe18 | ||
| 
						 | 
					ae74c4950a | ||
| 
						 | 
					80c878df65 | ||
| 
						 | 
					a571ccfa72 | ||
| 
						 | 
					283625c36b | ||
| 
						 | 
					bb751c2095 | ||
| 
						 | 
					8d9444d675 | ||
| 
						 | 
					c5e6528d5d | ||
| 
						 | 
					ceb414dc73 | ||
| 
						 | 
					dda70725ed | ||
| 
						 | 
					e551b19e49 | ||
| 
						 | 
					3554377aa3 | ||
| 
						 | 
					a62bc1b22b | ||
| 
						 | 
					c2085839e1 | ||
| 
						 | 
					fcd91249e5 | ||
| 
						 | 
					0ebe720aed | ||
| 
						 | 
					38b45804b5 | ||
| 
						 | 
					ba317382dc | ||
| 
						 | 
					43721d2346 | ||
| 
						 | 
					5ea21bf2ba | ||
| 
						 | 
					300b1bdff7 | ||
| 
						 | 
					84580d7737 | ||
| 
						 | 
					a460b5e683 | ||
| 
						 | 
					9f1392c9bf | ||
| 
						 | 
					9472e90210 | ||
| 
						 | 
					5accc8e023 | ||
| 
						 | 
					f7a2a67b4c | ||
| 
						 | 
					b905f177bc | ||
| 
						 | 
					0779722168 | ||
| 
						 | 
					fd75456293 | ||
| 
						 | 
					ada965aa7b | ||
| 
						 | 
					b5730d2471 | ||
| 
						 | 
					839389a46c | ||
| 
						 | 
					34c1caa1ce | ||
| 
						 | 
					6ff230f13e | ||
| 
						 | 
					75c825aabc | ||
| 
						 | 
					5f7b938b8c | ||
| 
						 | 
					7ae34a20f3 | ||
| 
						 | 
					acb76cdd52 | ||
| 
						 | 
					2d081a4fd5 | 
@ -1,2 +1,12 @@
 | 
			
		||||
/coverage
 | 
			
		||||
/node_modules
 | 
			
		||||
 | 
			
		||||
# Dependency directories
 | 
			
		||||
node_modules/
 | 
			
		||||
jspm_packages/
 | 
			
		||||
 | 
			
		||||
# yarn v2
 | 
			
		||||
.yarn/cache
 | 
			
		||||
.yarn/unplugged
 | 
			
		||||
.yarn/build-state.yml
 | 
			
		||||
.yarn/install-state.gz
 | 
			
		||||
.pnp.*
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
/dist/**
 | 
			
		||||
/coverage/**
 | 
			
		||||
/node_modules/**
 | 
			
		||||
							
								
								
									
										24
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
{
 | 
			
		||||
  "env": {
 | 
			
		||||
    "node": true,
 | 
			
		||||
    "es6": true,
 | 
			
		||||
    "jest": true
 | 
			
		||||
  },
 | 
			
		||||
  "extends": [
 | 
			
		||||
    "eslint:recommended",
 | 
			
		||||
    "plugin:@typescript-eslint/eslint-recommended",
 | 
			
		||||
    "plugin:@typescript-eslint/recommended",
 | 
			
		||||
    "plugin:jest/recommended",
 | 
			
		||||
    "plugin:prettier/recommended"
 | 
			
		||||
  ],
 | 
			
		||||
  "parser": "@typescript-eslint/parser",
 | 
			
		||||
  "parserOptions": {
 | 
			
		||||
    "ecmaVersion": 2023,
 | 
			
		||||
    "sourceType": "module"
 | 
			
		||||
  },
 | 
			
		||||
  "plugins": [
 | 
			
		||||
    "@typescript-eslint",
 | 
			
		||||
    "jest",
 | 
			
		||||
    "prettier"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@ -1,2 +1,4 @@
 | 
			
		||||
/.yarn/releases/** binary
 | 
			
		||||
/.yarn/plugins/** binary
 | 
			
		||||
/dist/** linguist-generated=true
 | 
			
		||||
/lib/** linguist-generated=true
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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.
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								.github/build-push-summary.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								.github/build-push-summary.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 81 KiB  | 
							
								
								
									
										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::"
 | 
			
		||||
							
								
								
									
										134
									
								
								.github/workflows/.e2e-run.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								.github/workflows/.e2e-run.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,134 @@
 | 
			
		||||
# 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: edge
 | 
			
		||||
            buildkit_image: moby/buildkit:latest
 | 
			
		||||
          -
 | 
			
		||||
            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 '{}' | sudo 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
 | 
			
		||||
          cat /etc/docker/daemon.json
 | 
			
		||||
          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 }}
 | 
			
		||||
          buildkitd-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 .}}'
 | 
			
		||||
							
								
								
									
										1283
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1283
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										104
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										104
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							@ -1,5 +1,9 @@
 | 
			
		||||
name: e2e
 | 
			
		||||
 | 
			
		||||
concurrency:
 | 
			
		||||
  group: ${{ github.workflow }}-${{ github.ref }}
 | 
			
		||||
  cancel-in-progress: true
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
  schedule:
 | 
			
		||||
@ -8,103 +12,103 @@ on:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'master'
 | 
			
		||||
    tags:
 | 
			
		||||
      - v*
 | 
			
		||||
      - '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:
 | 
			
		||||
            type: remote
 | 
			
		||||
          -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
            name: Quay
 | 
			
		||||
            registry: quay.io
 | 
			
		||||
            slug: quay.io/docker_build_team/ghactiontest
 | 
			
		||||
            username_secret: QUAY_USERNAME
 | 
			
		||||
            password_secret: QUAY_TOKEN
 | 
			
		||||
            type: remote
 | 
			
		||||
          -
 | 
			
		||||
        name: Docker meta
 | 
			
		||||
        id: meta
 | 
			
		||||
        uses: docker/metadata-action@v3
 | 
			
		||||
        with:
 | 
			
		||||
          images: ${{ matrix.slug }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to Registry
 | 
			
		||||
        if: github.event_name != 'pull_request'
 | 
			
		||||
        uses: docker/login-action@v1
 | 
			
		||||
            name: Artifactory
 | 
			
		||||
            registry: infradock.jfrog.io
 | 
			
		||||
            slug: infradock.jfrog.io/test-ghaction/build-push-action
 | 
			
		||||
            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 }}
 | 
			
		||||
          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 }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Dump context
 | 
			
		||||
        if: always()
 | 
			
		||||
        uses: crazy-max/ghaction-dump-context@v1
 | 
			
		||||
      slug: ${{ matrix.slug }}
 | 
			
		||||
      username_secret: ${{ matrix.username_secret }}
 | 
			
		||||
      password_secret: ${{ matrix.password_secret }}
 | 
			
		||||
    secrets: inherit
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										78
									
								
								.github/workflows/example.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								.github/workflows/example.yml
									
									
									
									
										vendored
									
									
								
							@ -1,78 +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@v3
 | 
			
		||||
        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@v1
 | 
			
		||||
        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 }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Dump context
 | 
			
		||||
        if: always()
 | 
			
		||||
        uses: crazy-max/ghaction-dump-context@v1
 | 
			
		||||
							
								
								
									
										17
									
								
								.github/workflows/pr-assign-author.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.github/workflows/pr-assign-author.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
name: pr-assign-author
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  pull_request_target:
 | 
			
		||||
    types:
 | 
			
		||||
      - opened
 | 
			
		||||
      - reopened
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  run:
 | 
			
		||||
    uses: crazy-max/.github/.github/workflows/pr-assign-author.yml@1b673f36fad86812f538c1df9794904038a23cbf
 | 
			
		||||
    permissions:
 | 
			
		||||
      contents: read
 | 
			
		||||
      pull-requests: write
 | 
			
		||||
							
								
								
									
										21
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
name: publish
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  release:
 | 
			
		||||
    types:
 | 
			
		||||
      - published
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  publish:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    permissions:
 | 
			
		||||
      contents: read
 | 
			
		||||
      id-token: write
 | 
			
		||||
      packages: write
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
      -
 | 
			
		||||
        name: Publish
 | 
			
		||||
        uses: actions/publish-immutable-action@v0.0.4
 | 
			
		||||
							
								
								
									
										22
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								.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,16 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
      -
 | 
			
		||||
        name: Validate
 | 
			
		||||
        uses: docker/bake-action@v1
 | 
			
		||||
        with:
 | 
			
		||||
          targets: validate
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
      -
 | 
			
		||||
        name: Test
 | 
			
		||||
        uses: docker/bake-action@v1
 | 
			
		||||
        uses: docker/bake-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          source: .
 | 
			
		||||
          targets: test
 | 
			
		||||
      -
 | 
			
		||||
        name: Upload coverage
 | 
			
		||||
        uses: codecov/codecov-action@v2
 | 
			
		||||
        uses: codecov/codecov-action@v5
 | 
			
		||||
        with:
 | 
			
		||||
          file: ./coverage/clover.xml
 | 
			
		||||
          files: ./coverage/clover.xml
 | 
			
		||||
          token: ${{ secrets.CODECOV_TOKEN }}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								.github/workflows/validate.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/validate.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
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.generate.outputs.targets }}
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
      -
 | 
			
		||||
        name: List targets
 | 
			
		||||
        id: generate
 | 
			
		||||
        uses: docker/bake-action/subaction/list-targets@v6
 | 
			
		||||
        with:
 | 
			
		||||
          target: validate
 | 
			
		||||
 | 
			
		||||
  validate:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    needs:
 | 
			
		||||
      - prepare
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        target: ${{ fromJson(needs.prepare.outputs.targets) }}
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Validate
 | 
			
		||||
        uses: docker/bake-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          targets: ${{ matrix.target }}
 | 
			
		||||
							
								
								
									
										43
									
								
								.github/workflows/virtual-env.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/virtual-env.yml
									
									
									
									
										vendored
									
									
								
							@ -1,43 +0,0 @@
 | 
			
		||||
name: virtual-env
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '0 10 * * *'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  os:
 | 
			
		||||
    runs-on: ${{ matrix.os }}
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        os:
 | 
			
		||||
          - ubuntu-latest
 | 
			
		||||
          - ubuntu-20.04
 | 
			
		||||
          - ubuntu-18.04
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: File system
 | 
			
		||||
        run: df -ah
 | 
			
		||||
      -
 | 
			
		||||
        name: List install packages
 | 
			
		||||
        run: apt list --installed
 | 
			
		||||
      -
 | 
			
		||||
        name: Docker info
 | 
			
		||||
        run: docker info
 | 
			
		||||
      -
 | 
			
		||||
        name: Docker version
 | 
			
		||||
        run: docker version
 | 
			
		||||
      -
 | 
			
		||||
        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
 | 
			
		||||
							
								
								
									
										70
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,11 +1,5 @@
 | 
			
		||||
node_modules
 | 
			
		||||
lib
 | 
			
		||||
# https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
 | 
			
		||||
 | 
			
		||||
# Jetbrains
 | 
			
		||||
/.idea
 | 
			
		||||
/*.iml
 | 
			
		||||
 | 
			
		||||
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
 | 
			
		||||
# Logs
 | 
			
		||||
logs
 | 
			
		||||
*.log
 | 
			
		||||
@ -13,6 +7,7 @@ npm-debug.log*
 | 
			
		||||
yarn-debug.log*
 | 
			
		||||
yarn-error.log*
 | 
			
		||||
lerna-debug.log*
 | 
			
		||||
.pnpm-debug.log*
 | 
			
		||||
 | 
			
		||||
# Diagnostic reports (https://nodejs.org/api/report.html)
 | 
			
		||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
 | 
			
		||||
@ -23,34 +18,14 @@ pids
 | 
			
		||||
*.seed
 | 
			
		||||
*.pid.lock
 | 
			
		||||
 | 
			
		||||
# Directory for instrumented libs generated by jscoverage/JSCover
 | 
			
		||||
lib-cov
 | 
			
		||||
 | 
			
		||||
# Coverage directory used by tools like istanbul
 | 
			
		||||
coverage
 | 
			
		||||
*.lcov
 | 
			
		||||
 | 
			
		||||
# nyc test coverage
 | 
			
		||||
.nyc_output
 | 
			
		||||
 | 
			
		||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
 | 
			
		||||
.grunt
 | 
			
		||||
 | 
			
		||||
# Bower dependency directory (https://bower.io/)
 | 
			
		||||
bower_components
 | 
			
		||||
 | 
			
		||||
# node-waf configuration
 | 
			
		||||
.lock-wscript
 | 
			
		||||
 | 
			
		||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
 | 
			
		||||
build/Release
 | 
			
		||||
 | 
			
		||||
# Dependency directories
 | 
			
		||||
node_modules/
 | 
			
		||||
jspm_packages/
 | 
			
		||||
 | 
			
		||||
# TypeScript v1 declaration files
 | 
			
		||||
typings/
 | 
			
		||||
 | 
			
		||||
# TypeScript cache
 | 
			
		||||
*.tsbuildinfo
 | 
			
		||||
 | 
			
		||||
@ -60,36 +35,19 @@ typings/
 | 
			
		||||
# Optional eslint cache
 | 
			
		||||
.eslintcache
 | 
			
		||||
 | 
			
		||||
# Optional REPL history
 | 
			
		||||
.node_repl_history
 | 
			
		||||
 | 
			
		||||
# Output of 'npm pack'
 | 
			
		||||
*.tgz
 | 
			
		||||
 | 
			
		||||
# Yarn Integrity file
 | 
			
		||||
.yarn-integrity
 | 
			
		||||
 | 
			
		||||
# dotenv environment variables file
 | 
			
		||||
# dotenv environment variable files
 | 
			
		||||
.env
 | 
			
		||||
.env.test
 | 
			
		||||
.env.development.local
 | 
			
		||||
.env.test.local
 | 
			
		||||
.env.production.local
 | 
			
		||||
.env.local
 | 
			
		||||
 | 
			
		||||
# parcel-bundler cache (https://parceljs.org/)
 | 
			
		||||
.cache
 | 
			
		||||
 | 
			
		||||
# next.js build output
 | 
			
		||||
.next
 | 
			
		||||
 | 
			
		||||
# nuxt.js build output
 | 
			
		||||
.nuxt
 | 
			
		||||
 | 
			
		||||
# vuepress build output
 | 
			
		||||
.vuepress/dist
 | 
			
		||||
 | 
			
		||||
# Serverless directories
 | 
			
		||||
.serverless/
 | 
			
		||||
 | 
			
		||||
# FuseBox cache
 | 
			
		||||
.fusebox/
 | 
			
		||||
 | 
			
		||||
# DynamoDB Local files
 | 
			
		||||
.dynamodb/
 | 
			
		||||
# yarn v2
 | 
			
		||||
.yarn/cache
 | 
			
		||||
.yarn/unplugged
 | 
			
		||||
.yarn/build-state.yml
 | 
			
		||||
.yarn/install-state.gz
 | 
			
		||||
.pnp.*
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
# Dependency directories
 | 
			
		||||
node_modules/
 | 
			
		||||
jspm_packages/
 | 
			
		||||
 | 
			
		||||
# yarn v2
 | 
			
		||||
.yarn/
 | 
			
		||||
							
								
								
									
										541
									
								
								.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										541
									
								
								.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										13
									
								
								.yarnrc.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.yarnrc.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
logFilters:
 | 
			
		||||
  - code: YN0013
 | 
			
		||||
    level: discard
 | 
			
		||||
  - code: YN0019
 | 
			
		||||
    level: discard
 | 
			
		||||
  - code: YN0076
 | 
			
		||||
    level: discard
 | 
			
		||||
 | 
			
		||||
nodeLinker: node-modules
 | 
			
		||||
 | 
			
		||||
plugins:
 | 
			
		||||
  - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
 | 
			
		||||
    spec: "@yarnpkg/plugin-interactive-tools"
 | 
			
		||||
							
								
								
									
										241
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										241
									
								
								README.md
									
									
									
									
									
								
							@ -1,14 +1,15 @@
 | 
			
		||||
[](https://github.com/docker/build-push-action/releases/latest)
 | 
			
		||||
[](https://github.com/marketplace/actions/build-and-push-docker-images)
 | 
			
		||||
[](https://github.com/docker/build-push-action/actions?workflow=ci)
 | 
			
		||||
[](https://github.com/docker/build-push-action/actions?workflow=test)
 | 
			
		||||
[](https://github.com/docker/build-push-action/actions?workflow=ci)
 | 
			
		||||
[](https://github.com/docker/build-push-action/actions?workflow=test)
 | 
			
		||||
[](https://codecov.io/gh/docker/build-push-action)
 | 
			
		||||
 | 
			
		||||
## About
 | 
			
		||||
 | 
			
		||||
GitHub Action to build and push Docker images with [Buildx](https://github.com/docker/buildx) with full support of the
 | 
			
		||||
features provided by [Moby BuildKit](https://github.com/moby/buildkit) builder toolkit. This includes multi-platform
 | 
			
		||||
build, secrets, remote cache, etc. and different builder deployment/namespacing options.
 | 
			
		||||
GitHub Action to build and push Docker images with [Buildx](https://github.com/docker/buildx)
 | 
			
		||||
with full support of the features provided by [Moby BuildKit](https://github.com/moby/buildkit)
 | 
			
		||||
builder toolkit. This includes multi-platform build, secrets, remote cache, etc.
 | 
			
		||||
and different builder deployment/namespacing options.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
@ -17,43 +18,36 @@ ___
 | 
			
		||||
* [Usage](#usage)
 | 
			
		||||
  * [Git context](#git-context)
 | 
			
		||||
  * [Path context](#path-context)
 | 
			
		||||
* [Advanced usage](#advanced-usage)
 | 
			
		||||
  * [Multi-platform image](docs/advanced/multi-platform.md)
 | 
			
		||||
  * [Secrets](docs/advanced/secrets.md)
 | 
			
		||||
  * [Isolated builders](docs/advanced/isolated-builders.md)
 | 
			
		||||
  * [Push to multi-registries](docs/advanced/push-multi-registries.md)
 | 
			
		||||
  * [Copy between registries](docs/advanced/copy-between-registries.md)  
 | 
			
		||||
  * [Cache](docs/advanced/cache.md)
 | 
			
		||||
  * [Local registry](docs/advanced/local-registry.md)
 | 
			
		||||
  * [Export image to Docker](docs/advanced/export-docker.md)
 | 
			
		||||
  * [Share built image between jobs](docs/advanced/share-image-jobs.md)
 | 
			
		||||
  * [Test your image before pushing it](docs/advanced/test-before-push.md)
 | 
			
		||||
  * [Handle tags and labels](docs/advanced/tags-labels.md)
 | 
			
		||||
  * [Update DockerHub repo description](docs/advanced/dockerhub-desc.md)
 | 
			
		||||
* [Examples](#examples)
 | 
			
		||||
* [Summaries](#summaries)
 | 
			
		||||
* [Customizing](#customizing)
 | 
			
		||||
  * [inputs](#inputs)
 | 
			
		||||
  * [outputs](#outputs)
 | 
			
		||||
  * [environment variables](#environment-variables)
 | 
			
		||||
* [Troubleshooting](#troubleshooting)
 | 
			
		||||
* [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot)
 | 
			
		||||
* [Contributing](#contributing)
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
In the examples below we are also using 3 other actions:
 | 
			
		||||
 | 
			
		||||
* [`setup-buildx`](https://github.com/docker/setup-buildx-action) action will create and boot a builder using by 
 | 
			
		||||
default the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver).
 | 
			
		||||
This is **not required but recommended** using it to be able to build multi-platform images, export cache, etc.
 | 
			
		||||
* [`setup-qemu`](https://github.com/docker/setup-qemu-action) action can be useful if you want
 | 
			
		||||
to add emulation support with QEMU to be able to build against more platforms. 
 | 
			
		||||
* [`login`](https://github.com/docker/login-action) action will take care to log in against a Docker registry.
 | 
			
		||||
* [`setup-buildx`](https://github.com/docker/setup-buildx-action) action will
 | 
			
		||||
  create and boot a builder using by default the [`docker-container` driver](https://docs.docker.com/build/building/drivers/docker-container/).
 | 
			
		||||
  This is **not required but recommended** using it to be able to build
 | 
			
		||||
  multi-platform images, export cache, etc.
 | 
			
		||||
* [`setup-qemu`](https://github.com/docker/setup-qemu-action) action can be
 | 
			
		||||
  useful if you want to add emulation support with QEMU to be able to build
 | 
			
		||||
  against more platforms. 
 | 
			
		||||
* [`login`](https://github.com/docker/login-action) action will take care to
 | 
			
		||||
  log in against a Docker registry.
 | 
			
		||||
 | 
			
		||||
### Git context
 | 
			
		||||
 | 
			
		||||
By default, this action uses the [Git context](#git-context) so you don't need
 | 
			
		||||
to use the [`actions/checkout`](https://github.com/actions/checkout/) action to
 | 
			
		||||
check out the repository because this will be done directly by [BuildKit](https://github.com/moby/buildkit).
 | 
			
		||||
By default, this action uses the [Git context](https://docs.docker.com/engine/reference/commandline/build/#git-repositories),
 | 
			
		||||
so you don't need to use the [`actions/checkout`](https://github.com/actions/checkout/)
 | 
			
		||||
action to check out the repository as this will be done directly by [BuildKit](https://github.com/moby/buildkit).
 | 
			
		||||
 | 
			
		||||
The git reference will be based on the [event that triggered your workflow](https://docs.github.com/en/actions/reference/events-that-trigger-workflows)
 | 
			
		||||
The git reference will be based on the [event that triggered your workflow](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows)
 | 
			
		||||
and will result in the following context: `https://github.com/<owner>/<repo>.git#<ref>`.
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
@ -61,28 +55,26 @@ name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        name: Login to Docker Hub
 | 
			
		||||
        uses: docker/login-action@v3
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          username: ${{ vars.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v3
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v3
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        uses: docker/build-push-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
@ -102,23 +94,22 @@ to the default Git context:
 | 
			
		||||
```yaml
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        uses: docker/build-push-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          context: "{{defaultContext}}:mysubdir"
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
```
 | 
			
		||||
> :warning: Subdirectory for Git context is not yet available for the buildx [`docker` driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver).
 | 
			
		||||
 | 
			
		||||
Building from the current repository automatically uses the [GitHub Token](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token)
 | 
			
		||||
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](docs/advanced/secrets.md) named
 | 
			
		||||
`GIT_AUTH_TOKEN` to be able to authenticate against it with buildx:
 | 
			
		||||
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@v2
 | 
			
		||||
        uses: docker/build-push-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
@ -133,8 +124,6 @@ name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
@ -142,48 +131,85 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1
 | 
			
		||||
        name: Login to Docker Hub
 | 
			
		||||
        uses: docker/login-action@v3
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          username: ${{ vars.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v3
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v3
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        uses: docker/build-push-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Advanced usage
 | 
			
		||||
## Examples
 | 
			
		||||
 | 
			
		||||
* [Multi-platform image](docs/advanced/multi-platform.md)
 | 
			
		||||
* [Secrets](docs/advanced/secrets.md)
 | 
			
		||||
* [Isolated builders](docs/advanced/isolated-builders.md)
 | 
			
		||||
* [Push to multi-registries](docs/advanced/push-multi-registries.md)
 | 
			
		||||
* [Copy between registries](docs/advanced/copy-between-registries.md)
 | 
			
		||||
* [Cache](docs/advanced/cache.md)
 | 
			
		||||
* [Local registry](docs/advanced/local-registry.md)
 | 
			
		||||
* [Export image to Docker](docs/advanced/export-docker.md)
 | 
			
		||||
* [Share built image between jobs](docs/advanced/share-image-jobs.md)
 | 
			
		||||
* [Test your image before pushing it](docs/advanced/test-before-push.md)
 | 
			
		||||
* [Handle tags and labels](docs/advanced/tags-labels.md)
 | 
			
		||||
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md)
 | 
			
		||||
* [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/)
 | 
			
		||||
* [Validating build configuration](https://docs.docker.com/build/ci/github-actions/checks/)
 | 
			
		||||
* [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/)
 | 
			
		||||
* [SBOM and provenance attestations](https://docs.docker.com/build/ci/github-actions/attestations/)
 | 
			
		||||
* [Annotations](https://docs.docker.com/build/ci/github-actions/annotations/)
 | 
			
		||||
* [Reproducible builds](https://docs.docker.com/build/ci/github-actions/reproducible-builds/)
 | 
			
		||||
 | 
			
		||||
## Summaries
 | 
			
		||||
 | 
			
		||||
This action generates a [job summary](https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/)
 | 
			
		||||
that provides a detailed overview of the build execution. The summary shows an
 | 
			
		||||
overview of all the steps executed during the build, including the build inputs
 | 
			
		||||
and eventual errors.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
The summary also includes a link for downloading the build record with
 | 
			
		||||
additional details about the build, including build stats, logs, outputs, and
 | 
			
		||||
more. The build record can be imported to Docker Desktop for inspecting the
 | 
			
		||||
build in greater detail.
 | 
			
		||||
 | 
			
		||||
> [!WARNING]
 | 
			
		||||
>
 | 
			
		||||
> If you're using the [`actions/download-artifact`](https://github.com/actions/download-artifact)
 | 
			
		||||
> action in your workflow, you need to ignore the build record artifacts
 | 
			
		||||
> if `name` and `pattern` inputs are not specified ([defaults to download all artifacts](https://github.com/actions/download-artifact?tab=readme-ov-file#download-all-artifacts) of the workflow),
 | 
			
		||||
> otherwise the action will fail:
 | 
			
		||||
> ```yaml
 | 
			
		||||
> - uses: actions/download-artifact@v4
 | 
			
		||||
>   with:
 | 
			
		||||
>     pattern: "!*.dockerbuild"
 | 
			
		||||
> ```
 | 
			
		||||
> More info: https://github.com/actions/toolkit/pull/1874
 | 
			
		||||
 | 
			
		||||
Summaries are enabled by default, but can be disabled with the
 | 
			
		||||
`DOCKER_BUILD_SUMMARY` [environment variable](#environment-variables).
 | 
			
		||||
 | 
			
		||||
For more information about summaries, refer to the
 | 
			
		||||
[documentation](https://docs.docker.com/go/build-summary/).
 | 
			
		||||
 | 
			
		||||
## Customizing
 | 
			
		||||
 | 
			
		||||
### inputs
 | 
			
		||||
 | 
			
		||||
Following inputs can be used as `step.with` keys
 | 
			
		||||
The following inputs can be used as `step.with` keys:
 | 
			
		||||
 | 
			
		||||
> `List` type is a newline-delimited string
 | 
			
		||||
> ```yaml
 | 
			
		||||
@ -198,60 +224,65 @@ Following inputs can be used as `step.with` keys
 | 
			
		||||
> ```
 | 
			
		||||
 | 
			
		||||
| Name               | Type        | Description                                                                                                                                                                       |
 | 
			
		||||
|---------------------|----------|------------------------------------|
 | 
			
		||||
|--------------------|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `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://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#allow) (e.g., `network.host,security.insecure`) |
 | 
			
		||||
| `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://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#build-arg) |
 | 
			
		||||
| `build-contexts`    | List     | List of additional [build contexts](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#build-context) (e.g., `name=path`) |
 | 
			
		||||
| `cache-from`        | List     | List of [external cache sources](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from) (e.g., `type=local,src=path/to/dir`) |
 | 
			
		||||
| `cache-to`          | List     | List of [cache export destinations](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-to) (e.g., `type=local,dest=path/to/dir`) |
 | 
			
		||||
| `build-args`       | List        | List of [build-time variables](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-arg)                                                                      |
 | 
			
		||||
| `build-contexts`   | List        | List of additional [build contexts](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context) (e.g., `name=path`)                                         |
 | 
			
		||||
| `cache-from`       | List        | List of [external cache sources](https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-from) (e.g., `type=local,src=path/to/dir`)                              |
 | 
			
		||||
| `cache-to`         | List        | List of [cache export destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-to) (e.g., `type=local,dest=path/to/dir`)                            |
 | 
			
		||||
| `call`             | String      | Set [method for evaluating build](https://docs.docker.com/reference/cli/docker/buildx/build/#call) (e.g., `check`)                                                                |
 | 
			
		||||
| `cgroup-parent`    | String      | Optional [parent cgroup](https://docs.docker.com/engine/reference/commandline/build/#use-a-custom-parent-cgroup---cgroup-parent) for the container used in the build              |
 | 
			
		||||
| `context`          | String      | Build's context is the set of files located in the specified [`PATH` or `URL`](https://docs.docker.com/engine/reference/commandline/build/) (default [Git context](#git-context)) |
 | 
			
		||||
| `file`             | String      | Path to the Dockerfile. (default `{context}/Dockerfile`)                                                                                                                          |
 | 
			
		||||
| `labels`           | List        | List of metadata for an image                                                                                                                                                     |
 | 
			
		||||
| `load`              | Bool     | [Load](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#load) is a shorthand for `--output=type=docker` (default `false`) |
 | 
			
		||||
| `load`             | Bool        | [Load](https://docs.docker.com/engine/reference/commandline/buildx_build/#load) is a shorthand for `--output=type=docker` (default `false`)                                       |
 | 
			
		||||
| `network`          | String      | Set the networking mode for the `RUN` instructions during build                                                                                                                   |
 | 
			
		||||
| `no-cache`         | Bool        | Do not use cache when building the image (default `false`)                                                                                                                        |
 | 
			
		||||
| `outputs`           | List     | List of [output destinations](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#output) (format: `type=local,dest=path`) |
 | 
			
		||||
| `platforms`         | List/CSV | List of [target platforms](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#platform) for build |
 | 
			
		||||
| `no-cache-filters` | List/CSV    | Do not cache specified stages                                                                                                                                                     |
 | 
			
		||||
| `outputs`          | List        | List of [output destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#output) (format: `type=local,dest=path`)                                         |
 | 
			
		||||
| `platforms`        | List/CSV    | List of [target platforms](https://docs.docker.com/engine/reference/commandline/buildx_build/#platform) for build                                                                 |
 | 
			
		||||
| `provenance`       | Bool/String | Generate [provenance](https://docs.docker.com/build/attestations/slsa-provenance/) attestation for the build (shorthand for `--attest=type=provenance`)                           |
 | 
			
		||||
| `pull`             | Bool        | Always attempt to pull all referenced images (default `false`)                                                                                                                    |
 | 
			
		||||
| `push`              | Bool     | [Push](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#push) is a shorthand for `--output=type=registry` (default `false`) |
 | 
			
		||||
| `secrets`           | List     | List of [secrets](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#secret) to expose to the build (e.g., `key=string`, `GIT_AUTH_TOKEN=mytoken`) |
 | 
			
		||||
| `secret-files`      | List     | List of [secret files](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#secret) to expose to the build (e.g., `key=filename`, `MY_SECRET=./secret.txt`) |
 | 
			
		||||
| `shm-size`          | String   | Size of [`/dev/shm`](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#-size-of-devshm---shm-size) (e.g., `2g`) |
 | 
			
		||||
| `ssh`               | List     | List of [SSH agent socket or keys](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#ssh) to expose to the build |
 | 
			
		||||
| `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                                                 |
 | 
			
		||||
| `tags`             | List/CSV    | List of tags                                                                                                                                                                      |
 | 
			
		||||
| `target`           | String      | Sets the target stage to build                                                                                                                                                    |
 | 
			
		||||
| `ulimit`            | List     | [Ulimit](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#-set-ulimits---ulimit) options (e.g., `nofile=1024:1024`) |
 | 
			
		||||
| `ulimit`           | List        | [Ulimit](https://docs.docker.com/engine/reference/commandline/buildx_build/#ulimit) options (e.g., `nofile=1024:1024`)                                                            |
 | 
			
		||||
| `github-token`     | String      | GitHub Token used to authenticate against a repository for [Git context](#git-context) (default `${{ github.token }}`)                                                            |
 | 
			
		||||
 | 
			
		||||
### outputs
 | 
			
		||||
 | 
			
		||||
Following outputs are available
 | 
			
		||||
The following outputs are available:
 | 
			
		||||
 | 
			
		||||
| Name       | Type    | Description           |
 | 
			
		||||
|-------------------|---------|---------------------------------------|
 | 
			
		||||
|------------|---------|-----------------------|
 | 
			
		||||
| `imageid`  | String  | Image ID              |
 | 
			
		||||
| `digest`   | String  | Image digest          |
 | 
			
		||||
| `metadata` | JSON    | Build result metadata |
 | 
			
		||||
 | 
			
		||||
### environment variables
 | 
			
		||||
 | 
			
		||||
| Name                                 | Type   | Default | Description                                                                                                                                                                                                                                                        |
 | 
			
		||||
|--------------------------------------|--------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `DOCKER_BUILD_CHECKS_ANNOTATIONS`    | Bool   | `true`  | If `false`, GitHub annotations are not generated for [build checks](https://docs.docker.com/build/checks/)                                                                                                                                                         |
 | 
			
		||||
| `DOCKER_BUILD_SUMMARY`               | Bool   | `true`  | If `false`, [build summary](https://docs.docker.com/build/ci/github-actions/build-summary/) generation is disabled                                                                                                                                                 |
 | 
			
		||||
| `DOCKER_BUILD_RECORD_UPLOAD`         | Bool   | `true`  | If `false`, build record upload as [GitHub artifact](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts) is disabled                                                                                                            |
 | 
			
		||||
| `DOCKER_BUILD_RECORD_RETENTION_DAYS` | Number |         | Duration after which build record artifact will expire in days. Defaults to repository/org [retention settings](https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration#artifact-and-log-retention-policy) if unset or `0` |
 | 
			
		||||
 | 
			
		||||
## Troubleshooting
 | 
			
		||||
 | 
			
		||||
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
 | 
			
		||||
 | 
			
		||||
## Keep up-to-date with GitHub Dependabot
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
Since [Dependabot](https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-github-dependabot)
 | 
			
		||||
has [native GitHub Actions support](https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#package-ecosystem),
 | 
			
		||||
to enable it on your GitHub repo all you need to do is add the `.github/dependabot.yml` file:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
version: 2
 | 
			
		||||
updates:
 | 
			
		||||
  # Maintain dependencies for GitHub Actions
 | 
			
		||||
  - package-ecosystem: "github-actions"
 | 
			
		||||
    directory: "/"
 | 
			
		||||
    schedule:
 | 
			
		||||
      interval: "daily"
 | 
			
		||||
```
 | 
			
		||||
Want to contribute? Awesome! You can find information about contributing to
 | 
			
		||||
this project in the [CONTRIBUTING.md](/.github/CONTRIBUTING.md)
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ While pushing to a registry, you may encounter these kinds of issues:
 | 
			
		||||
* `unexpected response: 401 Unauthorized`
 | 
			
		||||
 | 
			
		||||
These issues are not directly related to this action but are rather linked to
 | 
			
		||||
[buildx](https://github.com/docker/buildx), [buildkit](https://github.com/moby/buildkit),
 | 
			
		||||
[Buildx](https://github.com/docker/buildx), [BuildKit](https://github.com/moby/buildkit),
 | 
			
		||||
[containerd](https://github.com/containerd/containerd) or the registry on which
 | 
			
		||||
you're pushing your image. The quality of error message depends on the registry
 | 
			
		||||
and are usually not very informative.
 | 
			
		||||
@ -29,7 +29,7 @@ action step and attach BuildKit container logs to your issue.
 | 
			
		||||
### With containerd
 | 
			
		||||
 | 
			
		||||
Next you can test pushing with [containerd action](https://github.com/crazy-max/ghaction-setup-containerd)
 | 
			
		||||
using the following workflow. If it works then open an issue on [buildkit](https://github.com/moby/buildkit)
 | 
			
		||||
using the following workflow. If it works then open an issue on [BuildKit](https://github.com/moby/buildkit)
 | 
			
		||||
repository.
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
@ -44,21 +44,21 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
        uses: docker/setup-qemu-action@v3
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
        uses: docker/setup-buildx-action@v3
 | 
			
		||||
        with:
 | 
			
		||||
          buildkitd-flags: --debug
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up containerd
 | 
			
		||||
        uses: crazy-max/ghaction-setup-containerd@v1
 | 
			
		||||
        uses: crazy-max/ghaction-setup-containerd@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Build Docker image
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        uses: docker/build-push-action@v6
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          platforms: linux/amd64,linux/arm64
 | 
			
		||||
@ -105,13 +105,13 @@ to generate sanitized tags:
 | 
			
		||||
```yaml
 | 
			
		||||
- name: Docker meta
 | 
			
		||||
  id: meta
 | 
			
		||||
  uses: docker/metadata-action@v3
 | 
			
		||||
  uses: docker/metadata-action@v4
 | 
			
		||||
  with:
 | 
			
		||||
    images: ghcr.io/${{ github.repository }}
 | 
			
		||||
    tags: latest
 | 
			
		||||
 | 
			
		||||
- name: Build and push
 | 
			
		||||
  uses: docker/build-push-action@v2
 | 
			
		||||
  uses: docker/build-push-action@v6
 | 
			
		||||
  with:
 | 
			
		||||
    context: .
 | 
			
		||||
    push: true
 | 
			
		||||
@ -122,14 +122,14 @@ Or a dedicated step to sanitize the slug:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
- name: Sanitize repo slug
 | 
			
		||||
  uses: actions/github-script@v4
 | 
			
		||||
  uses: actions/github-script@v6
 | 
			
		||||
  id: repo_slug
 | 
			
		||||
  with:
 | 
			
		||||
    result-encoding: string
 | 
			
		||||
    script: return 'ghcr.io/${{ github.repository }}'.toLowerCase()
 | 
			
		||||
 | 
			
		||||
- name: Build and push
 | 
			
		||||
  uses: docker/build-push-action@v2
 | 
			
		||||
  uses: docker/build-push-action@v6
 | 
			
		||||
  with:
 | 
			
		||||
    context: .
 | 
			
		||||
    push: true
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										133
									
								
								UPGRADE.md
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								UPGRADE.md
									
									
									
									
									
								
							@ -1,133 +0,0 @@
 | 
			
		||||
# Upgrade notes
 | 
			
		||||
 | 
			
		||||
## v1 to v2
 | 
			
		||||
 | 
			
		||||
* Input `path` is now called `context` for consistency with other Docker build tools
 | 
			
		||||
* `path` defaults to current git repository so checkout action is not required in a workflow
 | 
			
		||||
* Rename `dockerfile` input to `file` for consistency with other Docker build tools
 | 
			
		||||
* Rename `always_pull` input to `pull` for consistency with other Docker build tools
 | 
			
		||||
* Add `builder` input to be able to choose a builder instance through our [setup-buildx action](https://github.com/docker/setup-buildx-action)
 | 
			
		||||
* Add `platforms` input to support multi-platform builds
 | 
			
		||||
* Add `allow` input
 | 
			
		||||
* Add `load` input
 | 
			
		||||
* Add `outputs` input
 | 
			
		||||
* Add `cache-from` input (`cache_froms` removed)
 | 
			
		||||
* Add `cache-to` input
 | 
			
		||||
* Rename `build_args` input to `build-args` for consistency with other Docker build tools
 | 
			
		||||
* Add `secrets` input
 | 
			
		||||
* Review `tags` input
 | 
			
		||||
* Remove `repository` input. See [Simple workflow](#simple-workflow) for migration
 | 
			
		||||
* Remove `username`, `password` and `registry` inputs. Login support moved to [docker/login-action](https://github.com/docker/login-action) repo
 | 
			
		||||
* Remove `tag_with_sha`, `tag_with_ref`, `add_git_labels` inputs. See [Tags with ref and Git labels](#tags-with-ref-and-git-labels) for migration
 | 
			
		||||
* Handle Git context
 | 
			
		||||
* Add `digest` output
 | 
			
		||||
 | 
			
		||||
### Simple workflow
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
# v1
 | 
			
		||||
steps:
 | 
			
		||||
  -
 | 
			
		||||
    name: Checkout
 | 
			
		||||
    uses: actions/checkout@v2
 | 
			
		||||
  -
 | 
			
		||||
    name: Build and push Docker images
 | 
			
		||||
    uses: docker/build-push-action@v1
 | 
			
		||||
    with:
 | 
			
		||||
      username: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
      password: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
      repository: myorg/myrepository
 | 
			
		||||
      always_pull: true
 | 
			
		||||
      build_args: arg1=value1,arg2=value2
 | 
			
		||||
      cache_froms: myorg/myrepository:latest
 | 
			
		||||
      tags: latest
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
# v2
 | 
			
		||||
steps:
 | 
			
		||||
  -
 | 
			
		||||
    name: Checkout
 | 
			
		||||
    uses: actions/checkout@v2
 | 
			
		||||
  -
 | 
			
		||||
    name: Set up Docker Buildx
 | 
			
		||||
    uses: docker/setup-buildx-action@v1
 | 
			
		||||
  -
 | 
			
		||||
    name: Login to DockerHub
 | 
			
		||||
    uses: docker/login-action@v1
 | 
			
		||||
    with:
 | 
			
		||||
      username: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
      password: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
  -
 | 
			
		||||
    name: Build and push
 | 
			
		||||
    uses: docker/build-push-action@v2
 | 
			
		||||
    with:
 | 
			
		||||
      context: .
 | 
			
		||||
      pull: true
 | 
			
		||||
      push: true
 | 
			
		||||
      build-args: |
 | 
			
		||||
        arg1=value1
 | 
			
		||||
        arg2=value2
 | 
			
		||||
      cache-from: type=registry,ref=myorg/myrepository:latest
 | 
			
		||||
      cache-to: type=inline
 | 
			
		||||
      tags: myorg/myrepository:latest
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Tags with ref and Git labels
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
# v1
 | 
			
		||||
steps:
 | 
			
		||||
  -
 | 
			
		||||
    name: Checkout
 | 
			
		||||
    uses: actions/checkout@v2
 | 
			
		||||
  -
 | 
			
		||||
    name: Build and push Docker images
 | 
			
		||||
    uses: docker/build-push-action@v1
 | 
			
		||||
    with:
 | 
			
		||||
      username: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
      password: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
      repository: myorg/myrepository
 | 
			
		||||
      push: ${{ github.event_name != 'pull_request' }}
 | 
			
		||||
      tag_with_ref: true
 | 
			
		||||
      tag_with_sha: true
 | 
			
		||||
      add_git_labels: true
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
# v2
 | 
			
		||||
steps:
 | 
			
		||||
  -
 | 
			
		||||
    name: Checkout
 | 
			
		||||
    uses: actions/checkout@v2
 | 
			
		||||
  -
 | 
			
		||||
    name: Docker meta
 | 
			
		||||
    id: meta
 | 
			
		||||
    uses: docker/metadata-action@v3
 | 
			
		||||
    with:
 | 
			
		||||
      images: |
 | 
			
		||||
        myorg/myrepository
 | 
			
		||||
      tags: |
 | 
			
		||||
        type=ref,event=branch
 | 
			
		||||
        type=ref,event=pr
 | 
			
		||||
        type=semver,pattern={{version}}
 | 
			
		||||
        type=sha
 | 
			
		||||
  -
 | 
			
		||||
    name: Set up Docker Buildx
 | 
			
		||||
    uses: docker/setup-buildx-action@v1
 | 
			
		||||
  -
 | 
			
		||||
    name: Login to DockerHub
 | 
			
		||||
    if: github.event_name != 'pull_request'
 | 
			
		||||
    uses: docker/login-action@v1 
 | 
			
		||||
    with:
 | 
			
		||||
      username: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
      password: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
  -
 | 
			
		||||
    name: Build and push
 | 
			
		||||
    uses: docker/build-push-action@v2
 | 
			
		||||
    with:
 | 
			
		||||
      context: .
 | 
			
		||||
      push: ${{ github.event_name != 'pull_request' }}
 | 
			
		||||
      tags: ${{ steps.meta.outputs.tags }}
 | 
			
		||||
      labels: ${{ steps.meta.outputs.labels }}
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										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,193 +0,0 @@
 | 
			
		||||
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', () => {
 | 
			
		||||
  // prettier-ignore
 | 
			
		||||
  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.SpyInstance = jest.spyOn(exec, 'getExecOutput');
 | 
			
		||||
  buildx.isAvailable();
 | 
			
		||||
 | 
			
		||||
  expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], {
 | 
			
		||||
    silent: true,
 | 
			
		||||
    ignoreReturnCode: true
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('getVersion', () => {
 | 
			
		||||
  async function isDaemonRunning() {
 | 
			
		||||
    return await exec
 | 
			
		||||
      .getExecOutput(`docker`, ['version', '--format', '{{.Server.Os}}'], {
 | 
			
		||||
        ignoreReturnCode: true,
 | 
			
		||||
        silent: true
 | 
			
		||||
      })
 | 
			
		||||
      .then(res => {
 | 
			
		||||
        return !res.stdout.includes(' ') && res.exitCode == 0;
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
  (isDaemonRunning() ? it : it.skip)(
 | 
			
		||||
    'valid',
 | 
			
		||||
    async () => {
 | 
			
		||||
      const version = await buildx.getVersion();
 | 
			
		||||
      expect(semver.valid(version)).not.toBeNull();
 | 
			
		||||
    },
 | 
			
		||||
    100000
 | 
			
		||||
  );
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
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}`);
 | 
			
		||||
      const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8');
 | 
			
		||||
      expect(secretValue).toEqual(exValue);
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      expect(true).toBe(invalid);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										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
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								action.yml
									
									
									
									
									
								
							@ -13,6 +13,12 @@ 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
 | 
			
		||||
  build-args:
 | 
			
		||||
    description: "List of build-time variables"
 | 
			
		||||
    required: false
 | 
			
		||||
@ -28,6 +34,9 @@ inputs:
 | 
			
		||||
  cache-to:
 | 
			
		||||
    description: "List of cache export destinations for buildx (e.g., user/app:cache, type=local,dest=path/to/dir)"
 | 
			
		||||
    required: false
 | 
			
		||||
  call:
 | 
			
		||||
    description: "Set method for evaluating build (e.g., check)"
 | 
			
		||||
    required: false
 | 
			
		||||
  cgroup-parent:
 | 
			
		||||
    description: "Optional parent cgroup for the container used in the build"
 | 
			
		||||
    required: false
 | 
			
		||||
@ -51,12 +60,18 @@ inputs:
 | 
			
		||||
    description: "Do not use cache when building the image"
 | 
			
		||||
    required: false
 | 
			
		||||
    default: 'false'
 | 
			
		||||
  no-cache-filters:
 | 
			
		||||
    description: "Do not cache specified stages"
 | 
			
		||||
    required: false
 | 
			
		||||
  outputs:
 | 
			
		||||
    description: "List of output destinations (format: type=local,dest=path)"
 | 
			
		||||
    required: false
 | 
			
		||||
  platforms:
 | 
			
		||||
    description: "List of target platforms for build"
 | 
			
		||||
    required: false
 | 
			
		||||
  provenance:
 | 
			
		||||
    description: "Generate provenance attestation for the build (shorthand for --attest=type=provenance)"
 | 
			
		||||
    required: false
 | 
			
		||||
  pull:
 | 
			
		||||
    description: "Always attempt to pull all referenced images"
 | 
			
		||||
    required: false
 | 
			
		||||
@ -65,9 +80,15 @@ inputs:
 | 
			
		||||
    description: "Push is a shorthand for --output=type=registry"
 | 
			
		||||
    required: false
 | 
			
		||||
    default: 'false'
 | 
			
		||||
  sbom:
 | 
			
		||||
    description: "Generate SBOM attestation for the build (shorthand for --attest=type=sbom)"
 | 
			
		||||
    required: false
 | 
			
		||||
  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
 | 
			
		||||
@ -100,6 +121,6 @@ outputs:
 | 
			
		||||
    description: 'Build result metadata'
 | 
			
		||||
 | 
			
		||||
runs:
 | 
			
		||||
  using: 'node12'
 | 
			
		||||
  using: 'node20'
 | 
			
		||||
  main: 'dist/index.js'
 | 
			
		||||
  post: 'dist/index.js'
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,20 @@
 | 
			
		||||
# syntax=docker/dockerfile:1.3-labs
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
 | 
			
		||||
ARG NODE_VERSION
 | 
			
		||||
ARG DOCKER_VERSION=20.10.10
 | 
			
		||||
ARG BUILDX_VERSION=0.7.0
 | 
			
		||||
ARG NODE_VERSION=20
 | 
			
		||||
 | 
			
		||||
FROM node:${NODE_VERSION}-alpine AS base
 | 
			
		||||
RUN apk add --no-cache cpio findutils git
 | 
			
		||||
WORKDIR /src
 | 
			
		||||
RUN --mount=type=bind,target=.,rw \
 | 
			
		||||
  --mount=type=cache,target=/src/.yarn/cache <<EOT
 | 
			
		||||
  corepack enable
 | 
			
		||||
  yarn --version
 | 
			
		||||
  yarn config set --home enableTelemetry 0
 | 
			
		||||
EOT
 | 
			
		||||
 | 
			
		||||
FROM base AS deps
 | 
			
		||||
RUN --mount=type=bind,target=.,rw \
 | 
			
		||||
  --mount=type=cache,target=/src/.yarn/cache \
 | 
			
		||||
  --mount=type=cache,target=/src/node_modules \
 | 
			
		||||
  yarn install && mkdir /vendor && cp yarn.lock /vendor
 | 
			
		||||
 | 
			
		||||
@ -18,18 +23,19 @@ COPY --from=deps /vendor /
 | 
			
		||||
 | 
			
		||||
FROM deps AS vendor-validate
 | 
			
		||||
RUN --mount=type=bind,target=.,rw <<EOT
 | 
			
		||||
set -e
 | 
			
		||||
git add -A
 | 
			
		||||
cp -rf /vendor/* .
 | 
			
		||||
if [ -n "$(git status --porcelain -- yarn.lock)" ]; then
 | 
			
		||||
  set -e
 | 
			
		||||
  git add -A
 | 
			
		||||
  cp -rf /vendor/* .
 | 
			
		||||
  if [ -n "$(git status --porcelain -- yarn.lock)" ]; then
 | 
			
		||||
    echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'
 | 
			
		||||
    git status --porcelain -- yarn.lock
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
  fi
 | 
			
		||||
EOT
 | 
			
		||||
 | 
			
		||||
FROM deps AS build
 | 
			
		||||
RUN --mount=type=bind,target=.,rw \
 | 
			
		||||
  --mount=type=cache,target=/src/.yarn/cache \
 | 
			
		||||
  --mount=type=cache,target=/src/node_modules \
 | 
			
		||||
  yarn run build && mkdir /out && cp -Rf dist /out/
 | 
			
		||||
 | 
			
		||||
@ -38,41 +44,37 @@ COPY --from=build /out /
 | 
			
		||||
 | 
			
		||||
FROM build AS build-validate
 | 
			
		||||
RUN --mount=type=bind,target=.,rw <<EOT
 | 
			
		||||
set -e
 | 
			
		||||
git add -A
 | 
			
		||||
cp -rf /out/* .
 | 
			
		||||
if [ -n "$(git status --porcelain -- dist)" ]; then
 | 
			
		||||
  set -e
 | 
			
		||||
  git add -A
 | 
			
		||||
  cp -rf /out/* .
 | 
			
		||||
  if [ -n "$(git status --porcelain -- dist)" ]; then
 | 
			
		||||
    echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
 | 
			
		||||
    git status --porcelain -- dist
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
  fi
 | 
			
		||||
EOT
 | 
			
		||||
 | 
			
		||||
FROM deps AS format
 | 
			
		||||
RUN --mount=type=bind,target=.,rw \
 | 
			
		||||
  --mount=type=cache,target=/src/.yarn/cache \
 | 
			
		||||
  --mount=type=cache,target=/src/node_modules \
 | 
			
		||||
  yarn run format \
 | 
			
		||||
  && mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out
 | 
			
		||||
  && mkdir /out && find . -name '*.ts' -not -path './node_modules/*' -not -path './.yarn/*' | cpio -pdm /out
 | 
			
		||||
 | 
			
		||||
FROM scratch AS format-update
 | 
			
		||||
COPY --from=format /out /
 | 
			
		||||
 | 
			
		||||
FROM deps AS format-validate
 | 
			
		||||
FROM deps AS lint
 | 
			
		||||
RUN --mount=type=bind,target=.,rw \
 | 
			
		||||
  --mount=type=cache,target=/src/.yarn/cache \
 | 
			
		||||
  --mount=type=cache,target=/src/node_modules \
 | 
			
		||||
  yarn run format-check
 | 
			
		||||
 | 
			
		||||
FROM docker:${DOCKER_VERSION} as docker
 | 
			
		||||
FROM docker/buildx-bin:${BUILDX_VERSION} as buildx
 | 
			
		||||
  yarn run lint
 | 
			
		||||
 | 
			
		||||
FROM deps AS test
 | 
			
		||||
ENV RUNNER_TEMP=/tmp/github_runner
 | 
			
		||||
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
 | 
			
		||||
RUN --mount=type=bind,target=.,rw \
 | 
			
		||||
  --mount=type=cache,target=/src/.yarn/cache \
 | 
			
		||||
  --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 /
 | 
			
		||||
							
								
								
									
										27954
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27954
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								dist/index.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/index.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										3924
									
								
								dist/licenses.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3924
									
								
								dist/licenses.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								dist/sourcemap-register.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/sourcemap-register.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -1,10 +1,6 @@
 | 
			
		||||
variable "NODE_VERSION" {
 | 
			
		||||
  default = "12"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
target "node-version" {
 | 
			
		||||
target "_common" {
 | 
			
		||||
  args = {
 | 
			
		||||
    NODE_VERSION = NODE_VERSION
 | 
			
		||||
    BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,58 +9,58 @@ group "default" {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
group "pre-checkin" {
 | 
			
		||||
  targets = ["vendor-update", "format", "build"]
 | 
			
		||||
  targets = ["vendor", "format", "build"]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
group "validate" {
 | 
			
		||||
  targets = ["format-validate", "build-validate", "vendor-validate"]
 | 
			
		||||
  targets = ["lint", "build-validate", "vendor-validate"]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
target "build" {
 | 
			
		||||
  inherits = ["node-version"]
 | 
			
		||||
  dockerfile = "./hack/build.Dockerfile"
 | 
			
		||||
  inherits = ["_common"]
 | 
			
		||||
  dockerfile = "dev.Dockerfile"
 | 
			
		||||
  target = "build-update"
 | 
			
		||||
  output = ["."]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
target "build-validate" {
 | 
			
		||||
  inherits = ["node-version"]
 | 
			
		||||
  dockerfile = "./hack/build.Dockerfile"
 | 
			
		||||
  inherits = ["_common"]
 | 
			
		||||
  dockerfile = "dev.Dockerfile"
 | 
			
		||||
  target = "build-validate"
 | 
			
		||||
  output = ["type=cacheonly"]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
target "format" {
 | 
			
		||||
  inherits = ["node-version"]
 | 
			
		||||
  dockerfile = "./hack/build.Dockerfile"
 | 
			
		||||
  inherits = ["_common"]
 | 
			
		||||
  dockerfile = "dev.Dockerfile"
 | 
			
		||||
  target = "format-update"
 | 
			
		||||
  output = ["."]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
target "format-validate" {
 | 
			
		||||
  inherits = ["node-version"]
 | 
			
		||||
  dockerfile = "./hack/build.Dockerfile"
 | 
			
		||||
  target = "format-validate"
 | 
			
		||||
target "lint" {
 | 
			
		||||
  inherits = ["_common"]
 | 
			
		||||
  dockerfile = "dev.Dockerfile"
 | 
			
		||||
  target = "lint"
 | 
			
		||||
  output = ["type=cacheonly"]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
target "vendor-update" {
 | 
			
		||||
  inherits = ["node-version"]
 | 
			
		||||
  dockerfile = "./hack/build.Dockerfile"
 | 
			
		||||
target "vendor" {
 | 
			
		||||
  inherits = ["_common"]
 | 
			
		||||
  dockerfile = "dev.Dockerfile"
 | 
			
		||||
  target = "vendor-update"
 | 
			
		||||
  output = ["."]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
target "vendor-validate" {
 | 
			
		||||
  inherits = ["node-version"]
 | 
			
		||||
  dockerfile = "./hack/build.Dockerfile"
 | 
			
		||||
  inherits = ["_common"]
 | 
			
		||||
  dockerfile = "dev.Dockerfile"
 | 
			
		||||
  target = "vendor-validate"
 | 
			
		||||
  output = ["type=cacheonly"]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
target "test" {
 | 
			
		||||
  inherits = ["node-version"]
 | 
			
		||||
  dockerfile = "./hack/build.Dockerfile"
 | 
			
		||||
  inherits = ["_common"]
 | 
			
		||||
  dockerfile = "dev.Dockerfile"
 | 
			
		||||
  target = "test-coverage"
 | 
			
		||||
  output = ["./coverage"]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,200 +0,0 @@
 | 
			
		||||
# Cache
 | 
			
		||||
 | 
			
		||||
* [Inline cache](#inline-cache)
 | 
			
		||||
* [Registry cache](#registry-cache)
 | 
			
		||||
* [GitHub cache](#github-cache)
 | 
			
		||||
  * [Cache backend API](#cache-backend-api)
 | 
			
		||||
  * [Local cache](#local-cache)
 | 
			
		||||
 | 
			
		||||
> More info about cache on [BuildKit](https://github.com/moby/buildkit#export-cache) and [Buildx](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from) repositories.
 | 
			
		||||
 | 
			
		||||
## Inline cache
 | 
			
		||||
 | 
			
		||||
In most cases you want to use the [`type=inline` cache exporter](https://github.com/moby/buildkit#inline-push-image-and-cache-together).
 | 
			
		||||
However, note that the `inline` cache exporter only supports `min` cache mode. To enable `max` cache mode, push the
 | 
			
		||||
image and the cache separately by using the `registry` cache exporter as shown in the [next example](#registry-cache).
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
          cache-from: type=registry,ref=user/app:latest
 | 
			
		||||
          cache-to: type=inline
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Registry cache
 | 
			
		||||
 | 
			
		||||
You can import/export cache from a cache manifest or (special) image configuration on the registry with the
 | 
			
		||||
[`type=registry` cache exporter](https://github.com/moby/buildkit/tree/master#registry-push-image-and-cache-separately).
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
          cache-from: type=registry,ref=user/app:buildcache
 | 
			
		||||
          cache-to: type=registry,ref=user/app:buildcache,mode=max
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## GitHub cache
 | 
			
		||||
 | 
			
		||||
### Cache backend API
 | 
			
		||||
 | 
			
		||||
> :test_tube: This cache exporter is considered EXPERIMENTAL until further notice. Please provide feedback on
 | 
			
		||||
> [BuildKit repository](https://github.com/moby/buildkit) if you encounter any issues.
 | 
			
		||||
 | 
			
		||||
Since [buildx 0.6.0](https://github.com/docker/buildx/releases/tag/v0.6.0) and [BuildKit 0.9.0](https://github.com/moby/buildkit/releases/tag/v0.9.0),
 | 
			
		||||
you can use the [`type=gha` cache exporter](https://github.com/moby/buildkit/tree/master#github-actions-cache-experimental).
 | 
			
		||||
 | 
			
		||||
GitHub Actions cache exporter backend uses the [GitHub Cache API](https://github.com/tonistiigi/go-actions-cache/blob/master/api.md)
 | 
			
		||||
to fetch and upload cache blobs. That's why this type of cache should be exclusively used in a GitHub Action workflow
 | 
			
		||||
as the `url` (`$ACTIONS_CACHE_URL`) and `token` (`$ACTIONS_RUNTIME_TOKEN`) attributes are populated when a workflow
 | 
			
		||||
is started.
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
          cache-from: type=gha
 | 
			
		||||
          cache-to: type=gha,mode=max
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Local cache
 | 
			
		||||
 | 
			
		||||
> :warning: At the moment caches are copied over the existing cache so it [keeps growing](https://github.com/docker/build-push-action/issues/252).
 | 
			
		||||
> The `Move cache` step is used as a temporary fix (see https://github.com/moby/buildkit/issues/1896).
 | 
			
		||||
 | 
			
		||||
You can also leverage [GitHub cache](https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows)
 | 
			
		||||
using [actions/cache](https://github.com/actions/cache) and [`type=local` cache exporter](https://github.com/moby/buildkit#local-directory-1)
 | 
			
		||||
with this action:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Cache Docker layers
 | 
			
		||||
        uses: actions/cache@v2
 | 
			
		||||
        with:
 | 
			
		||||
          path: /tmp/.buildx-cache
 | 
			
		||||
          key: ${{ runner.os }}-buildx-${{ github.sha }}
 | 
			
		||||
          restore-keys: |
 | 
			
		||||
            ${{ runner.os }}-buildx-
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
          cache-from: type=local,src=/tmp/.buildx-cache
 | 
			
		||||
          cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
 | 
			
		||||
      -
 | 
			
		||||
        # 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
 | 
			
		||||
```
 | 
			
		||||
@ -1,73 +0,0 @@
 | 
			
		||||
# Copy images between registries
 | 
			
		||||
 | 
			
		||||
Multi-platform images built using buildx can be copied from one registry to another without
 | 
			
		||||
changing the image SHA using the [tag-push-action](https://github.com/akhilerm/tag-push-action).
 | 
			
		||||
 | 
			
		||||
The following workflow will first push the image to dockerhub, run some tests using the images
 | 
			
		||||
and then push to quay and ghcr
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - 
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      - # quay and ghcr logins for pushing image after testing
 | 
			
		||||
        name: Login to Quay Registry
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          registry: quay.io
 | 
			
		||||
          username: ${{ secrets.QUAY_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.QUAY_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to GitHub Container Registry
 | 
			
		||||
        uses: docker/login-action@v1
 | 
			
		||||
        with:
 | 
			
		||||
          registry: ghcr.io
 | 
			
		||||
          username: ${{ github.repository_owner }}
 | 
			
		||||
          password: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          platforms: linux/amd64,linux/arm64
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: |
 | 
			
		||||
            user/app:latest
 | 
			
		||||
            user/app:1.0.0
 | 
			
		||||
      - # run tests using image from docker hub
 | 
			
		||||
        name: Run Tests
 | 
			
		||||
        run: make tests
 | 
			
		||||
      - # copy multiplatform image from dockerhub to quay and ghcr
 | 
			
		||||
        name: Push Image to multiple registries
 | 
			
		||||
        uses: akhilerm/tag-push-action@v2.0.0
 | 
			
		||||
        with:
 | 
			
		||||
          src: docker.io/user/app:1.0.0
 | 
			
		||||
          dst: |
 | 
			
		||||
            quay.io/user/app:latest
 | 
			
		||||
            quay.io/user/app:1.0.0
 | 
			
		||||
            ghcr.io/user/app:latest
 | 
			
		||||
            ghcr.io/user/app:1.0.0
 | 
			
		||||
```
 | 
			
		||||
@ -1,48 +0,0 @@
 | 
			
		||||
# Update DockerHub repo description
 | 
			
		||||
 | 
			
		||||
You can update the [DockerHub repository description](https://docs.docker.com/docker-hub/repos/) using
 | 
			
		||||
a third party action called [DockerHub Description](https://github.com/peter-evans/dockerhub-description)
 | 
			
		||||
with this action:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
      -
 | 
			
		||||
        name: Update repo description
 | 
			
		||||
        uses: peter-evans/dockerhub-description@v2
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_PASSWORD }}
 | 
			
		||||
          repository: user/app
 | 
			
		||||
```
 | 
			
		||||
@ -1,35 +0,0 @@
 | 
			
		||||
# Export image to Docker
 | 
			
		||||
 | 
			
		||||
You may want your build result to be available in the Docker client through `docker images` to be able to use it
 | 
			
		||||
in another step of your workflow:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Build
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          load: true
 | 
			
		||||
          tags: myimage:latest
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker image inspect myimage:latest
 | 
			
		||||
```
 | 
			
		||||
@ -1,44 +0,0 @@
 | 
			
		||||
# Isolated builders
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
        id: builder1
 | 
			
		||||
      -
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
        id: builder2
 | 
			
		||||
      -
 | 
			
		||||
        name: Builder 1 name
 | 
			
		||||
        run: echo ${{ steps.builder1.outputs.name }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Builder 2 name
 | 
			
		||||
        run: echo ${{ steps.builder2.outputs.name }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build against builder1
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          builder: ${{ steps.builder1.outputs.name }}
 | 
			
		||||
          context: .
 | 
			
		||||
          target: mytarget1
 | 
			
		||||
      -
 | 
			
		||||
        name: Build against builder2
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          builder: ${{ steps.builder2.outputs.name }}
 | 
			
		||||
          context: .
 | 
			
		||||
          target: mytarget2
 | 
			
		||||
```
 | 
			
		||||
@ -1,44 +0,0 @@
 | 
			
		||||
# Local registry
 | 
			
		||||
 | 
			
		||||
For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry) to push images into:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    services:
 | 
			
		||||
      registry:
 | 
			
		||||
        image: registry:2
 | 
			
		||||
        ports:
 | 
			
		||||
          - 5000:5000
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
        with:
 | 
			
		||||
          driver-opts: network=host
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push to local registry
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: localhost:5000/name/app:latest
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:latest
 | 
			
		||||
```
 | 
			
		||||
@ -1,44 +0,0 @@
 | 
			
		||||
# Multi-platform image
 | 
			
		||||
 | 
			
		||||
You can build multi-platform images using the [`platforms` input](../../README.md#inputs) as described below.
 | 
			
		||||
 | 
			
		||||
> :bulb: List of available platforms will be displayed and available through our [setup-buildx](https://github.com/docker/setup-buildx-action#about) action.
 | 
			
		||||
 | 
			
		||||
> :bulb: If you want support for more platforms, you can use QEMU with our [setup-qemu](https://github.com/docker/setup-qemu-action) action.
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          platforms: linux/amd64,linux/arm64
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
```
 | 
			
		||||
@ -1,57 +0,0 @@
 | 
			
		||||
# Push to multi-registries
 | 
			
		||||
 | 
			
		||||
* [Docker Hub and GHCR](#docker-hub-and-ghcr)
 | 
			
		||||
 | 
			
		||||
## Docker Hub and GHCR
 | 
			
		||||
 | 
			
		||||
The following workflow will connect you to [DockerHub](https://github.com/docker/login-action#dockerhub)
 | 
			
		||||
and [GitHub Container Registry](https://github.com/docker/login-action#github-container-registry) and push the
 | 
			
		||||
image to these registries.
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to GitHub Container Registry
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          registry: ghcr.io
 | 
			
		||||
          username: ${{ github.repository_owner }}
 | 
			
		||||
          password: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          platforms: linux/amd64,linux/arm64
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: |
 | 
			
		||||
            user/app:latest
 | 
			
		||||
            user/app:1.0.0
 | 
			
		||||
            ghcr.io/user/app:latest
 | 
			
		||||
            ghcr.io/user/app:1.0.0
 | 
			
		||||
```
 | 
			
		||||
@ -1,84 +0,0 @@
 | 
			
		||||
# Secrets
 | 
			
		||||
 | 
			
		||||
In the following example we will expose and use the [GITHUB_TOKEN secret](https://docs.github.com/en/actions/reference/authentication-in-a-workflow#about-the-github_token-secret)
 | 
			
		||||
as provided by GitHub in your workflow.
 | 
			
		||||
 | 
			
		||||
First let's create our `Dockerfile` to use our secret:
 | 
			
		||||
 | 
			
		||||
```Dockerfile
 | 
			
		||||
#syntax=docker/dockerfile:1.2
 | 
			
		||||
 | 
			
		||||
FROM alpine
 | 
			
		||||
RUN --mount=type=secret,id=github_token \
 | 
			
		||||
  cat /run/secrets/github_token
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
As you can see we have named our secret `github_token`. Here is the workflow you can use to expose this secret using
 | 
			
		||||
the [`secrets` input](../../README.md#inputs):
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Build
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          platforms: linux/amd64,linux/arm64
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
          secrets: |
 | 
			
		||||
            "github_token=${{ secrets.GITHUB_TOKEN }}"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> :bulb: You can also expose a secret file to the build with [`secret-files`](../../README.md#inputs) input:
 | 
			
		||||
> ```yaml
 | 
			
		||||
> secret-files: |
 | 
			
		||||
>   "MY_SECRET=./secret.txt"
 | 
			
		||||
> ```
 | 
			
		||||
 | 
			
		||||
If you're using [GitHub secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) and need to handle
 | 
			
		||||
multi-line value, you will need to place the key-value pair between quotes:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
secrets: |
 | 
			
		||||
  "MYSECRET=${{ secrets.GPG_KEY }}"
 | 
			
		||||
  GIT_AUTH_TOKEN=abcdefghi,jklmno=0123456789
 | 
			
		||||
  "MYSECRET=aaaaaaaa
 | 
			
		||||
  bbbbbbb
 | 
			
		||||
  ccccccccc"
 | 
			
		||||
  FOO=bar
 | 
			
		||||
  "EMPTYLINE=aaaa
 | 
			
		||||
  
 | 
			
		||||
  bbbb
 | 
			
		||||
  ccc"
 | 
			
		||||
  "JSON_SECRET={""key1"":""value1"",""key2"":""value2""}"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
| Key                | Value                                            |
 | 
			
		||||
|--------------------|--------------------------------------------------|
 | 
			
		||||
| `MYSECRET`         | `***********************` |
 | 
			
		||||
| `GIT_AUTH_TOKEN`   | `abcdefghi,jklmno=0123456789` |
 | 
			
		||||
| `MYSECRET`         | `aaaaaaaa\nbbbbbbb\nccccccccc` |
 | 
			
		||||
| `FOO`              | `bar` |
 | 
			
		||||
| `EMPTYLINE`        | `aaaa\n\nbbbb\nccc` |
 | 
			
		||||
| `JSON_SECRET`      | `{"key1":"value1","key2":"value2"}` |
 | 
			
		||||
 | 
			
		||||
> :bulb: All quote signs need to be doubled for escaping.
 | 
			
		||||
@ -1,58 +0,0 @@
 | 
			
		||||
# Share built image between jobs
 | 
			
		||||
 | 
			
		||||
As each job is isolated in its own runner you cannot use your built image between jobs (except for [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners)).
 | 
			
		||||
However, you can [pass data between jobs in a workflow](https://docs.github.com/en/actions/guides/storing-workflow-data-as-artifacts#passing-data-between-jobs-in-a-workflow)
 | 
			
		||||
using the [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/download-artifact](https://github.com/actions/download-artifact)
 | 
			
		||||
actions:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and export
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          tags: myimage:latest
 | 
			
		||||
          outputs: type=docker,dest=/tmp/myimage.tar
 | 
			
		||||
      -
 | 
			
		||||
        name: Upload artifact
 | 
			
		||||
        uses: actions/upload-artifact@v2
 | 
			
		||||
        with:
 | 
			
		||||
          name: myimage
 | 
			
		||||
          path: /tmp/myimage.tar
 | 
			
		||||
 | 
			
		||||
  use:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    needs: build
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Download artifact
 | 
			
		||||
        uses: actions/download-artifact@v2
 | 
			
		||||
        with:
 | 
			
		||||
          name: myimage
 | 
			
		||||
          path: /tmp
 | 
			
		||||
      -
 | 
			
		||||
        name: Load image
 | 
			
		||||
        run: |
 | 
			
		||||
          docker load --input /tmp/myimage.tar
 | 
			
		||||
          docker image ls -a
 | 
			
		||||
```
 | 
			
		||||
@ -1,76 +0,0 @@
 | 
			
		||||
# Handle tags and labels
 | 
			
		||||
 | 
			
		||||
If you want an "automatic" tag management and [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md)
 | 
			
		||||
for labels, you can do it in a dedicated step. The following workflow will use the [Docker metadata action](https://github.com/docker/metadata-action)
 | 
			
		||||
to handle tags and labels based on GitHub actions events and Git metadata.
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '0 10 * * *'
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - '**'
 | 
			
		||||
    tags:
 | 
			
		||||
      - 'v*.*.*'
 | 
			
		||||
  pull_request:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Docker meta
 | 
			
		||||
        id: meta
 | 
			
		||||
        uses: docker/metadata-action@v3
 | 
			
		||||
        with:
 | 
			
		||||
          # list of Docker images to use as base name for tags
 | 
			
		||||
          images: |
 | 
			
		||||
            name/app
 | 
			
		||||
            ghcr.io/username/app
 | 
			
		||||
          # generate Docker tags based on the following events/attributes
 | 
			
		||||
          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 QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        if: github.event_name != 'pull_request'
 | 
			
		||||
        uses: docker/login-action@v1 
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to GHCR
 | 
			
		||||
        if: github.event_name != 'pull_request'
 | 
			
		||||
        uses: docker/login-action@v1
 | 
			
		||||
        with:
 | 
			
		||||
          registry: ghcr.io
 | 
			
		||||
          username: ${{ github.repository_owner }}
 | 
			
		||||
          password: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          push: ${{ github.event_name != 'pull_request' }}
 | 
			
		||||
          tags: ${{ steps.meta.outputs.tags }}
 | 
			
		||||
          labels: ${{ steps.meta.outputs.labels }}
 | 
			
		||||
```
 | 
			
		||||
@ -1,64 +0,0 @@
 | 
			
		||||
# Test your image before pushing it
 | 
			
		||||
 | 
			
		||||
In some cases, you might want to validate that the image works as expected
 | 
			
		||||
before pushing it.
 | 
			
		||||
 | 
			
		||||
The workflow below will be composed of several steps to achieve this:
 | 
			
		||||
* Build and export the image to Docker
 | 
			
		||||
* Test your image
 | 
			
		||||
* Multi-platform build and push the image
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - 'main'
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  TEST_TAG: user/myapp:test
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  docker:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up QEMU
 | 
			
		||||
        uses: docker/setup-qemu-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v1
 | 
			
		||||
      -
 | 
			
		||||
        name: Login to DockerHub
 | 
			
		||||
        uses: docker/login-action@v1
 | 
			
		||||
        with:
 | 
			
		||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
			
		||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and export to Docker
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          load: true
 | 
			
		||||
          tags: ${{ env.TEST_TAG }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Test
 | 
			
		||||
        run: |
 | 
			
		||||
          docker run --rm ${{ env.TEST_TAG }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        uses: docker/build-push-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          context: .
 | 
			
		||||
          platforms: linux/amd64,linux/arm64
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> :bulb: Build time will not be increased with this workflow because internal
 | 
			
		||||
> cache for `linux/amd64` will be used from previous step on `Build and push`
 | 
			
		||||
> step so only `linux/arm64` will be actually built.
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
module.exports = {
 | 
			
		||||
  clearMocks: false,
 | 
			
		||||
  moduleFileExtensions: ['js', 'ts'],
 | 
			
		||||
  setupFiles: ["dotenv/config"],
 | 
			
		||||
  testEnvironment: 'node',
 | 
			
		||||
  testMatch: ['**/*.test.ts'],
 | 
			
		||||
  testRunner: 'jest-circus/runner',
 | 
			
		||||
  transform: {
 | 
			
		||||
    '^.+\\.ts$': 'ts-jest'
 | 
			
		||||
  },
 | 
			
		||||
  verbose: false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								jest.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								jest.config.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
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, {
 | 
			
		||||
  TEMP: tmpDir,
 | 
			
		||||
  GITHUB_REPOSITORY: 'docker/build-push-action',
 | 
			
		||||
  RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
 | 
			
		||||
  RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
 | 
			
		||||
}) as {
 | 
			
		||||
  [key: string]: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  clearMocks: false,
 | 
			
		||||
  testEnvironment: 'node',
 | 
			
		||||
  moduleFileExtensions: ['js', 'ts'],
 | 
			
		||||
  testMatch: ['**/*.test.ts'],
 | 
			
		||||
  transform: {
 | 
			
		||||
    '^.+\\.ts$': 'ts-jest'
 | 
			
		||||
  },
 | 
			
		||||
  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
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										60
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								package.json
									
									
									
									
									
								
							@ -1,13 +1,16 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "docker-build-push",
 | 
			
		||||
  "description": "Build and push Docker images",
 | 
			
		||||
  "main": "lib/main.js",
 | 
			
		||||
  "main": "src/main.ts",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "build": "tsc && ncc build",
 | 
			
		||||
    "format": "prettier --write **/*.ts",
 | 
			
		||||
    "format-check": "prettier --check **/*.ts",
 | 
			
		||||
    "test": "jest --coverage",
 | 
			
		||||
    "pre-checkin": "yarn run format && yarn run build"
 | 
			
		||||
    "build": "ncc build --source-map --minify --license licenses.txt",
 | 
			
		||||
    "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"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
@ -19,36 +22,27 @@
 | 
			
		||||
    "build",
 | 
			
		||||
    "push"
 | 
			
		||||
  ],
 | 
			
		||||
  "author": "Docker",
 | 
			
		||||
  "contributors": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "CrazyMax",
 | 
			
		||||
      "url": "https://crazymax.dev"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "author": "Docker Inc.",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "packageManager": "yarn@3.6.3",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@actions/core": "^1.6.0",
 | 
			
		||||
    "@actions/exec": "^1.1.0",
 | 
			
		||||
    "@actions/github": "^5.0.0",
 | 
			
		||||
    "csv-parse": "^4.16.3",
 | 
			
		||||
    "handlebars": "^4.7.7",
 | 
			
		||||
    "semver": "^7.3.5",
 | 
			
		||||
    "tmp": "^0.2.1"
 | 
			
		||||
    "@actions/core": "^1.11.1",
 | 
			
		||||
    "@docker/actions-toolkit": "0.59.0",
 | 
			
		||||
    "handlebars": "^4.7.7"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/csv-parse": "^1.2.2",
 | 
			
		||||
    "@types/jest": "^26.0.23",
 | 
			
		||||
    "@types/node": "^14.17.4",
 | 
			
		||||
    "@types/tmp": "^0.2.0",
 | 
			
		||||
    "@vercel/ncc": "^0.28.6",
 | 
			
		||||
    "dotenv": "^8.6.0",
 | 
			
		||||
    "jest": "^26.6.3",
 | 
			
		||||
    "jest-circus": "^26.6.3",
 | 
			
		||||
    "jest-runtime": "^26.6.3",
 | 
			
		||||
    "prettier": "^2.3.1",
 | 
			
		||||
    "ts-jest": "^26.5.6",
 | 
			
		||||
    "typescript": "^4.3.4",
 | 
			
		||||
    "typescript-formatter": "^7.2.2"
 | 
			
		||||
    "@types/node": "^20.12.12",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^7.9.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^7.9.0",
 | 
			
		||||
    "@vercel/ncc": "^0.38.1",
 | 
			
		||||
    "eslint": "^8.57.0",
 | 
			
		||||
    "eslint-config-prettier": "^9.1.0",
 | 
			
		||||
    "eslint-plugin-jest": "^28.5.0",
 | 
			
		||||
    "eslint-plugin-prettier": "^5.1.3",
 | 
			
		||||
    "jest": "^29.7.0",
 | 
			
		||||
    "prettier": "^3.2.5",
 | 
			
		||||
    "ts-jest": "^29.1.2",
 | 
			
		||||
    "ts-node": "^10.9.2",
 | 
			
		||||
    "typescript": "^5.4.5"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										147
									
								
								src/buildx.ts
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								src/buildx.ts
									
									
									
									
									
								
							@ -1,147 +0,0 @@
 | 
			
		||||
import csvparse from 'csv-parse/lib/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 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 {
 | 
			
		||||
  for (let output of csvparse(outputs.join(`\n`), {
 | 
			
		||||
    delimiter: ',',
 | 
			
		||||
    trim: true,
 | 
			
		||||
    columns: false,
 | 
			
		||||
    relaxColumnCount: true
 | 
			
		||||
  })) {
 | 
			
		||||
    // Local if no type is defined
 | 
			
		||||
    // https://github.com/docker/buildx/blob/d2bf42f8b4784d83fde17acb3ed84703ddc2156b/build/output.go#L29-L43
 | 
			
		||||
    if (output.length == 1 && !output[0].startsWith('type=')) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    for (let [key, value] of output.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 (let secret of secrets) {
 | 
			
		||||
    if (secret.startsWith('GIT_AUTH_TOKEN=')) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function isAvailable(): Promise<Boolean> {
 | 
			
		||||
  return await exec
 | 
			
		||||
    .getExecOutput('docker', ['buildx'], {
 | 
			
		||||
      ignoreReturnCode: true,
 | 
			
		||||
      silent: true
 | 
			
		||||
    })
 | 
			
		||||
    .then(res => {
 | 
			
		||||
      if (res.stderr.length > 0 && res.exitCode != 0) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      return res.exitCode == 0;
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getVersion(): Promise<string> {
 | 
			
		||||
  return await exec
 | 
			
		||||
    .getExecOutput('docker', ['buildx', 'version'], {
 | 
			
		||||
      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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										306
									
								
								src/context.ts
									
									
									
									
									
								
							
							
						
						
									
										306
									
								
								src/context.ts
									
									
									
									
									
								
							@ -1,201 +1,223 @@
 | 
			
		||||
import csvparse from 'csv-parse/lib/sync';
 | 
			
		||||
import * as fs from 'fs';
 | 
			
		||||
import * as os from 'os';
 | 
			
		||||
import * as path from 'path';
 | 
			
		||||
import * as tmp from 'tmp';
 | 
			
		||||
 | 
			
		||||
import * as core from '@actions/core';
 | 
			
		||||
import {issueCommand} from '@actions/core/lib/command';
 | 
			
		||||
import * as github from '@actions/github';
 | 
			
		||||
 | 
			
		||||
import * as buildx from './buildx';
 | 
			
		||||
import * as handlebars from 'handlebars';
 | 
			
		||||
 | 
			
		||||
let _defaultContext, _tmpDir: string;
 | 
			
		||||
import {Build} from '@docker/actions-toolkit/lib/buildx/build';
 | 
			
		||||
import {Context} from '@docker/actions-toolkit/lib/context';
 | 
			
		||||
import {GitHub} from '@docker/actions-toolkit/lib/github';
 | 
			
		||||
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
 | 
			
		||||
import {Util} from '@docker/actions-toolkit/lib/util';
 | 
			
		||||
 | 
			
		||||
export interface Inputs {
 | 
			
		||||
  addHosts: string[];
 | 
			
		||||
  'add-hosts': string[];
 | 
			
		||||
  allow: string[];
 | 
			
		||||
  buildArgs: string[];
 | 
			
		||||
  buildContexts: string[];
 | 
			
		||||
  annotations: string[];
 | 
			
		||||
  attests: string[];
 | 
			
		||||
  'build-args': string[];
 | 
			
		||||
  'build-contexts': string[];
 | 
			
		||||
  builder: string;
 | 
			
		||||
  cacheFrom: string[];
 | 
			
		||||
  cacheTo: string[];
 | 
			
		||||
  cgroupParent: string;
 | 
			
		||||
  'cache-from': string[];
 | 
			
		||||
  'cache-to': string[];
 | 
			
		||||
  call: string;
 | 
			
		||||
  'cgroup-parent': string;
 | 
			
		||||
  context: string;
 | 
			
		||||
  file: string;
 | 
			
		||||
  labels: string[];
 | 
			
		||||
  load: boolean;
 | 
			
		||||
  network: string;
 | 
			
		||||
  noCache: boolean;
 | 
			
		||||
  'no-cache': boolean;
 | 
			
		||||
  'no-cache-filters': string[];
 | 
			
		||||
  outputs: string[];
 | 
			
		||||
  platforms: string[];
 | 
			
		||||
  provenance: string;
 | 
			
		||||
  pull: boolean;
 | 
			
		||||
  push: boolean;
 | 
			
		||||
  sbom: string;
 | 
			
		||||
  secrets: string[];
 | 
			
		||||
  secretFiles: string[];
 | 
			
		||||
  shmSize: string;
 | 
			
		||||
  'secret-envs': string[];
 | 
			
		||||
  'secret-files': string[];
 | 
			
		||||
  'shm-size': string;
 | 
			
		||||
  ssh: string[];
 | 
			
		||||
  tags: string[];
 | 
			
		||||
  target: string;
 | 
			
		||||
  ulimit: string[];
 | 
			
		||||
  githubToken: string;
 | 
			
		||||
  'github-token': 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 async function getInputs(defaultContext: string): Promise<Inputs> {
 | 
			
		||||
export async function getInputs(): Promise<Inputs> {
 | 
			
		||||
  return {
 | 
			
		||||
    addHosts: await getInputList('add-hosts'),
 | 
			
		||||
    allow: await getInputList('allow'),
 | 
			
		||||
    buildArgs: await getInputList('build-args', true),
 | 
			
		||||
    buildContexts: await getInputList('build-contexts', true),
 | 
			
		||||
    'add-hosts': Util.getInputList('add-hosts'),
 | 
			
		||||
    allow: Util.getInputList('allow'),
 | 
			
		||||
    annotations: Util.getInputList('annotations', {ignoreComma: true}),
 | 
			
		||||
    attests: Util.getInputList('attests', {ignoreComma: true}),
 | 
			
		||||
    'build-args': Util.getInputList('build-args', {ignoreComma: true}),
 | 
			
		||||
    'build-contexts': Util.getInputList('build-contexts', {ignoreComma: true}),
 | 
			
		||||
    builder: core.getInput('builder'),
 | 
			
		||||
    cacheFrom: await getInputList('cache-from', true),
 | 
			
		||||
    cacheTo: await getInputList('cache-to', true),
 | 
			
		||||
    cgroupParent: core.getInput('cgroup-parent'),
 | 
			
		||||
    context: core.getInput('context') || defaultContext,
 | 
			
		||||
    'cache-from': Util.getInputList('cache-from', {ignoreComma: true}),
 | 
			
		||||
    'cache-to': Util.getInputList('cache-to', {ignoreComma: true}),
 | 
			
		||||
    call: core.getInput('call'),
 | 
			
		||||
    'cgroup-parent': core.getInput('cgroup-parent'),
 | 
			
		||||
    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'),
 | 
			
		||||
    outputs: await getInputList('outputs', true),
 | 
			
		||||
    platforms: await getInputList('platforms'),
 | 
			
		||||
    'no-cache': core.getBooleanInput('no-cache'),
 | 
			
		||||
    'no-cache-filters': Util.getInputList('no-cache-filters'),
 | 
			
		||||
    outputs: Util.getInputList('outputs', {ignoreComma: true, quote: false}),
 | 
			
		||||
    platforms: Util.getInputList('platforms'),
 | 
			
		||||
    provenance: Build.getProvenanceInput('provenance'),
 | 
			
		||||
    pull: core.getBooleanInput('pull'),
 | 
			
		||||
    push: core.getBooleanInput('push'),
 | 
			
		||||
    secrets: await getInputList('secrets', true),
 | 
			
		||||
    secretFiles: await getInputList('secret-files', true),
 | 
			
		||||
    shmSize: core.getInput('shm-size'),
 | 
			
		||||
    ssh: await getInputList('ssh'),
 | 
			
		||||
    tags: await getInputList('tags'),
 | 
			
		||||
    sbom: core.getInput('sbom'),
 | 
			
		||||
    secrets: Util.getInputList('secrets', {ignoreComma: true}),
 | 
			
		||||
    'secret-envs': Util.getInputList('secret-envs'),
 | 
			
		||||
    'secret-files': Util.getInputList('secret-files', {ignoreComma: true}),
 | 
			
		||||
    'shm-size': core.getInput('shm-size'),
 | 
			
		||||
    ssh: Util.getInputList('ssh'),
 | 
			
		||||
    tags: Util.getInputList('tags'),
 | 
			
		||||
    target: core.getInput('target'),
 | 
			
		||||
    ulimit: await getInputList('ulimit', true),
 | 
			
		||||
    githubToken: core.getInput('github-token')
 | 
			
		||||
    ulimit: Util.getInputList('ulimit', {ignoreComma: true}),
 | 
			
		||||
    'github-token': core.getInput('github-token')
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
 | 
			
		||||
  let args: Array<string> = ['buildx'];
 | 
			
		||||
  args.push.apply(args, await getBuildArgs(inputs, defaultContext, buildxVersion));
 | 
			
		||||
  args.push.apply(args, await getCommonArgs(inputs, buildxVersion));
 | 
			
		||||
  args.push(handlebars.compile(inputs.context)({defaultContext}));
 | 
			
		||||
  return args;
 | 
			
		||||
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, context, toolkit),
 | 
			
		||||
    ...await getCommonArgs(inputs, toolkit),
 | 
			
		||||
    context
 | 
			
		||||
  ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
 | 
			
		||||
  let args: Array<string> = ['build'];
 | 
			
		||||
  await asyncForEach(inputs.addHosts, async addHost => {
 | 
			
		||||
async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit): Promise<Array<string>> {
 | 
			
		||||
  const args: Array<string> = ['build'];
 | 
			
		||||
  await Util.asyncForEach(inputs['add-hosts'], async addHost => {
 | 
			
		||||
    args.push('--add-host', addHost);
 | 
			
		||||
  });
 | 
			
		||||
  if (inputs.allow.length > 0) {
 | 
			
		||||
    args.push('--allow', inputs.allow.join(','));
 | 
			
		||||
  await Util.asyncForEach(inputs.allow, async allow => {
 | 
			
		||||
    args.push('--allow', allow);
 | 
			
		||||
  });
 | 
			
		||||
  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 asyncForEach(inputs.buildArgs, async buildArg => {
 | 
			
		||||
  await Util.asyncForEach(inputs['build-args'], async buildArg => {
 | 
			
		||||
    args.push('--build-arg', buildArg);
 | 
			
		||||
  });
 | 
			
		||||
  if (buildx.satisfies(buildxVersion, '>=0.8.0')) {
 | 
			
		||||
    await asyncForEach(inputs.buildContexts, async buildContext => {
 | 
			
		||||
      args.push('--build-context', buildContext);
 | 
			
		||||
  if (await toolkit.buildx.versionSatisfies('>=0.8.0')) {
 | 
			
		||||
    await Util.asyncForEach(inputs['build-contexts'], async buildContext => {
 | 
			
		||||
      args.push(
 | 
			
		||||
        '--build-context',
 | 
			
		||||
        handlebars.compile(buildContext)({
 | 
			
		||||
          defaultContext: Context.gitContext()
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  } else if (inputs['build-contexts'].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['cache-from'], async cacheFrom => {
 | 
			
		||||
    args.push('--cache-from', cacheFrom);
 | 
			
		||||
  });
 | 
			
		||||
  await asyncForEach(inputs.cacheTo, async cacheTo => {
 | 
			
		||||
  await Util.asyncForEach(inputs['cache-to'], async cacheTo => {
 | 
			
		||||
    args.push('--cache-to', cacheTo);
 | 
			
		||||
  });
 | 
			
		||||
  if (inputs.cgroupParent) {
 | 
			
		||||
    args.push('--cgroup-parent', inputs.cgroupParent);
 | 
			
		||||
  if (inputs.call) {
 | 
			
		||||
    if (!(await toolkit.buildx.versionSatisfies('>=0.15.0'))) {
 | 
			
		||||
      throw new Error(`Buildx >= 0.15.0 is required to use the call flag.`);
 | 
			
		||||
    }
 | 
			
		||||
    args.push('--call', inputs.call);
 | 
			
		||||
  }
 | 
			
		||||
  if (inputs['cgroup-parent']) {
 | 
			
		||||
    args.push('--cgroup-parent', inputs['cgroup-parent']);
 | 
			
		||||
  }
 | 
			
		||||
  await Util.asyncForEach(inputs['secret-envs'], async secretEnv => {
 | 
			
		||||
    try {
 | 
			
		||||
      args.push('--secret', Build.resolveSecretEnv(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 (!Build.hasLocalExporter(inputs.outputs) && !Build.hasTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || (await toolkit.buildx.versionSatisfies('>=0.4.2')))) {
 | 
			
		||||
    args.push('--iidfile', toolkit.buildxBuild.getImageIDFilePath());
 | 
			
		||||
  }
 | 
			
		||||
  await asyncForEach(inputs.labels, async label => {
 | 
			
		||||
  await Util.asyncForEach(inputs.labels, async label => {
 | 
			
		||||
    args.push('--label', label);
 | 
			
		||||
  });
 | 
			
		||||
  await asyncForEach(inputs.outputs, async output => {
 | 
			
		||||
  await Util.asyncForEach(inputs['no-cache-filters'], async noCacheFilter => {
 | 
			
		||||
    args.push('--no-cache-filter', noCacheFilter);
 | 
			
		||||
  });
 | 
			
		||||
  await Util.asyncForEach(inputs.outputs, async output => {
 | 
			
		||||
    args.push('--output', output);
 | 
			
		||||
  });
 | 
			
		||||
  if (inputs.platforms.length > 0) {
 | 
			
		||||
    args.push('--platform', inputs.platforms.join(','));
 | 
			
		||||
  }
 | 
			
		||||
  await asyncForEach(inputs.secrets, async secret => {
 | 
			
		||||
  if (await toolkit.buildx.versionSatisfies('>=0.10.0')) {
 | 
			
		||||
    args.push(...(await getAttestArgs(inputs, toolkit)));
 | 
			
		||||
  } else {
 | 
			
		||||
    core.warning("Attestations are only supported by buildx >= 0.10.0; the inputs 'attests', 'provenance' and 'sbom' are ignored.");
 | 
			
		||||
  }
 | 
			
		||||
  await Util.asyncForEach(inputs.secrets, async secret => {
 | 
			
		||||
    try {
 | 
			
		||||
      args.push('--secret', await buildx.getSecretString(secret));
 | 
			
		||||
      args.push('--secret', Build.resolveSecretString(secret));
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      core.warning(err.message);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  await asyncForEach(inputs.secretFiles, async secretFile => {
 | 
			
		||||
  await Util.asyncForEach(inputs['secret-files'], async secretFile => {
 | 
			
		||||
    try {
 | 
			
		||||
      args.push('--secret', await buildx.getSecretFile(secretFile));
 | 
			
		||||
      args.push('--secret', Build.resolveSecretFile(secretFile));
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      core.warning(err.message);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) {
 | 
			
		||||
    args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
 | 
			
		||||
  if (inputs['github-token'] && !Build.hasGitAuthTokenSecret(inputs.secrets) && context.startsWith(Context.gitContext())) {
 | 
			
		||||
    args.push('--secret', Build.resolveSecretString(`GIT_AUTH_TOKEN=${inputs['github-token']}`));
 | 
			
		||||
  }
 | 
			
		||||
  if (inputs.shmSize) {
 | 
			
		||||
    args.push('--shm-size', inputs.shmSize);
 | 
			
		||||
  if (inputs['shm-size']) {
 | 
			
		||||
    args.push('--shm-size', inputs['shm-size']);
 | 
			
		||||
  }
 | 
			
		||||
  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>> {
 | 
			
		||||
  let args: Array<string> = [];
 | 
			
		||||
async function getCommonArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
 | 
			
		||||
  const args: Array<string> = [];
 | 
			
		||||
  if (inputs.builder) {
 | 
			
		||||
    args.push('--builder', inputs.builder);
 | 
			
		||||
  }
 | 
			
		||||
  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', toolkit.buildxBuild.getMetadataFilePath());
 | 
			
		||||
  }
 | 
			
		||||
  if (inputs.network) {
 | 
			
		||||
    args.push('--network', inputs.network);
 | 
			
		||||
  }
 | 
			
		||||
  if (inputs.noCache) {
 | 
			
		||||
  if (inputs['no-cache']) {
 | 
			
		||||
    args.push('--no-cache');
 | 
			
		||||
  }
 | 
			
		||||
  if (inputs.pull) {
 | 
			
		||||
@ -207,40 +229,58 @@ async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Arr
 | 
			
		||||
  return args;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> {
 | 
			
		||||
  let res: Array<string> = [];
 | 
			
		||||
async function getAttestArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
 | 
			
		||||
  const args: Array<string> = [];
 | 
			
		||||
 | 
			
		||||
  const items = core.getInput(name);
 | 
			
		||||
  if (items == '') {
 | 
			
		||||
    return res;
 | 
			
		||||
  // check if provenance attestation is set in attests input
 | 
			
		||||
  let hasAttestProvenance = false;
 | 
			
		||||
  await Util.asyncForEach(inputs.attests, async (attest: string) => {
 | 
			
		||||
    if (Build.hasAttestationType('provenance', attest)) {
 | 
			
		||||
      hasAttestProvenance = true;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  let provenanceSet = false;
 | 
			
		||||
  let sbomSet = false;
 | 
			
		||||
  if (inputs.provenance) {
 | 
			
		||||
    args.push('--attest', Build.resolveAttestationAttrs(`type=provenance,${inputs.provenance}`));
 | 
			
		||||
    provenanceSet = true;
 | 
			
		||||
  } else if (!hasAttestProvenance && !noDefaultAttestations() && (await toolkit.buildkit.versionSatisfies(inputs.builder, '>=0.11.0')) && !Build.hasDockerExporter(inputs.outputs, inputs.load)) {
 | 
			
		||||
    // if provenance not specified in provenance or attests inputs 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.
 | 
			
		||||
    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('--attest', `type=provenance,${Build.resolveProvenanceAttrs(`mode=min,inline-only=true`)}`);
 | 
			
		||||
    } else {
 | 
			
		||||
      // for a public repository, we set max provenance mode.
 | 
			
		||||
      args.push('--attest', `type=provenance,${Build.resolveProvenanceAttrs(`mode=max`)}`);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (inputs.sbom) {
 | 
			
		||||
    args.push('--attest', Build.resolveAttestationAttrs(`type=sbom,${inputs.sbom}`));
 | 
			
		||||
    sbomSet = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (let output of (await csvparse(items, {
 | 
			
		||||
    columns: false,
 | 
			
		||||
    relax: true,
 | 
			
		||||
    relaxColumnCount: true,
 | 
			
		||||
    skipLinesWithEmptyValues: true
 | 
			
		||||
  })) as Array<string[]>) {
 | 
			
		||||
    if (output.length == 1) {
 | 
			
		||||
      res.push(output[0]);
 | 
			
		||||
      continue;
 | 
			
		||||
    } else if (!ignoreComma) {
 | 
			
		||||
      res.push(...output);
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    res.push(output.join(','));
 | 
			
		||||
  // set attests but check if provenance or sbom types already set as
 | 
			
		||||
  // provenance and sbom inputs take precedence over attests input.
 | 
			
		||||
  await Util.asyncForEach(inputs.attests, async (attest: string) => {
 | 
			
		||||
    if (!Build.hasAttestationType('provenance', attest) && !Build.hasAttestationType('sbom', attest)) {
 | 
			
		||||
      args.push('--attest', Build.resolveAttestationAttrs(attest));
 | 
			
		||||
    } else if (!provenanceSet && Build.hasAttestationType('provenance', attest)) {
 | 
			
		||||
      args.push('--attest', Build.resolveProvenanceAttrs(attest));
 | 
			
		||||
    } else if (!sbomSet && Build.hasAttestationType('sbom', attest)) {
 | 
			
		||||
      args.push('--attest', attest);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return res.filter(item => item).map(pat => pat.trim());
 | 
			
		||||
  return args;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const asyncForEach = async (array, callback) => {
 | 
			
		||||
  for (let index = 0; index < array.length; index++) {
 | 
			
		||||
    await callback(array[index], index, array);
 | 
			
		||||
function noDefaultAttestations(): boolean {
 | 
			
		||||
  if (process.env.BUILDX_NO_DEFAULT_ATTESTATIONS) {
 | 
			
		||||
    return Util.parseBool(process.env.BUILDX_NO_DEFAULT_ATTESTATIONS);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// FIXME: Temp fix https://github.com/actions/toolkit/issues/777
 | 
			
		||||
export function setOutput(name: string, value: any): void {
 | 
			
		||||
  issueCommand('set-output', {name}, value);
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										313
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										313
									
								
								src/main.ts
									
									
									
									
									
								
							@ -1,75 +1,296 @@
 | 
			
		||||
import * as fs from 'fs';
 | 
			
		||||
import * as buildx from './buildx';
 | 
			
		||||
import * as context from './context';
 | 
			
		||||
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';
 | 
			
		||||
 | 
			
		||||
async function run(): Promise<void> {
 | 
			
		||||
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
 | 
			
		||||
import {History as BuildxHistory} from '@docker/actions-toolkit/lib/buildx/history';
 | 
			
		||||
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 {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
 | 
			
		||||
import {Util} from '@docker/actions-toolkit/lib/util';
 | 
			
		||||
 | 
			
		||||
import {BuilderInfo} from '@docker/actions-toolkit/lib/types/buildx/builder';
 | 
			
		||||
import {ConfigFile} from '@docker/actions-toolkit/lib/types/docker/docker';
 | 
			
		||||
import {UploadArtifactResponse} from '@docker/actions-toolkit/lib/types/github';
 | 
			
		||||
 | 
			
		||||
import * as context from './context';
 | 
			
		||||
 | 
			
		||||
actionsToolkit.run(
 | 
			
		||||
  // main
 | 
			
		||||
  async () => {
 | 
			
		||||
    const startedTime = new Date();
 | 
			
		||||
    const inputs: context.Inputs = await context.getInputs();
 | 
			
		||||
    stateHelper.setSummaryInputs(inputs);
 | 
			
		||||
    core.debug(`inputs: ${JSON.stringify(inputs)}`);
 | 
			
		||||
 | 
			
		||||
    const toolkit = new Toolkit();
 | 
			
		||||
 | 
			
		||||
    await core.group(`GitHub Actions runtime token ACs`, async () => {
 | 
			
		||||
      try {
 | 
			
		||||
    core.startGroup(`Docker info`);
 | 
			
		||||
    await exec.exec('docker', ['version']);
 | 
			
		||||
    await exec.exec('docker', ['info']);
 | 
			
		||||
    core.endGroup();
 | 
			
		||||
 | 
			
		||||
    if (!(await 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();
 | 
			
		||||
    const defContext = context.defaultContext();
 | 
			
		||||
    let inputs: context.Inputs = await context.getInputs(defContext);
 | 
			
		||||
 | 
			
		||||
    const args: string[] = await context.getArgs(inputs, defContext, buildxVersion);
 | 
			
		||||
    await exec
 | 
			
		||||
      .getExecOutput('docker', 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()}`);
 | 
			
		||||
        await GitHub.printActionsRuntimeTokenACs();
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        core.warning(e.message);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const imageID = await buildx.getImageID();
 | 
			
		||||
    const metadata = await buildx.getMetadata();
 | 
			
		||||
    const digest = await buildx.getDigest(metadata);
 | 
			
		||||
    await core.group(`Docker info`, async () => {
 | 
			
		||||
      try {
 | 
			
		||||
        await Docker.printVersion();
 | 
			
		||||
        await Docker.printInfo();
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        core.info(e.message);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    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());
 | 
			
		||||
 | 
			
		||||
    await core.group(`Buildx version`, async () => {
 | 
			
		||||
      await toolkit.buildx.printVersion();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let builder: BuilderInfo;
 | 
			
		||||
    await core.group(`Builder info`, async () => {
 | 
			
		||||
      builder = await toolkit.builder.inspect(inputs.builder);
 | 
			
		||||
      core.info(JSON.stringify(builder, null, 2));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const args: string[] = await context.getArgs(inputs, toolkit);
 | 
			
		||||
    core.debug(`context.getArgs: ${JSON.stringify(args)}`);
 | 
			
		||||
 | 
			
		||||
    const buildCmd = await toolkit.buildx.getCommand(args);
 | 
			
		||||
    core.debug(`buildCmd.command: ${buildCmd.command}`);
 | 
			
		||||
    core.debug(`buildCmd.args: ${JSON.stringify(buildCmd.args)}`);
 | 
			
		||||
 | 
			
		||||
    let err: Error | undefined;
 | 
			
		||||
    await Exec.getExecOutput(buildCmd.command, buildCmd.args, {
 | 
			
		||||
      ignoreReturnCode: true,
 | 
			
		||||
      env: Object.assign({}, process.env, {
 | 
			
		||||
        BUILDX_METADATA_WARNINGS: 'true'
 | 
			
		||||
      }) as {
 | 
			
		||||
        [key: string]: string;
 | 
			
		||||
      }
 | 
			
		||||
    }).then(res => {
 | 
			
		||||
      if (res.exitCode != 0) {
 | 
			
		||||
        if (inputs.call && inputs.call === 'check' && res.stdout.length > 0) {
 | 
			
		||||
          // checks warnings are printed to stdout: https://github.com/docker/buildx/pull/2647
 | 
			
		||||
          // take the first line with the message summaryzing the warnings
 | 
			
		||||
          err = new Error(res.stdout.split('\n')[0]?.trim());
 | 
			
		||||
        } else if (res.stderr.length > 0) {
 | 
			
		||||
          err = new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const imageID = toolkit.buildxBuild.resolveImageID();
 | 
			
		||||
    const metadata = toolkit.buildxBuild.resolveMetadata();
 | 
			
		||||
    const digest = toolkit.buildxBuild.resolveDigest(metadata);
 | 
			
		||||
    if (imageID) {
 | 
			
		||||
      await core.group(`ImageID`, async () => {
 | 
			
		||||
        core.info(imageID);
 | 
			
		||||
        context.setOutput('imageid', imageID);
 | 
			
		||||
        core.setOutput('imageid', imageID);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    if (digest) {
 | 
			
		||||
      await core.group(`Digest`, async () => {
 | 
			
		||||
        core.info(digest);
 | 
			
		||||
        context.setOutput('digest', digest);
 | 
			
		||||
        core.setOutput('digest', digest);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    if (metadata) {
 | 
			
		||||
      await core.group(`Metadata`, async () => {
 | 
			
		||||
        core.info(metadata);
 | 
			
		||||
        context.setOutput('metadata', metadata);
 | 
			
		||||
        const metadatadt = JSON.stringify(metadata, null, 2);
 | 
			
		||||
        core.info(metadatadt);
 | 
			
		||||
        core.setOutput('metadata', metadatadt);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    core.setFailed(error.message);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function cleanup(): Promise<void> {
 | 
			
		||||
    let ref: string | undefined;
 | 
			
		||||
    await core.group(`Reference`, async () => {
 | 
			
		||||
      ref = await buildRef(toolkit, startedTime, inputs.builder);
 | 
			
		||||
      if (ref) {
 | 
			
		||||
        core.info(ref);
 | 
			
		||||
        stateHelper.setBuildRef(ref);
 | 
			
		||||
      } else {
 | 
			
		||||
        core.info('No build reference found');
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (buildChecksAnnotationsEnabled()) {
 | 
			
		||||
      const warnings = toolkit.buildxBuild.resolveWarnings(metadata);
 | 
			
		||||
      if (ref && warnings && warnings.length > 0) {
 | 
			
		||||
        const annotations = await Buildx.convertWarningsToGitHubAnnotations(warnings, [ref]);
 | 
			
		||||
        core.debug(`annotations: ${JSON.stringify(annotations, null, 2)}`);
 | 
			
		||||
        if (annotations && annotations.length > 0) {
 | 
			
		||||
          await core.group(`Generating GitHub annotations (${annotations.length} build checks found)`, async () => {
 | 
			
		||||
            for (const annotation of annotations) {
 | 
			
		||||
              core.warning(annotation.message, annotation);
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    await core.group(`Check build summary support`, async () => {
 | 
			
		||||
      if (!buildSummaryEnabled()) {
 | 
			
		||||
        core.info('Build summary disabled');
 | 
			
		||||
      } else if (inputs.call && inputs.call !== 'build') {
 | 
			
		||||
        core.info(`Build summary skipped for ${inputs.call} subrequest`);
 | 
			
		||||
      } else if (GitHub.isGHES) {
 | 
			
		||||
        core.info('Build summary is not yet supported on GHES');
 | 
			
		||||
      } else if (!(await toolkit.buildx.versionSatisfies('>=0.13.0'))) {
 | 
			
		||||
        core.info('Build summary requires Buildx >= 0.13.0');
 | 
			
		||||
      } else if (builder && builder.driver === 'cloud') {
 | 
			
		||||
        core.info('Build summary is not yet supported with Docker Build Cloud');
 | 
			
		||||
      } else if (!ref) {
 | 
			
		||||
        core.info('Build summary requires a build reference');
 | 
			
		||||
      } else {
 | 
			
		||||
        core.info('Build summary supported!');
 | 
			
		||||
        stateHelper.setSummarySupported();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (err) {
 | 
			
		||||
      throw err;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  // post
 | 
			
		||||
  async () => {
 | 
			
		||||
    if (stateHelper.isSummarySupported) {
 | 
			
		||||
      await core.group(`Generating build summary`, async () => {
 | 
			
		||||
        try {
 | 
			
		||||
          const recordUploadEnabled = buildRecordUploadEnabled();
 | 
			
		||||
          let recordRetentionDays: number | undefined;
 | 
			
		||||
          if (recordUploadEnabled) {
 | 
			
		||||
            recordRetentionDays = buildRecordRetentionDays();
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          const buildxHistory = new BuildxHistory();
 | 
			
		||||
          const exportRes = await buildxHistory.export({
 | 
			
		||||
            refs: stateHelper.buildRef ? [stateHelper.buildRef] : []
 | 
			
		||||
          });
 | 
			
		||||
          core.info(`Build record written to ${exportRes.dockerbuildFilename} (${Util.formatFileSize(exportRes.dockerbuildSize)})`);
 | 
			
		||||
 | 
			
		||||
          let uploadRes: UploadArtifactResponse | undefined;
 | 
			
		||||
          if (recordUploadEnabled) {
 | 
			
		||||
            uploadRes = await GitHub.uploadArtifact({
 | 
			
		||||
              filename: exportRes.dockerbuildFilename,
 | 
			
		||||
              mimeType: 'application/gzip',
 | 
			
		||||
              retentionDays: recordRetentionDays
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          await GitHub.writeBuildSummary({
 | 
			
		||||
            exportRes: exportRes,
 | 
			
		||||
            uploadRes: uploadRes,
 | 
			
		||||
            inputs: stateHelper.summaryInputs
 | 
			
		||||
          });
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          core.warning(e.message);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    if (stateHelper.tmpDir.length > 0) {
 | 
			
		||||
    core.startGroup(`Removing temp folder ${stateHelper.tmpDir}`);
 | 
			
		||||
    fs.rmdirSync(stateHelper.tmpDir, {recursive: true});
 | 
			
		||||
    core.endGroup();
 | 
			
		||||
      await core.group(`Removing temp folder ${stateHelper.tmpDir}`, async () => {
 | 
			
		||||
        try {
 | 
			
		||||
          fs.rmSync(stateHelper.tmpDir, {recursive: true});
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          core.warning(`Failed to remove temp folder ${stateHelper.tmpDir}`);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
async function buildRef(toolkit: Toolkit, since: Date, builder?: string): Promise<string> {
 | 
			
		||||
  // get ref from metadata file
 | 
			
		||||
  const ref = toolkit.buildxBuild.resolveRef();
 | 
			
		||||
  if (ref) {
 | 
			
		||||
    return ref;
 | 
			
		||||
  }
 | 
			
		||||
  // otherwise, look for the very first build ref since the build has started
 | 
			
		||||
  if (!builder) {
 | 
			
		||||
    const currentBuilder = await toolkit.builder.inspect();
 | 
			
		||||
    builder = currentBuilder.name;
 | 
			
		||||
  }
 | 
			
		||||
  const refs = Buildx.refs({
 | 
			
		||||
    dir: Buildx.refsDir,
 | 
			
		||||
    builderName: builder,
 | 
			
		||||
    since: since
 | 
			
		||||
  });
 | 
			
		||||
  return Object.keys(refs).length > 0 ? Object.keys(refs)[0] : '';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!stateHelper.IsPost) {
 | 
			
		||||
  run();
 | 
			
		||||
} else {
 | 
			
		||||
  cleanup();
 | 
			
		||||
function buildChecksAnnotationsEnabled(): boolean {
 | 
			
		||||
  if (process.env.DOCKER_BUILD_CHECKS_ANNOTATIONS) {
 | 
			
		||||
    return Util.parseBool(process.env.DOCKER_BUILD_CHECKS_ANNOTATIONS);
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function buildSummaryEnabled(): boolean {
 | 
			
		||||
  if (process.env.DOCKER_BUILD_NO_SUMMARY) {
 | 
			
		||||
    core.warning('DOCKER_BUILD_NO_SUMMARY is deprecated. Set DOCKER_BUILD_SUMMARY to false instead.');
 | 
			
		||||
    return !Util.parseBool(process.env.DOCKER_BUILD_NO_SUMMARY);
 | 
			
		||||
  } else if (process.env.DOCKER_BUILD_SUMMARY) {
 | 
			
		||||
    return Util.parseBool(process.env.DOCKER_BUILD_SUMMARY);
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function buildRecordUploadEnabled(): boolean {
 | 
			
		||||
  if (process.env.DOCKER_BUILD_RECORD_UPLOAD) {
 | 
			
		||||
    return Util.parseBool(process.env.DOCKER_BUILD_RECORD_UPLOAD);
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function buildRecordRetentionDays(): number | undefined {
 | 
			
		||||
  let val: string | undefined;
 | 
			
		||||
  if (process.env.DOCKER_BUILD_EXPORT_RETENTION_DAYS) {
 | 
			
		||||
    core.warning('DOCKER_BUILD_EXPORT_RETENTION_DAYS is deprecated. Use DOCKER_BUILD_RECORD_RETENTION_DAYS instead.');
 | 
			
		||||
    val = process.env.DOCKER_BUILD_EXPORT_RETENTION_DAYS;
 | 
			
		||||
  } else if (process.env.DOCKER_BUILD_RECORD_RETENTION_DAYS) {
 | 
			
		||||
    val = process.env.DOCKER_BUILD_RECORD_RETENTION_DAYS;
 | 
			
		||||
  }
 | 
			
		||||
  if (val) {
 | 
			
		||||
    const res = parseInt(val);
 | 
			
		||||
    if (isNaN(res)) {
 | 
			
		||||
      throw new Error(`Invalid build record retention days: ${val}`);
 | 
			
		||||
    }
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,58 @@
 | 
			
		||||
import * as core from '@actions/core';
 | 
			
		||||
 | 
			
		||||
export const IsPost = !!process.env['STATE_isPost'];
 | 
			
		||||
import {Build} from '@docker/actions-toolkit/lib/buildx/build';
 | 
			
		||||
 | 
			
		||||
import {Inputs} from './context';
 | 
			
		||||
 | 
			
		||||
export const tmpDir = process.env['STATE_tmpDir'] || '';
 | 
			
		||||
export const buildRef = process.env['STATE_buildRef'] || '';
 | 
			
		||||
export const isSummarySupported = !!process.env['STATE_isSummarySupported'];
 | 
			
		||||
export const summaryInputs = process.env['STATE_summaryInputs'] ? JSON.parse(process.env['STATE_summaryInputs']) : undefined;
 | 
			
		||||
 | 
			
		||||
export function setTmpDir(tmpDir: string) {
 | 
			
		||||
  core.saveState('tmpDir', tmpDir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!IsPost) {
 | 
			
		||||
  core.saveState('isPost', 'true');
 | 
			
		||||
export function setBuildRef(buildRef: string) {
 | 
			
		||||
  core.saveState('buildRef', buildRef);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function setSummarySupported() {
 | 
			
		||||
  core.saveState('isSummarySupported', 'true');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function setSummaryInputs(inputs: Inputs) {
 | 
			
		||||
  const res = {};
 | 
			
		||||
  for (const key of Object.keys(inputs)) {
 | 
			
		||||
    if (key === 'github-token') {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    const value: string | string[] | boolean = inputs[key];
 | 
			
		||||
    if (typeof value === 'boolean' && !value) {
 | 
			
		||||
      continue;
 | 
			
		||||
    } else if (Array.isArray(value)) {
 | 
			
		||||
      if (value.length === 0) {
 | 
			
		||||
        continue;
 | 
			
		||||
      } else if (key === 'secrets' && value.length > 0) {
 | 
			
		||||
        const secretKeys: string[] = [];
 | 
			
		||||
        for (const secret of value) {
 | 
			
		||||
          try {
 | 
			
		||||
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
            const [skey, _] = Build.parseSecretKvp(secret, true);
 | 
			
		||||
            secretKeys.push(skey);
 | 
			
		||||
          } catch (err) {
 | 
			
		||||
            // ignore invalid secret
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (secretKeys.length > 0) {
 | 
			
		||||
          res[key] = secretKeys;
 | 
			
		||||
        }
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
    } else if (!value) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    res[key] = value;
 | 
			
		||||
  }
 | 
			
		||||
  core.saveState('summaryInputs', JSON.stringify(res));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,3 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
FROM alpine
 | 
			
		||||
 | 
			
		||||
RUN echo "Hello world!"
 | 
			
		||||
 | 
			
		||||
@ -1,2 +1,3 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
FROM busybox
 | 
			
		||||
RUN cat /etc/hosts
 | 
			
		||||
 | 
			
		||||
@ -1,3 +0,0 @@
 | 
			
		||||
# syntax=docker/dockerfile-upstream:master
 | 
			
		||||
FROM alpine
 | 
			
		||||
RUN cat /etc/*release
 | 
			
		||||
@ -1,2 +1,3 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
FROM alpine
 | 
			
		||||
RUN cat /proc/self/cgroup
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								test/go/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								test/go/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
# 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
 | 
			
		||||
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 AS image
 | 
			
		||||
COPY --from=build /usr/bin/app /bin/app
 | 
			
		||||
EXPOSE 8080
 | 
			
		||||
ENTRYPOINT ["/bin/app"]
 | 
			
		||||
							
								
								
									
										3
									
								
								test/go/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/go/go.mod
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
module github.com/docker/build-push-action/test/go
 | 
			
		||||
 | 
			
		||||
go 1.18
 | 
			
		||||
							
								
								
									
										14
									
								
								test/go/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								test/go/main.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		fmt.Fprintf(w, "Hello, Go!")
 | 
			
		||||
	})
 | 
			
		||||
	log.Fatal(http.ListenAndServe(":8080", nil))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								test/lint.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								test/lint.Dockerfile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
frOM busybox as base
 | 
			
		||||
cOpy lint.Dockerfile .
 | 
			
		||||
 | 
			
		||||
from scratch
 | 
			
		||||
MAINTAINER moby@example.com
 | 
			
		||||
COPy --from=base \
 | 
			
		||||
  /lint.Dockerfile \
 | 
			
		||||
  /
 | 
			
		||||
 | 
			
		||||
CMD [ "echo", "Hello, Norway!" ]
 | 
			
		||||
CMD [ "echo", "Hello, Sweden!" ]
 | 
			
		||||
ENTRYPOINT my-program start
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
FROM --platform=$BUILDPLATFORM golang:alpine AS build
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
 | 
			
		||||
FROM --platform=$BUILDPLATFORM alpine AS build
 | 
			
		||||
ARG TARGETPLATFORM
 | 
			
		||||
ARG BUILDPLATFORM
 | 
			
		||||
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
 | 
			
		||||
 | 
			
		||||
RUN apk --update --no-cache add \
 | 
			
		||||
    shadow \
 | 
			
		||||
    sudo \
 | 
			
		||||
@ -13,10 +13,9 @@ RUN apk --update --no-cache add \
 | 
			
		||||
  && rm -rf /tmp/* /var/cache/apk/*
 | 
			
		||||
 | 
			
		||||
USER buildx
 | 
			
		||||
RUN sudo chown buildx. /log
 | 
			
		||||
RUN sudo chown buildx: /log
 | 
			
		||||
USER root
 | 
			
		||||
 | 
			
		||||
FROM alpine
 | 
			
		||||
 | 
			
		||||
COPY --from=build /log /log
 | 
			
		||||
RUN ls -al /log
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
FROM --platform=$BUILDPLATFORM golang:alpine AS build
 | 
			
		||||
 | 
			
		||||
ARG TARGETPLATFORM
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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!"
 | 
			
		||||
							
								
								
									
										4
									
								
								test/named-context.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								test/named-context.Dockerfile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
 | 
			
		||||
FROM alpine
 | 
			
		||||
RUN cat /etc/*release
 | 
			
		||||
							
								
								
									
										9
									
								
								test/nocachefilter.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/nocachefilter.Dockerfile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
FROM busybox AS base
 | 
			
		||||
RUN echo "Hello world!" > /hello
 | 
			
		||||
 | 
			
		||||
FROM alpine AS build
 | 
			
		||||
COPY --from=base /hello /hello
 | 
			
		||||
RUN uname -a
 | 
			
		||||
 | 
			
		||||
FROM build
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										4
									
								
								test/secret.Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								test/secret.Dockerfile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
FROM busybox
 | 
			
		||||
RUN --mount=type=secret,id=MYSECRET \
 | 
			
		||||
  echo "MYSECRET=$(cat /run/secrets/MYSECRET)"
 | 
			
		||||
@ -1,2 +1,3 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
FROM busybox
 | 
			
		||||
RUN mount | grep /dev/shm
 | 
			
		||||
 | 
			
		||||
@ -1,2 +1,3 @@
 | 
			
		||||
# syntax=docker/dockerfile:1
 | 
			
		||||
FROM busybox
 | 
			
		||||
RUN ulimit -a
 | 
			
		||||
 | 
			
		||||
@ -1,21 +1,22 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "esModuleInterop": true,
 | 
			
		||||
    "target": "es6",
 | 
			
		||||
    "module": "commonjs",
 | 
			
		||||
    "lib": [
 | 
			
		||||
      "es6",
 | 
			
		||||
      "dom"
 | 
			
		||||
    ],
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "newLine": "lf",
 | 
			
		||||
    "outDir": "./lib",
 | 
			
		||||
    "rootDir": "./src",
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "forceConsistentCasingInFileNames": true,
 | 
			
		||||
    "noImplicitAny": false,
 | 
			
		||||
    "esModuleInterop": true,
 | 
			
		||||
    "sourceMap": true
 | 
			
		||||
    "resolveJsonModule": true,
 | 
			
		||||
    "useUnknownInCatchVariables": false,
 | 
			
		||||
  },
 | 
			
		||||
  "exclude": [
 | 
			
		||||
    "./__mocks__/**/*",
 | 
			
		||||
    "./__tests__/**/*",
 | 
			
		||||
    "./lib/**/*",
 | 
			
		||||
    "node_modules",
 | 
			
		||||
    "**/*.test.ts"
 | 
			
		||||
    "jest.config.ts"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user