Compare commits

..

89 Commits

Author SHA1 Message Date
c56af95754 Merge pull request #704 from crazy-max/setOutput
Remove workaround for setOutput
2022-10-12 08:33:54 +02:00
75aaa63262 Remove workaround for setOutput
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-12 06:56:31 +02:00
f97d6e2850 Merge pull request #700 from crazy-max/update-docs
docs: update links and layout
2022-10-11 12:07:35 +02:00
47c00d78bf ci: secret job to check for invalid secrets
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-09 17:42:47 +02:00
871b930e7a docs: update links and layout
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-07 19:28:55 +02:00
105bf59b00 docs: copy between registries with buildx
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-07 19:23:10 +02:00
48888e0b13 Merge pull request #699 from crazy-max/docs-outputs
docs: note about multiple outputs
2022-10-07 18:33:56 +02:00
6b820ad47e docs: note about multiple outputs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-07 18:31:06 +02:00
e1a10350ee Merge pull request #665 from baibaratsky/patch-1
docs: named contexts
2022-10-07 18:25:40 +02:00
0f5a7d48d5 docs: named contexts
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-07 18:22:40 +02:00
6a6e8c7c14 docs: build contexts and bake options
Signed-off-by: Andrei Baibaratsky <andrei@baibaratsky.com>
2022-10-07 18:21:37 +02:00
e189a1cb78 Merge pull request #696 from docker/dependabot/npm_and_yarn/actions/github-5.1.1
Bump @actions/github from 5.0.3 to 5.1.1
2022-10-07 16:47:39 +02:00
2cf0d6fbdc Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-07 16:46:29 +02:00
3cde535b0c Bump @actions/github from 5.0.3 to 5.1.1
Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 5.0.3 to 5.1.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-01 01:09:07 +00:00
83a00fb5e6 Merge pull request #695 from docker/dependabot/npm_and_yarn/actions/core-1.10.0
Bump @actions/core from 1.9.1 to 1.10.0
2022-10-01 03:07:44 +02:00
1d5915004a Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-01 03:05:50 +02:00
2e87529dad Bump @actions/core from 1.9.1 to 1.10.0
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.9.1 to 1.10.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-30 11:12:03 +00:00
e27bcee4eb Merge pull request #685 from crazy-max/git-context-docs
docs: fix Git context link and add more details about subdir support
2022-09-02 14:26:21 +02:00
71d260c49a docs: fix Git context link and add more details about subdir support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-02 12:24:08 +02:00
965c6a410d Merge pull request #672 from crazy-max/fix-ci-dispatch
ci: fix workflow dispatch inputs
2022-08-17 11:25:02 +02:00
08aa123a28 ci: fix workflow dispatch inputs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-17 02:17:37 +02:00
1527803881 Merge pull request #666 from deronnax/patch-1
use ${{ env.TEST_TAG }} to tag image in push step
2022-08-12 18:17:02 +02:00
a49d9ab751 Merge pull request #667 from docker/dependabot/npm_and_yarn/actions/core-1.9.1
Bump @actions/core from 1.9.0 to 1.9.1
2022-08-12 18:14:31 +02:00
cbb574ee73 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-12 18:13:02 +02:00
8b56e74b48 ci: cleanup ci workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-12 18:12:47 +02:00
a5024d816a Bump @actions/core from 1.9.0 to 1.9.1
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-12 18:12:16 +02:00
2235b57edd Merge pull request #669 from crazy-max/buildx-dispatch
ci: allow arbitrary buildx/buildkit version on workflow dispatch event
2022-08-12 17:04:32 +02:00
15b9e74b95 ci: allow arbitrary buildx/buildkit version on workflow dispatch event
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-12 16:45:35 +02:00
48daa618bd use ${{ env.TEST_TAG }} to tag image in push step
Signed-off-by: Mathieu Dupuy <deronnax@gmail.com>
2022-08-06 11:12:45 +02:00
c84f382811 Merge pull request #663 from crazy-max/fix-git-token-cond
Fix GitHub token not passed with Git context if subdir defined
2022-08-03 17:25:08 +02:00
cd5d0b79ea Merge pull request #661 from dud225/subdir_context
Update comment regarding the support of subdir context
2022-08-03 16:59:34 +02:00
30a32246ba Fix GitHub token not passed with Git context if subdir defined
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-03 14:39:01 +02:00
1f19633b92 Update comment regarding the support of subdir context
Signed-off-by: Hervé Werner <dud225@hotmail.com>
2022-08-03 13:55:05 +02:00
67af6dc1d3 Merge pull request #657 from bendrucker/deprecated-fs-rmdir
Replace deprecated `fs.rmdir` with `fs.rm`
2022-07-28 11:04:08 +02:00
988cb093f2 replace deprecated fs.rmdir with fs.rm
Signed-off-by: Ben Drucker <bvdrucker@gmail.com>
2022-07-27 16:47:22 -07:00
1cb9d22b93 Merge pull request #653 from crazy-max/no-cache-filters
`no-cache-filters` input
2022-07-19 17:04:40 +02:00
5ffbca1432 no-cache-filters input
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-19 00:04:41 +02:00
a8d76c070a Merge pull request #650 from docker/dependabot/npm_and_yarn/csv-parse-5.3.0
Bump csv-parse from 5.1.0 to 5.3.0
2022-07-18 17:08:08 +02:00
12b1e419c2 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-18 17:06:02 +02:00
2a60beff0d Bump csv-parse from 5.1.0 to 5.3.0
Bumps [csv-parse](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-parse) from 5.1.0 to 5.3.0.
- [Release notes](https://github.com/adaltas/node-csv/releases)
- [Changelog](https://github.com/adaltas/node-csv/blob/master/packages/csv-parse/CHANGELOG.md)
- [Commits](https://github.com/adaltas/node-csv/commits/csv-parse@5.3.0/packages/csv-parse)

---
updated-dependencies:
- dependency-name: csv-parse
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-18 15:03:16 +00:00
5268745b5f Merge pull request #637 from docker/dependabot/npm_and_yarn/actions/core-1.9.0
Bump @actions/core from 1.8.2 to 1.9.0
2022-07-18 17:01:49 +02:00
a2a27346c0 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-18 16:53:08 +02:00
05d9e522ae Bump @actions/core from 1.8.2 to 1.9.0
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.8.2 to 1.9.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-16 11:05:21 +00:00
42863b1282 Merge pull request #623 from docker/dependabot/npm_and_yarn/csv-parse-5.1.0
Bump csv-parse from 5.0.4 to 5.1.0
2022-06-07 11:35:13 +02:00
c372f73edc Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-07 11:30:16 +02:00
d17cab8f42 Merge pull request #630 from crazy-max/bump-actions
Bump actions to latest major
2022-06-07 11:22:11 +02:00
4c2810ab91 Merge pull request #622 from crazy-max/ubuntu-2204
ci: add ubuntu 22.04 to virtual env
2022-05-31 10:18:41 +02:00
307a009589 Bump actions to latest major
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-28 18:36:30 +02:00
f2c26aa560 Bump csv-parse from 5.0.4 to 5.1.0
Bumps [csv-parse](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-parse) from 5.0.4 to 5.1.0.
- [Release notes](https://github.com/adaltas/node-csv/releases)
- [Changelog](https://github.com/adaltas/node-csv/blob/master/packages/csv-parse/CHANGELOG.md)
- [Commits](https://github.com/adaltas/node-csv/commits/csv-parse@5.1.0/packages/csv-parse)

---
updated-dependencies:
- dependency-name: csv-parse
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-24 14:03:18 +00:00
a806b8fe18 Merge pull request #620 from docker/dependabot/npm_and_yarn/actions/core-1.8.2
Bump @actions/core from 1.6.0 to 1.8.2
2022-05-24 16:01:57 +02:00
ae74c4950a Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-24 15:50:32 +02:00
80c878df65 Bump @actions/core from 1.6.0 to 1.8.2
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.6.0 to 1.8.2.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 09:04:16 +00:00
a571ccfa72 Merge pull request #619 from docker/dependabot/npm_and_yarn/actions/github-5.0.3
Bump @actions/github from 5.0.1 to 5.0.3
2022-05-23 11:02:48 +02:00
283625c36b Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-23 10:53:30 +02:00
bb751c2095 ci: add ubuntu 22.04 to virtual env
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-23 10:24:26 +02:00
8d9444d675 Bump @actions/github from 5.0.1 to 5.0.3
Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 5.0.1 to 5.0.3.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 11:05:13 +00:00
c5e6528d5d Merge pull request #610 from crazy-max/update-refs
Bump all Docker actions to latest major
2022-05-05 19:34:15 +02:00
ceb414dc73 Remove UPGRADE notes (v1 EOL)
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-05 19:26:50 +02:00
dda70725ed Bump all Docker actions to latest major
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-05 19:26:01 +02:00
e551b19e49 Merge pull request #564 from crazy-max/node-16
Node 16 as default runtime
2022-05-05 19:06:55 +02:00
3554377aa3 Merge pull request #609 from crazy-max/ci-fix-test
ci: fix standalone test
2022-05-05 18:42:11 +02:00
a62bc1b22b ci: fix standalone test
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-05 18:40:08 +02:00
c2085839e1 Merge pull request #601 from crazy-max/standalone-mode
Standalone mode support
2022-05-05 18:11:51 +02:00
fcd91249e5 Merge pull request #607 from docker/dependabot/github_actions/docker/metadata-action-4
Bump docker/metadata-action from 3 to 4
2022-05-05 14:01:16 +02:00
0ebe720aed Bump docker/metadata-action from 3 to 4
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 3 to 4.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Upgrade guide](https://github.com/docker/metadata-action/blob/master/UPGRADE.md)
- [Commits](https://github.com/docker/metadata-action/compare/v3...v4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-05 11:02:33 +00:00
38b45804b5 Standalone mode support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-28 09:31:51 +02:00
ba317382dc Merge pull request #533 from docker/dependabot/npm_and_yarn/csv-parse-5.0.4
Bump csv-parse from 4.16.3 to 5.0.4
2022-04-25 06:51:12 +02:00
43721d2346 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-25 06:47:57 +02:00
5ea21bf2ba Fix csv-parse implementation since major update
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-25 06:47:57 +02:00
300b1bdff7 Bump csv-parse from 4.16.3 to 5.0.4
Bumps [csv-parse](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-parse) from 4.16.3 to 5.0.4.
- [Release notes](https://github.com/adaltas/node-csv/releases)
- [Changelog](https://github.com/adaltas/node-csv/blob/master/packages/csv-parse/CHANGELOG.md)
- [Commits](https://github.com/adaltas/node-csv/commits/csv-parse@5.0.4/packages/csv-parse)

---
updated-dependencies:
- dependency-name: csv-parse
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-22 09:27:30 +00:00
84580d7737 Merge pull request #595 from docker/dependabot/npm_and_yarn/semver-7.3.7
Bump semver from 7.3.5 to 7.3.7
2022-04-22 11:26:12 +02:00
a460b5e683 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-22 11:08:34 +02:00
9f1392c9bf Bump semver from 7.3.5 to 7.3.7
Bumps [semver](https://github.com/npm/node-semver) from 7.3.5 to 7.3.7.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v7.3.5...v7.3.7)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-13 11:04:19 +00:00
9472e90210 Merge pull request #589 from docker/dependabot/github_actions/codecov/codecov-action-3
Bump codecov/codecov-action from 2 to 3
2022-04-08 15:51:32 +02:00
5accc8e023 Bump codecov/codecov-action from 2 to 3
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 2 to 3.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v2...v3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-06 11:03:02 +00:00
f7a2a67b4c Merge pull request #584 from docker/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-04-04 15:12:31 +02:00
b905f177bc Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 13:10:51 +00:00
0779722168 Merge pull request #582 from docker/dependabot/npm_and_yarn/actions/github-5.0.1
Bump @actions/github from 5.0.0 to 5.0.1
2022-04-04 15:10:11 +02:00
fd75456293 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-04 15:07:18 +02:00
ada965aa7b Bump @actions/github from 5.0.0 to 5.0.1
Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-01 11:04:48 +00:00
b5730d2471 Merge pull request #575 from docker/dependabot/github_actions/actions/cache-3
Bump actions/cache from 2 to 3
2022-03-22 19:55:45 +01:00
839389a46c Bump actions/cache from 2 to 3
Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 11:16:07 +00:00
34c1caa1ce Merge pull request #573 from docker/dependabot/npm_and_yarn/actions/exec-1.1.1
Bump @actions/exec from 1.1.0 to 1.1.1
2022-03-21 10:07:25 +01:00
6ff230f13e Node 16 as default runtime
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-21 09:58:43 +01:00
75c825aabc Merge pull request #571 from crazy-max/update-dev
chore: update dev dependencies and workflow
2022-03-21 09:55:11 +01:00
5f7b938b8c ci: update virtual-env workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-19 10:44:24 +01:00
7ae34a20f3 Bump @actions/exec from 1.1.0 to 1.1.1
Bumps [@actions/exec](https://github.com/actions/toolkit/tree/HEAD/packages/exec) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/exec/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/@actions/tool-cache@1.1.1/packages/exec)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-18 11:03:49 +00:00
acb76cdd52 chore: update bins
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-15 22:00:00 +01:00
2d081a4fd5 chore: update dev dependencies and workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-15 21:59:59 +01:00
50 changed files with 3555 additions and 30397 deletions

23
.eslintrc.json Normal file
View File

@ -0,0 +1,23 @@
{
"env": {
"node": true,
"es2021": true,
"jest/globals": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:jest/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"jest",
"prettier"
]
}

View File

@ -2,6 +2,15 @@ name: ci
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
buildx-version:
description: 'Buildx version or Git context'
default: 'latest'
required: false
buildkit-image:
description: 'BuildKit image'
default: 'moby/buildkit:buildx-stable-1'
required: false
push: push:
branches: branches:
- 'master' - 'master'
@ -9,6 +18,10 @@ on:
branches: branches:
- 'master' - 'master'
env:
BUILDX_VERSION: latest
BUILDKIT_IMAGE: moby/buildkit:buildx-stable-1
jobs: jobs:
minimal: minimal:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -20,7 +33,11 @@ jobs:
path: action path: action
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build name: Build
uses: ./action uses: ./action
@ -42,14 +59,16 @@ jobs:
path: action path: action
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: latest version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: network=host driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build and push name: Build and push
id: docker_build id: docker_build
@ -89,13 +108,16 @@ jobs:
path: action path: action
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
driver-opts: network=host version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build and push name: Build and push
id: docker_build id: docker_build
@ -132,12 +154,6 @@ jobs:
path-context: path-context:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
buildx-version:
- ""
- latest
services: services:
registry: registry:
image: registry:2 image: registry:2
@ -149,14 +165,16 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: ${{ matrix.buildx-version }} version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: network=host driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build and push name: Build and push
id: docker_build id: docker_build
@ -216,10 +234,14 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build name: Build
id: docker_build id: docker_build
@ -280,6 +302,29 @@ jobs:
run: | run: |
docker image inspect myimage:latest docker image inspect myimage:latest
secret:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./
with:
context: .
file: ./test/secret.Dockerfile
secrets: |
MYSECRET=foo
INVALID_SECRET=
network: network:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -288,7 +333,11 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: List networks name: List networks
run: docker network ls run: docker network ls
@ -308,11 +357,11 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: v0.7.0 version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: | driver-opts: |
image=moby/buildkit:master image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build name: Build
uses: ./ uses: ./
@ -330,11 +379,12 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: v0.7.0 version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: | driver-opts: |
image=moby/buildkit:master network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build name: Build
uses: ./ uses: ./
@ -354,11 +404,12 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: v0.7.0 version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: | driver-opts: |
image=moby/buildkit:master network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build name: Build
uses: ./ uses: ./
@ -376,7 +427,12 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build name: Build
uses: ./ uses: ./
@ -393,12 +449,14 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: v0.8.0 version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build name: Build
uses: ./ uses: ./
@ -409,14 +467,35 @@ jobs:
alpine=docker-image://debian:stable-slim alpine=docker-image://debian:stable-slim
tags: name/app:latest tags: name/app:latest
no-cache-filters:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./
with:
context: ./test
file: ./test/nocachefilter.Dockerfile
no-cache-filters: build
tags: name/app:latest
cache-from: type=gha,scope=nocachefilter
cache-to: type=gha,scope=nocachefilter,mode=max
multi: multi:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
buildx-version:
- ""
- latest
dockerfile: dockerfile:
- multi - multi
- multi-sudo - multi-sudo
@ -431,14 +510,16 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: ${{ matrix.buildx-version }} version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: network=host driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build and push name: Build and push
id: docker_build id: docker_build
@ -501,12 +582,12 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: v0.8.0 version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver: ${{ matrix.driver }} driver: ${{ matrix.driver }}
driver-opts: | driver-opts: |
network=host network=host
@ -565,14 +646,16 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: | driver-opts: |
network=host network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Build and push (1) name: Build and push (1)
id: docker_build id: docker_build
@ -638,145 +721,8 @@ jobs:
exit 1 exit 1
fi fi
local-cache-first:
runs-on: ubuntu-latest
outputs:
digest: ${{ steps.docker_build.outputs.digest }}
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
with:
driver-opts: |
network=host
-
name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-local-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-ghcache-
-
name: Erase cache
run: |
rm -rf /tmp/.buildx-cache/*
-
name: Build and push
id: docker_build
uses: ./
with:
context: ./test
file: ./test/multi.Dockerfile
builder: ${{ steps.buildx.outputs.name }}
platforms: linux/amd64,linux/arm64
push: true
tags: |
localhost:5000/name/app:latest
localhost:5000/name/app:1.0.0
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
-
name: Inspect
run: |
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
-
name: Check digest
run: |
if [ -z "${{ steps.docker_build.outputs.digest }}" ]; then
echo "::error::Digest should not be empty"
exit 1
fi
local-cache-hit:
runs-on: ubuntu-latest
needs: local-cache-first
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
with:
driver-opts: |
network=host
-
name: Cache Docker layers
uses: actions/cache@v2
id: cache
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-local-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-ghcache-
-
name: Build and push
id: docker_build
uses: ./
with:
context: ./test
file: ./test/multi.Dockerfile
builder: ${{ steps.buildx.outputs.name }}
platforms: linux/amd64,linux/arm64
push: true
tags: |
localhost:5000/name/app:latest
localhost:5000/name/app:1.0.0
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
-
name: Inspect
run: |
docker buildx imagetools inspect localhost:5000/name/app:1.0.0
-
name: Check digest
run: |
if [ -z "${{ steps.docker_build.outputs.digest }}" ]; then
echo "::error::Digest should not be empty"
exit 1
fi
-
name: Compare digests
run: |
echo Compare "${{ needs.local-cache-first.outputs.digest }}" with "${{ steps.docker_build.outputs.digest }}"
if [ "${{ needs.local-cache-first.outputs.digest }}" != "${{ steps.docker_build.outputs.digest }}" ]; then
echo "::error::Digests should be identical"
exit 1
fi
-
name: Cache hit
run: echo ${{ steps.cache.outputs.cache-hit }}
github-cache: github-cache:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
buildx_version:
- ""
- latest
services: services:
registry: registry:
image: registry:2 image: registry:2
@ -788,14 +734,15 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: ${{ matrix.buildx_version }} version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: | driver-opts: |
network=host network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
buildkitd-flags: --debug buildkitd-flags: --debug
- -
name: Build and push name: Build and push
@ -814,3 +761,28 @@ jobs:
name: Inspect name: Inspect
run: | run: |
docker buildx imagetools inspect localhost:5000/name/app:1.0.0 docker buildx imagetools inspect localhost:5000/name/app:1.0.0
standalone:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Uninstall moby cli
run: |
sudo apt-get purge -y moby-cli moby-buildx
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./
with:
context: ./test
file: ./test/Dockerfile

View File

@ -2,6 +2,15 @@ name: e2e
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
buildx-version:
description: 'Buildx version or Git context'
default: 'latest'
required: false
buildkit-image:
description: 'BuildKit image'
default: 'moby/buildkit:buildx-stable-1'
required: false
schedule: schedule:
- cron: '0 10 * * *' - cron: '0 10 * * *'
push: push:
@ -10,6 +19,10 @@ on:
tags: tags:
- v* - v*
env:
BUILDX_VERSION: latest
BUILDKIT_IMAGE: moby/buildkit:buildx-stable-1
jobs: jobs:
docker: docker:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -64,19 +77,23 @@ jobs:
- -
name: Docker meta name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v3 uses: docker/metadata-action@v4
with: with:
images: ${{ matrix.slug }} images: ${{ matrix.slug }}
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
- -
name: Login to Registry name: Login to Registry
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
registry: ${{ matrix.registry }} registry: ${{ matrix.registry }}
username: ${{ secrets[matrix.username_secret] }} username: ${{ secrets[matrix.username_secret] }}
@ -104,7 +121,3 @@ jobs:
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
run: | run: |
docker buildx imagetools inspect ${{ matrix.slug }}:${{ steps.meta.outputs.version }} docker buildx imagetools inspect ${{ matrix.slug }}:${{ steps.meta.outputs.version }}
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1

View File

@ -29,7 +29,7 @@ jobs:
- -
name: Docker meta name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v3 uses: docker/metadata-action@v4
with: with:
images: ${{ env.DOCKER_IMAGE }} images: ${{ env.DOCKER_IMAGE }}
tags: | tags: |
@ -42,7 +42,7 @@ jobs:
type=sha type=sha
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
driver-opts: network=host driver-opts: network=host
- -
@ -72,7 +72,3 @@ jobs:
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
run: | run: |
docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }} docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }}
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1

View File

@ -17,16 +17,16 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Validate name: Validate
uses: docker/bake-action@v1 uses: docker/bake-action@v2
with: with:
targets: validate targets: validate
- -
name: Test name: Test
uses: docker/bake-action@v1 uses: docker/bake-action@v2
with: with:
targets: test targets: test
- -
name: Upload coverage name: Upload coverage
uses: codecov/codecov-action@v2 uses: codecov/codecov-action@v3
with: with:
file: ./coverage/clover.xml file: ./coverage/clover.xml

View File

@ -4,6 +4,16 @@ on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
- cron: '0 10 * * *' - cron: '0 10 * * *'
push:
branches:
- 'master'
paths:
- '.github/workflows/virtual-env.yml'
pull_request:
branches:
- 'master'
paths:
- '.github/workflows/virtual-env.yml'
jobs: jobs:
os: os:
@ -13,21 +23,40 @@ jobs:
matrix: matrix:
os: os:
- ubuntu-latest - ubuntu-latest
- ubuntu-22.04
- ubuntu-20.04 - ubuntu-20.04
- ubuntu-18.04 - ubuntu-18.04
steps: steps:
- -
name: File system name: File system
run: df -ah run: df -ah
-
name: Mounts
run: mount
-
name: Node info
run: node -p process
-
name: NPM version
run: npm version
- -
name: List install packages name: List install packages
run: apt list --installed run: apt list --installed
-
name: Docker daemon conf
run: |
cat /etc/docker/daemon.json
- -
name: Docker info name: Docker info
run: docker info run: docker info
- -
name: Docker version name: Docker version
run: docker version run: docker version
-
name: Cgroups
run: |
sudo apt-get install -y cgroup-tools
lscgroup
- -
name: buildx version name: buildx version
run: docker buildx version run: docker buildx version

172
README.md
View File

@ -6,9 +6,10 @@
## About ## About
GitHub Action to build and push Docker images with [Buildx](https://github.com/docker/buildx) with full support of the GitHub Action to build and push Docker images with [Buildx](https://github.com/docker/buildx)
features provided by [Moby BuildKit](https://github.com/moby/buildkit) builder toolkit. This includes multi-platform with full support of the features provided by [Moby BuildKit](https://github.com/moby/buildkit)
build, secrets, remote cache, etc. and different builder deployment/namespacing options. builder toolkit. This includes multi-platform build, secrets, remote cache, etc.
and different builder deployment/namespacing options.
![Screenshot](.github/build-push-action.png) ![Screenshot](.github/build-push-action.png)
@ -22,38 +23,42 @@ ___
* [Secrets](docs/advanced/secrets.md) * [Secrets](docs/advanced/secrets.md)
* [Isolated builders](docs/advanced/isolated-builders.md) * [Isolated builders](docs/advanced/isolated-builders.md)
* [Push to multi-registries](docs/advanced/push-multi-registries.md) * [Push to multi-registries](docs/advanced/push-multi-registries.md)
* [Copy between registries](docs/advanced/copy-between-registries.md) * [Copy between registries](docs/advanced/copy-between-registries.md)
* [Cache](docs/advanced/cache.md) * [Cache](docs/advanced/cache.md)
* [Local registry](docs/advanced/local-registry.md) * [Local registry](docs/advanced/local-registry.md)
* [Export image to Docker](docs/advanced/export-docker.md) * [Export image to Docker](docs/advanced/export-docker.md)
* [Share built image between jobs](docs/advanced/share-image-jobs.md) * [Share built image between jobs](docs/advanced/share-image-jobs.md)
* [Test your image before pushing it](docs/advanced/test-before-push.md) * [Test your image before pushing it](docs/advanced/test-before-push.md)
* [Named contexts](docs/advanced/named-contexts.md)
* [Handle tags and labels](docs/advanced/tags-labels.md) * [Handle tags and labels](docs/advanced/tags-labels.md)
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md) * [Update Docker Hub repo description](docs/advanced/dockerhub-desc.md)
* [Customizing](#customizing) * [Customizing](#customizing)
* [inputs](#inputs) * [inputs](#inputs)
* [outputs](#outputs) * [outputs](#outputs)
* [Troubleshooting](#troubleshooting) * [Troubleshooting](#troubleshooting)
* [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot) * [Contributing](#contributing)
## Usage ## Usage
In the examples below we are also using 3 other actions: 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 * [`setup-buildx`](https://github.com/docker/setup-buildx-action) action will
default the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver). 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. This is **not required but recommended** using it to be able to build
* [`setup-qemu`](https://github.com/docker/setup-qemu-action) action can be useful if you want multi-platform images, export cache, etc.
to add emulation support with QEMU to be able to build against more platforms. * [`setup-qemu`](https://github.com/docker/setup-qemu-action) action can be
* [`login`](https://github.com/docker/login-action) action will take care to log in against a Docker registry. 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 ### Git context
By default, this action uses the [Git context](#git-context) so you don't need By default, this action uses the [Git context](https://docs.docker.com/engine/reference/commandline/build/#git-repositories),
to use the [`actions/checkout`](https://github.com/actions/checkout/) action to so you don't need to use the [`actions/checkout`](https://github.com/actions/checkout/)
check out the repository because this will be done directly by [BuildKit](https://github.com/moby/buildkit). 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>`. and will result in the following context: `https://github.com/<owner>/<repo>.git#<ref>`.
```yaml ```yaml
@ -70,19 +75,19 @@ jobs:
steps: steps:
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
push: true push: true
tags: user/app:latest tags: user/app:latest
@ -100,25 +105,37 @@ expression `{{defaultContext}}`. Here we can use it to provide a subdirectory
to the default Git context: to the default Git context:
```yaml ```yaml
-
# Setting up Docker Buildx with docker-container driver is required
# at the moment to be able to use a subdirectory with Git context
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: "{{defaultContext}}:mysubdir" context: "{{defaultContext}}:mysubdir"
push: true push: true
tags: user/app:latest 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) > **Warning**
>
> Subdirectory for Git context is available from [BuildKit v0.9.0](https://github.com/moby/buildkit/releases/tag/v0.9.0).
> If you're using the `docker` builder (default if `setup-buildx-action` not used),
> then BuildKit in Docker Engine will be used. As Docker Engine < v22.x.x embeds
> Buildkit 0.8.2 at the moment, it does not support this feature. It's therefore
> required to use the `setup-buildx-action` at the moment.
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 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 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: `GIT_AUTH_TOKEN` to be able to authenticate against it with Buildx:
```yaml ```yaml
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
push: true push: true
tags: user/app:latest tags: user/app:latest
@ -142,22 +159,22 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true
@ -176,8 +193,9 @@ jobs:
* [Export image to Docker](docs/advanced/export-docker.md) * [Export image to Docker](docs/advanced/export-docker.md)
* [Share built image between jobs](docs/advanced/share-image-jobs.md) * [Share built image between jobs](docs/advanced/share-image-jobs.md)
* [Test your image before pushing it](docs/advanced/test-before-push.md) * [Test your image before pushing it](docs/advanced/test-before-push.md)
* [Named contexts](docs/advanced/named-contexts.md)
* [Handle tags and labels](docs/advanced/tags-labels.md) * [Handle tags and labels](docs/advanced/tags-labels.md)
* [Update DockerHub repo description](docs/advanced/dockerhub-desc.md) * [Update Docker Hub repo description](docs/advanced/dockerhub-desc.md)
## Customizing ## Customizing
@ -197,61 +215,55 @@ Following inputs can be used as `step.with` keys
> tags: name/app:latest,name/app:1.0.0 > tags: name/app:latest,name/app:1.0.0
> ``` > ```
| Name | Type | Description | | 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`) | | `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`) |
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) | | `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-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://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#build-context) (e.g., `name=path`) | | `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://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from) (e.g., `type=local,src=path/to/dir`) | | `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://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-to) (e.g., `type=local,dest=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`) |
| `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 | | `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)) | | `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`) | | `file` | String | Path to the Dockerfile. (default `{context}/Dockerfile`) |
| `labels` | List | List of metadata for an image | | `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 | | `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`) | | `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`) | | `no-cache-filters` | List/CSV | Do not cache specified stages |
| `platforms` | List/CSV | List of [target platforms](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#platform) for build | | `outputs`¹ | List | List of [output destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#output) (format: `type=local,dest=path`) |
| `pull` | Bool | Always attempt to pull all referenced images (default `false`) | | `platforms` | List/CSV | List of [target platforms](https://docs.docker.com/engine/reference/commandline/buildx_build/#platform) for build |
| `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`) | | `pull` | Bool | Always attempt to pull all referenced images (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`) | | `push` | Bool | [Push](https://docs.docker.com/engine/reference/commandline/buildx_build/#push) is a shorthand for `--output=type=registry` (default `false`) |
| `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`) | | `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`) |
| `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`) | | `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`) |
| `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 | | `shm-size` | String | Size of [`/dev/shm`](https://docs.docker.com/engine/reference/commandline/buildx_build/#shm-size) (e.g., `2g`) |
| `tags` | List/CSV | List of tags | | `ssh` | List | List of [SSH agent socket or keys](https://docs.docker.com/engine/reference/commandline/buildx_build/#ssh) to expose to the build |
| `target` | String | Sets the target stage to build | | `tags` | List/CSV | List of tags |
| `ulimit` | List | [Ulimit](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#-set-ulimits---ulimit) options (e.g., `nofile=1024:1024`) | | `target` | String | Sets the target stage to build |
| `github-token` | String | GitHub Token used to authenticate against a repository for [Git context](#git-context) (default `${{ github.token }}`) | | `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 }}`) |
> **Note**
>
> * ¹ multiple `outputs` are [not yet supported](https://github.com/moby/buildkit/issues/1555)
### outputs ### outputs
Following outputs are available Following outputs are available
| Name | Type | Description | | Name | Type | Description |
|-------------------|---------|---------------------------------------| |------------|---------|-----------------------|
| `imageid` | String | Image ID | | `imageid` | String | Image ID |
| `digest` | String | Image digest | | `digest` | String | Image digest |
| `metadata` | JSON | Build result metadata | | `metadata` | JSON | Build result metadata |
## Troubleshooting ## Troubleshooting
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) 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) Want to contribute? Awesome! You can find information about contributing to
has [native GitHub Actions support](https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#package-ecosystem), this project in the [CONTRIBUTING.md](/.github/CONTRIBUTING.md)
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"
```

View File

@ -16,7 +16,7 @@ While pushing to a registry, you may encounter these kinds of issues:
* `unexpected response: 401 Unauthorized` * `unexpected response: 401 Unauthorized`
These issues are not directly related to this action but are rather linked to 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 [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 you're pushing your image. The quality of error message depends on the registry
and are usually not very informative. and are usually not very informative.
@ -29,7 +29,7 @@ action step and attach BuildKit container logs to your issue.
### With containerd ### With containerd
Next you can test pushing with [containerd action](https://github.com/crazy-max/ghaction-setup-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. repository.
```yaml ```yaml
@ -44,21 +44,21 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
buildkitd-flags: --debug buildkitd-flags: --debug
- -
name: Set up containerd name: Set up containerd
uses: crazy-max/ghaction-setup-containerd@v1 uses: crazy-max/ghaction-setup-containerd@v2
- -
name: Build Docker image name: Build Docker image
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
@ -105,13 +105,13 @@ to generate sanitized tags:
```yaml ```yaml
- name: Docker meta - name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v3 uses: docker/metadata-action@v4
with: with:
images: ghcr.io/${{ github.repository }} images: ghcr.io/${{ github.repository }}
tags: latest tags: latest
- name: Build and push - name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true
@ -122,14 +122,14 @@ Or a dedicated step to sanitize the slug:
```yaml ```yaml
- name: Sanitize repo slug - name: Sanitize repo slug
uses: actions/github-script@v4 uses: actions/github-script@v6
id: repo_slug id: repo_slug
with: with:
result-encoding: string result-encoding: string
script: return 'ghcr.io/${{ github.repository }}'.toLowerCase() script: return 'ghcr.io/${{ github.repository }}'.toLowerCase()
- name: Build and push - name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true

View File

@ -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 }}
```

View File

@ -1,8 +1,8 @@
import {describe, expect, it, jest, test} from '@jest/globals';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import * as buildx from '../src/buildx'; import * as buildx from '../src/buildx';
import * as context from '../src/context'; import * as context from '../src/context';
@ -53,94 +53,47 @@ describe('getDigest', () => {
}); });
describe('isLocalOrTarExporter', () => { describe('isLocalOrTarExporter', () => {
// prettier-ignore
test.each([ test.each([
[ [['type=registry,ref=user/app'], false],
[ [['type=docker'], false],
'type=registry,ref=user/app', [['type=local,dest=./release-out'], true],
], [['type=tar,dest=/tmp/image.tar'], true],
false [['type=docker', 'type=tar,dest=/tmp/image.tar'], true],
], [['"type=tar","dest=/tmp/image.tar"'], true],
[ [['" type= local" , dest=./release-out'], true],
[ [['.'], true]
'type=docker', ])('given %p returns %p', async (outputs: Array<string>, expected: boolean) => {
], expect(buildx.isLocalOrTarExporter(outputs)).toEqual(expected);
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', () => { describe('isAvailable', () => {
const execSpy: jest.SpyInstance = jest.spyOn(exec, 'getExecOutput'); const execSpy = jest.spyOn(exec, 'getExecOutput');
buildx.isAvailable(); buildx.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], { expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], {
silent: true, silent: true,
ignoreReturnCode: true ignoreReturnCode: true
}); });
}); });
describe('isAvailable standalone', () => {
const execSpy = jest.spyOn(exec, 'getExecOutput');
buildx.isAvailable(true);
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`buildx`, [], {
silent: true,
ignoreReturnCode: true
});
});
describe('getVersion', () => { describe('getVersion', () => {
async function isDaemonRunning() { it('valid', async () => {
return await exec const version = await buildx.getVersion();
.getExecOutput(`docker`, ['version', '--format', '{{.Server.Os}}'], { expect(semver.valid(version)).not.toBeNull();
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', () => { describe('parseVersion', () => {
@ -184,9 +137,9 @@ describe('getSecret', () => {
} }
expect(true).toBe(!invalid); expect(true).toBe(!invalid);
expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`); expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`);
const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8'); expect(fs.readFileSync(tmpNameSync, 'utf-8')).toEqual(exValue);
expect(secretValue).toEqual(exValue);
} catch (err) { } catch (err) {
// eslint-disable-next-line jest/no-conditional-expect
expect(true).toBe(invalid); expect(true).toBe(invalid);
} }
}); });

View File

@ -1,5 +1,5 @@
import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
import * as fs from 'fs'; import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import * as context from '../src/context'; import * as context from '../src/context';
@ -150,7 +150,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'.' '.'
@ -167,7 +166,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--build-arg', 'MY_ARG=val1,val2,val3', '--build-arg', 'MY_ARG=val1,val2,val3',
'--build-arg', 'ARG=val', '--build-arg', 'ARG=val',
@ -186,7 +184,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--tag', 'name/app:7.4', '--tag', 'name/app:7.4',
@ -207,7 +204,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--label', 'org.opencontainers.image.title=buildkit', '--label', 'org.opencontainers.image.title=buildkit',
'--label', 'org.opencontainers.image.description=concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit', '--label', 'org.opencontainers.image.description=concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit',
@ -227,7 +223,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--platform', 'linux/amd64,linux/arm64', '--platform', 'linux/amd64,linux/arm64',
'.' '.'
@ -244,7 +239,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'.' '.'
@ -262,7 +256,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
@ -281,7 +274,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--output', '.', '--output', '.',
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
@ -304,7 +296,6 @@ describe('getArgs', () => {
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--file', './test/Dockerfile', '--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
@ -339,7 +330,6 @@ ccc"`],
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--file', './test/Dockerfile', '--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
@ -377,7 +367,6 @@ ccc`],
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--file', './test/Dockerfile', '--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
@ -407,7 +396,6 @@ ccc`],
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--file', './test/Dockerfile', '--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
@ -431,7 +419,6 @@ ccc`],
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--label', 'org.opencontainers.image.title=filter_results_top_n', '--label', 'org.opencontainers.image.title=filter_results_top_n',
'--label', 'org.opencontainers.image.description=Reference implementation of operation "filter results (top-n)"', '--label', 'org.opencontainers.image.description=Reference implementation of operation "filter results (top-n)"',
@ -454,7 +441,6 @@ ccc`],
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--add-host', 'docker:10.180.0.1', '--add-host', 'docker:10.180.0.1',
'--add-host', 'foo:10.0.0.1', '--add-host', 'foo:10.0.0.1',
@ -483,7 +469,6 @@ nproc=3`],
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--add-host', 'docker:10.180.0.1', '--add-host', 'docker:10.180.0.1',
'--add-host', 'foo:10.0.0.1', '--add-host', 'foo:10.0.0.1',
@ -508,17 +493,35 @@ nproc=3`],
['pull', 'false'], ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
'https://github.com/docker/build-push-action.git#refs/heads/test-jest:docker' 'https://github.com/docker/build-push-action.git#refs/heads/test-jest:docker'
] ]
], ],
[
16,
'0.8.2',
new Map<string, string>([
['github-token', 'abcdefghijklmno0123456789'],
['context', '{{defaultContext}}:subdir'],
['load', 'false'],
['no-cache', 'false'],
['push', 'false'],
['pull', 'false'],
]),
[
'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
'https://github.com/docker/build-push-action.git#refs/heads/test-jest:subdir'
]
]
])( ])(
'[%d] given %p with %p as inputs, returns %p', '[%d] given %p with %p as inputs, returns %p',
async (num: number, buildxVersion: string, inputs: Map<string, any>, expected: Array<string>) => { async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {
await inputs.forEach((value: string, name: string) => { inputs.forEach((value: string, name: string) => {
setInput(name, value); setInput(name, value);
}); });
const defContext = context.defaultContext(); const defContext = context.defaultContext();
@ -666,7 +669,7 @@ FOO=bar`
expect(res).toEqual([ expect(res).toEqual([
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
`MYSECRET=aaaaaaaa `MYSECRET=aaaaaaaa
bbbb\"bbb bbbb"bbb
ccccccccc`, ccccccccc`,
'FOO=bar' 'FOO=bar'
]); ]);
@ -686,27 +689,6 @@ describe('asyncForEach', () => {
}); });
}); });
describe('setOutput', () => {
beforeEach(() => {
process.stdout.write = jest.fn();
});
it('setOutput produces the correct command', () => {
context.setOutput('some output', 'some value');
assertWriteCalls([`::set-output name=some output::some value${os.EOL}`]);
});
it('setOutput handles bools', () => {
context.setOutput('some output', false);
assertWriteCalls([`::set-output name=some output::false${os.EOL}`]);
});
it('setOutput handles numbers', () => {
context.setOutput('some output', 1.01);
assertWriteCalls([`::set-output name=some output::1.01${os.EOL}`]);
});
});
// See: https://github.com/actions/toolkit/blob/a1b068ec31a042ff1e10a522d8fdf0b8869d53ca/packages/core/src/core.ts#L89 // See: https://github.com/actions/toolkit/blob/a1b068ec31a042ff1e10a522d8fdf0b8869d53ca/packages/core/src/core.ts#L89
function getInputName(name: string): string { function getInputName(name: string): string {
return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`; return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
@ -715,11 +697,3 @@ function getInputName(name: string): string {
function setInput(name: string, value: string): void { function setInput(name: string, value: string): void {
process.env[getInputName(name)] = value; process.env[getInputName(name)] = value;
} }
// Assert that process.stdout.write calls called only with the given arguments.
function assertWriteCalls(calls: string[]): void {
expect(process.stdout.write).toHaveBeenCalledTimes(calls.length);
for (let i = 0; i < calls.length; i++) {
expect(process.stdout.write).toHaveBeenNthCalledWith(i + 1, calls[i]);
}
}

16
__tests__/docker.test.ts Normal file
View File

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

View File

@ -51,6 +51,9 @@ inputs:
description: "Do not use cache when building the image" description: "Do not use cache when building the image"
required: false required: false
default: 'false' default: 'false'
no-cache-filters:
description: "Do not cache specified stages"
required: false
outputs: outputs:
description: "List of output destinations (format: type=local,dest=path)" description: "List of output destinations (format: type=local,dest=path)"
required: false required: false
@ -100,6 +103,6 @@ outputs:
description: 'Build result metadata' description: 'Build result metadata'
runs: runs:
using: 'node12' using: 'node16'
main: 'dist/index.js' main: 'dist/index.js'
post: 'dist/index.js' post: 'dist/index.js'

View File

@ -1,8 +1,8 @@
# syntax=docker/dockerfile:1.3-labs # syntax=docker/dockerfile:1
ARG NODE_VERSION ARG NODE_VERSION=16
ARG DOCKER_VERSION=20.10.10 ARG DOCKER_VERSION=20.10.13
ARG BUILDX_VERSION=0.7.0 ARG BUILDX_VERSION=0.8.0
FROM node:${NODE_VERSION}-alpine AS base FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git RUN apk add --no-cache cpio findutils git
@ -57,10 +57,10 @@ RUN --mount=type=bind,target=.,rw \
FROM scratch AS format-update FROM scratch AS format-update
COPY --from=format /out / COPY --from=format /out /
FROM deps AS format-validate FROM deps AS lint
RUN --mount=type=bind,target=.,rw \ RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \ --mount=type=cache,target=/src/node_modules \
yarn run format-check yarn run lint
FROM docker:${DOCKER_VERSION} as docker FROM docker:${DOCKER_VERSION} as docker
FROM docker/buildx-bin:${BUILDX_VERSION} as buildx FROM docker/buildx-bin:${BUILDX_VERSION} as buildx

27909
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

File diff suppressed because one or more lines are too long

1058
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

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,3 @@
variable "NODE_VERSION" {
default = "12"
}
target "node-version" {
args = {
NODE_VERSION = NODE_VERSION
}
}
group "default" { group "default" {
targets = ["build"] targets = ["build"]
} }
@ -17,54 +7,47 @@ group "pre-checkin" {
} }
group "validate" { group "validate" {
targets = ["format-validate", "build-validate", "vendor-validate"] targets = ["lint", "build-validate", "vendor-validate"]
} }
target "build" { target "build" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/build.Dockerfile"
target = "build-update" target = "build-update"
output = ["."] output = ["."]
} }
target "build-validate" { target "build-validate" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/build.Dockerfile"
target = "build-validate" target = "build-validate"
output = ["type=cacheonly"] output = ["type=cacheonly"]
} }
target "format" { target "format" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/build.Dockerfile"
target = "format-update" target = "format-update"
output = ["."] output = ["."]
} }
target "format-validate" { target "lint" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/build.Dockerfile" target = "lint"
target = "format-validate"
output = ["type=cacheonly"] output = ["type=cacheonly"]
} }
target "vendor-update" { target "vendor-update" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/build.Dockerfile"
target = "vendor-update" target = "vendor-update"
output = ["."] output = ["."]
} }
target "vendor-validate" { target "vendor-validate" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/build.Dockerfile"
target = "vendor-validate" target = "vendor-validate"
output = ["type=cacheonly"] output = ["type=cacheonly"]
} }
target "test" { target "test" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/build.Dockerfile"
target = "test-coverage" target = "test-coverage"
output = ["./coverage"] output = ["./coverage"]
} }

View File

@ -6,11 +6,14 @@
* [Cache backend API](#cache-backend-api) * [Cache backend API](#cache-backend-api)
* [Local cache](#local-cache) * [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. > **Note**
>
> See [our guide](https://github.com/docker/buildx/blob/master/docs/guides/cache/index.md)
> for more details about cache storage backends.
## Inline cache ## 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). In most cases you want to use the [`type=inline` cache exporter](https://github.com/docker/buildx/blob/master/docs/guides/cache/inline.md).
However, note that the `inline` cache exporter only supports `min` cache mode. To enable `max` cache mode, push the 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). image and the cache separately by using the `registry` cache exporter as shown in the [next example](#registry-cache).
@ -28,19 +31,19 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true
@ -52,7 +55,7 @@ jobs:
## Registry cache ## Registry cache
You can import/export cache from a cache manifest or (special) image configuration on the registry with the 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). [`type=registry` cache exporter](https://github.com/docker/buildx/blob/master/docs/guides/cache/registry.md).
```yaml ```yaml
name: ci name: ci
@ -68,19 +71,19 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true
@ -93,15 +96,17 @@ jobs:
### Cache backend API ### Cache backend API
> :test_tube: This cache exporter is considered EXPERIMENTAL until further notice. Please provide feedback on > **Warning**
> [BuildKit repository](https://github.com/moby/buildkit) if you encounter any issues. >
> 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), [GitHub Actions cache exporter](https://github.com/docker/buildx/blob/master/docs/guides/cache/gha.md)
you can use the [`type=gha` cache exporter](https://github.com/moby/buildkit/tree/master#github-actions-cache-experimental). 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
GitHub Actions cache exporter backend uses the [GitHub Cache API](https://github.com/tonistiigi/go-actions-cache/blob/master/api.md) exclusively used in a GitHub Action workflow as the `url` (`$ACTIONS_CACHE_URL`)
to fetch and upload cache blobs. That's why this type of cache should be exclusively used in a GitHub Action workflow and `token` (`$ACTIONS_RUNTIME_TOKEN`) attributes are populated when a workflow
as the `url` (`$ACTIONS_CACHE_URL`) and `token` (`$ACTIONS_RUNTIME_TOKEN`) attributes are populated when a workflow
is started. is started.
```yaml ```yaml
@ -118,19 +123,19 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true
@ -141,11 +146,13 @@ jobs:
### Local cache ### 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). > **Warning**
> The `Move cache` step is used as a temporary fix (see https://github.com/moby/buildkit/issues/1896). >
> 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 workaround (see [moby/buildkit#1896](https://github.com/moby/buildkit/issues/1896) for more info).
You can also leverage [GitHub cache](https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows) You can also leverage [GitHub cache](https://docs.github.com/en/actions/using-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) using the [actions/cache](https://github.com/actions/cache) and [`type=local` cache exporter](https://github.com/docker/buildx/blob/master/docs/guides/cache/local.md)
with this action: with this action:
```yaml ```yaml
@ -162,27 +169,27 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Cache Docker layers name: Cache Docker layers
uses: actions/cache@v2 uses: actions/cache@v3
with: with:
path: /tmp/.buildx-cache path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }} key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: | restore-keys: |
${{ runner.os }}-buildx- ${{ runner.os }}-buildx-
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true

View File

@ -1,10 +1,8 @@
# Copy images between registries # Copy images between registries
Multi-platform images built using buildx can be copied from one registry to another without [Multi-platform images](https://docs.docker.com/build/building/multi-platform/)
changing the image SHA using the [tag-push-action](https://github.com/akhilerm/tag-push-action). built using Buildx can be copied from one registry to another using the
[`imagetools create` command](https://docs.docker.com/engine/reference/commandline/buildx_imagetools_create/):
The following workflow will first push the image to dockerhub, run some tests using the images
and then push to quay and ghcr
```yaml ```yaml
name: ci name: ci
@ -20,36 +18,29 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- # quay and ghcr logins for pushing image after testing -
name: Login to Quay Registry name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
registry: quay.io username: ${{ secrets.DOCKERHUB_USERNAME }}
username: ${{ secrets.QUAY_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }}
password: ${{ secrets.QUAY_TOKEN }}
- -
name: Login to GitHub Container Registry name: Login to GitHub Container Registry
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} 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 name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
@ -57,17 +48,11 @@ jobs:
tags: | tags: |
user/app:latest user/app:latest
user/app:1.0.0 user/app:1.0.0
- # run tests using image from docker hub -
name: Run Tests name: Push image to GHCR
run: make tests run: |
- # copy multiplatform image from dockerhub to quay and ghcr docker buildx imagetools create \
name: Push Image to multiple registries --tag ghcr.io/user/app:latest \
uses: akhilerm/tag-push-action@v2.0.0 --tag ghcr.io/user/app:1.0.0 \
with: user/app:latest
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
``` ```

View File

@ -1,7 +1,7 @@
# Update DockerHub repo description # Update Docker Hub repo description
You can update the [DockerHub repository description](https://docs.docker.com/docker-hub/repos/) using You can update the [Docker Hub repository description](https://docs.docker.com/docker-hub/repos/)
a third party action called [DockerHub Description](https://github.com/peter-evans/dockerhub-description) using a third party action called [Docker Hub Description](https://github.com/peter-evans/dockerhub-description)
with this action: with this action:
```yaml ```yaml
@ -18,22 +18,22 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true

View File

@ -1,7 +1,7 @@
# Export image to Docker # 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 You may want your build result to be available in the Docker client through
in another step of your workflow: `docker images` to be able to use it in another step of your workflow:
```yaml ```yaml
name: ci name: ci
@ -17,13 +17,13 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Build name: Build
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
load: true load: true

View File

@ -14,12 +14,12 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
id: builder1 id: builder1
- -
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
id: builder2 id: builder2
- -
name: Builder 1 name name: Builder 1 name
@ -29,14 +29,14 @@ jobs:
run: echo ${{ steps.builder2.outputs.name }} run: echo ${{ steps.builder2.outputs.name }}
- -
name: Build against builder1 name: Build against builder1
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
builder: ${{ steps.builder1.outputs.name }} builder: ${{ steps.builder1.outputs.name }}
context: . context: .
target: mytarget1 target: mytarget1
- -
name: Build against builder2 name: Build against builder2
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
builder: ${{ steps.builder2.outputs.name }} builder: ${{ steps.builder2.outputs.name }}
context: . context: .

View File

@ -1,6 +1,7 @@
# Local registry # Local registry
For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry) to push images into: For testing purposes you may need to create a [local registry](https://hub.docker.com/_/registry)
to push images into:
```yaml ```yaml
name: ci name: ci
@ -21,18 +22,18 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
driver-opts: network=host driver-opts: network=host
- -
name: Build and push to local registry name: Build and push to local registry
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true

View File

@ -1,10 +1,14 @@
# Multi-platform image # Multi-platform image
You can build multi-platform images using the [`platforms` input](../../README.md#inputs) as described below. You can build [multi-platform images](https://docs.docker.com/build/building/multi-platform/)
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. > **Note**
>
> :bulb: If you want support for more platforms, you can use QEMU with our [setup-qemu](https://github.com/docker/setup-qemu-action) action. > * List of available platforms will be displayed and available through our
> [setup-buildx](https://github.com/docker/setup-buildx-action#about) action.
> * If you want support for more platforms, you can use QEMU with our
> [setup-qemu](https://github.com/docker/setup-qemu-action) action.
```yaml ```yaml
name: ci name: ci
@ -20,22 +24,22 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64

View File

@ -0,0 +1,98 @@
# Named contexts
You can define [additional build contexts](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context)
that can be accessed in your Dockerfile with `FROM name` or `--from=name`. When
Dockerfile defines a stage with the same name it is overwritten.
This can be useful with GitHub Actions to reuse results from other builds or
pin an image to a spcific tag in your workflow.
* [Pin image to a specific tag](#pin-image-to-a-specific-tag)
* [Usage of the built image in other build steps](#usage-of-the-built-image-in-other-build-steps)
## Pin image to a specific tag
Replace `alpine:latest` with a pinned one:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
```
```yaml
name: ci
on:
push:
branches:
- 'main'
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build
uses: docker/build-push-action@v3
with:
context: .
build-contexts: |
alpine=docker-image://alpine:3.16
tags: myimage:latest
```
## Usage of the built image in other build steps
By default, the [`setup-buildx` action](https://github.com/docker/setup-buildx-action#about)
uses `docker-container` as a build driver, so built Docker images are not
available in the builder container.
With named contexts you can reuse the built image:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello World"
```
```yaml
name: ci
on:
push:
branches:
- 'main'
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build base image
uses: docker/build-push-action@v3
with:
context: base
load: true
tags: my-base-image:latest
-
name: Build
uses: docker/build-push-action@v3
with:
context: .
build-contexts: |
alpine=docker-image://my-base-image:latest
tags: myimage:latest
```

View File

@ -1,12 +1,8 @@
# Push to multi-registries # Push to multi-registries
* [Docker Hub and GHCR](#docker-hub-and-ghcr) The following workflow will connect you to [Docker Hub](https://github.com/docker/login-action#dockerhub)
and [GitHub Container Registry](https://github.com/docker/login-action#github-container-registry)
## Docker Hub and GHCR and push the image to these registries:
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 ```yaml
name: ci name: ci
@ -22,29 +18,29 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Login to GitHub Container Registry name: Login to GitHub Container Registry
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64

View File

@ -1,20 +1,19 @@
# Secrets # 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) In the following example we will expose and use the [GITHUB_TOKEN secret](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret)
as provided by GitHub in your workflow. as provided by GitHub in your workflow.
First let's create our `Dockerfile` to use our secret: First let's create our `Dockerfile` to use our secret:
```Dockerfile ```dockerfile
#syntax=docker/dockerfile:1.2 # syntax=docker/dockerfile:1
FROM alpine FROM alpine
RUN --mount=type=secret,id=github_token \ RUN --mount=type=secret,id=github_token \
cat /run/secrets/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 As you can see we have named our secret `github_token`. Here is the workflow
the [`secrets` input](../../README.md#inputs): you can use to expose this secret using the [`secrets` input](../../README.md#inputs):
```yaml ```yaml
name: ci name: ci
@ -30,16 +29,16 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Build name: Build
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
@ -48,14 +47,17 @@ jobs:
"github_token=${{ secrets.GITHUB_TOKEN }}" "github_token=${{ secrets.GITHUB_TOKEN }}"
``` ```
> :bulb: You can also expose a secret file to the build with [`secret-files`](../../README.md#inputs) input: > **Note**
>
> You can also expose a secret file to the build with the [`secret-files`](../../README.md#inputs) input:
> ```yaml > ```yaml
> secret-files: | > secret-files: |
> "MY_SECRET=./secret.txt" > "MY_SECRET=./secret.txt"
> ``` > ```
If you're using [GitHub secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) and need to handle If you're using [GitHub secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)
multi-line value, you will need to place the key-value pair between quotes: and need to handle multi-line value, you will need to place the key-value pair
between quotes:
```yaml ```yaml
secrets: | secrets: |
@ -72,13 +74,15 @@ secrets: |
"JSON_SECRET={""key1"":""value1"",""key2"":""value2""}" "JSON_SECRET={""key1"":""value1"",""key2"":""value2""}"
``` ```
| Key | Value | | Key | Value |
|--------------------|--------------------------------------------------| |--------------------|-------------------------------------|
| `MYSECRET` | `***********************` | | `MYSECRET` | `***********************` |
| `GIT_AUTH_TOKEN` | `abcdefghi,jklmno=0123456789` | | `GIT_AUTH_TOKEN` | `abcdefghi,jklmno=0123456789` |
| `MYSECRET` | `aaaaaaaa\nbbbbbbb\nccccccccc` | | `MYSECRET` | `aaaaaaaa\nbbbbbbb\nccccccccc` |
| `FOO` | `bar` | | `FOO` | `bar` |
| `EMPTYLINE` | `aaaa\n\nbbbb\nccc` | | `EMPTYLINE` | `aaaa\n\nbbbb\nccc` |
| `JSON_SECRET` | `{"key1":"value1","key2":"value2"}` | | `JSON_SECRET` | `{"key1":"value1","key2":"value2"}` |
> :bulb: All quote signs need to be doubled for escaping. > **Note**
>
> All quote signs need to be doubled for escaping.

View File

@ -1,8 +1,10 @@
# Share built image between jobs # 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)). As each job is isolated in its own runner you cannot use your built image
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) between jobs (except for [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners)).
using the [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/download-artifact](https://github.com/actions/download-artifact) However, you can [pass data between jobs in a workflow](https://docs.github.com/en/actions/using-workflows/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: actions:
```yaml ```yaml
@ -19,20 +21,20 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Build and export name: Build and export
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
tags: myimage:latest tags: myimage:latest
outputs: type=docker,dest=/tmp/myimage.tar outputs: type=docker,dest=/tmp/myimage.tar
- -
name: Upload artifact name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: myimage name: myimage
path: /tmp/myimage.tar path: /tmp/myimage.tar
@ -43,10 +45,10 @@ jobs:
steps: steps:
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Download artifact name: Download artifact
uses: actions/download-artifact@v2 uses: actions/download-artifact@v3
with: with:
name: myimage name: myimage
path: /tmp path: /tmp

View File

@ -1,8 +1,9 @@
# Handle tags and labels # 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) 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) for labels, you can do it in a dedicated step. The following workflow will use
to handle tags and labels based on GitHub actions events and Git metadata. the [Docker metadata action](https://github.com/docker/metadata-action) to
handle tags and labels based on GitHub actions events and Git metadata:
```yaml ```yaml
name: ci name: ci
@ -25,11 +26,11 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Docker meta name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v3 uses: docker/metadata-action@v4
with: with:
# list of Docker images to use as base name for tags # list of Docker images to use as base name for tags
images: | images: |
@ -46,28 +47,28 @@ jobs:
type=sha type=sha
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Login to GHCR name: Login to GHCR
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: ${{ github.event_name != 'pull_request' }} push: ${{ github.event_name != 'pull_request' }}

View File

@ -25,22 +25,22 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v2
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
- -
name: Login to DockerHub name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- -
name: Build and export to Docker name: Build and export to Docker
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
load: true load: true
@ -51,14 +51,16 @@ jobs:
docker run --rm ${{ env.TEST_TAG }} docker run --rm ${{ env.TEST_TAG }}
- -
name: Build and push name: Build and push
uses: docker/build-push-action@v2 uses: docker/build-push-action@v3
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: user/app:latest tags: ${{ env.TEST_TAG }}
``` ```
> :bulb: Build time will not be increased with this workflow because internal > **Note**
> cache for `linux/amd64` will be used from previous step on `Build and push` >
> step so only `linux/arm64` will be actually built. > 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.

View File

@ -1,12 +1,13 @@
module.exports = { module.exports = {
clearMocks: false, clearMocks: false,
moduleFileExtensions: ['js', 'ts'], moduleFileExtensions: ['js', 'ts'],
setupFiles: ["dotenv/config"], setupFiles: ['dotenv/config'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'], testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: { transform: {
'^.+\\.ts$': 'ts-jest' '^.+\\.ts$': 'ts-jest'
}, },
verbose: false moduleNameMapper: {
} '^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
},
verbose: true
};

View File

@ -3,11 +3,11 @@
"description": "Build and push Docker images", "description": "Build and push Docker images",
"main": "lib/main.js", "main": "lib/main.js",
"scripts": { "scripts": {
"build": "tsc && ncc build", "build": "ncc build src/main.ts --source-map --minify --license licenses.txt",
"format": "prettier --write **/*.ts", "lint": "eslint src/**/*.ts __tests__/**/*.ts",
"format-check": "prettier --check **/*.ts", "format": "eslint --fix src/**/*.ts __tests__/**/*.ts",
"test": "jest --coverage", "test": "jest --coverage",
"pre-checkin": "yarn run format && yarn run build" "all": "yarn run build && yarn run format && yarn test"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -28,27 +28,31 @@
], ],
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@actions/core": "^1.6.0", "@actions/core": "^1.10.0",
"@actions/exec": "^1.1.0", "@actions/exec": "^1.1.1",
"@actions/github": "^5.0.0", "@actions/github": "^5.1.1",
"csv-parse": "^4.16.3", "csv-parse": "^5.3.0",
"handlebars": "^4.7.7", "handlebars": "^4.7.7",
"semver": "^7.3.5", "semver": "^7.3.7",
"tmp": "^0.2.1" "tmp": "^0.2.1"
}, },
"devDependencies": { "devDependencies": {
"@types/csv-parse": "^1.2.2", "@types/csv-parse": "^1.2.2",
"@types/jest": "^26.0.23", "@types/node": "^16.11.26",
"@types/node": "^14.17.4", "@types/semver": "^7.3.9",
"@types/tmp": "^0.2.0", "@types/tmp": "^0.2.3",
"@vercel/ncc": "^0.28.6", "@typescript-eslint/eslint-plugin": "^5.14.0",
"dotenv": "^8.6.0", "@typescript-eslint/parser": "^5.14.0",
"jest": "^26.6.3", "@vercel/ncc": "^0.33.3",
"jest-circus": "^26.6.3", "dotenv": "^16.0.0",
"jest-runtime": "^26.6.3", "eslint": "^8.11.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "^26.1.1",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.2.5",
"prettier": "^2.3.1", "prettier": "^2.3.1",
"ts-jest": "^26.5.6", "ts-jest": "^27.1.2",
"typescript": "^4.3.4", "ts-node": "^10.7.0",
"typescript-formatter": "^7.2.2" "typescript": "^4.4.4"
} }
} }

View File

@ -1,4 +1,4 @@
import csvparse from 'csv-parse/lib/sync'; import {parse} from 'csv-parse/sync';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
@ -76,19 +76,20 @@ export async function getSecret(kvp: string, file: boolean): Promise<string> {
return `id=${key},src=${secretFile}`; return `id=${key},src=${secretFile}`;
} }
export function isLocalOrTarExporter(outputs: string[]): Boolean { export function isLocalOrTarExporter(outputs: string[]): boolean {
for (let output of csvparse(outputs.join(`\n`), { const records = parse(outputs.join(`\n`), {
delimiter: ',', delimiter: ',',
trim: true, trim: true,
columns: false, columns: false,
relaxColumnCount: true relaxColumnCount: true
})) { });
for (const record of records) {
// Local if no type is defined // Local if no type is defined
// https://github.com/docker/buildx/blob/d2bf42f8b4784d83fde17acb3ed84703ddc2156b/build/output.go#L29-L43 // https://github.com/docker/buildx/blob/d2bf42f8b4784d83fde17acb3ed84703ddc2156b/build/output.go#L29-L43
if (output.length == 1 && !output[0].startsWith('type=')) { if (record.length == 1 && !record[0].startsWith('type=')) {
return true; return true;
} }
for (let [key, value] of output.map(chunk => chunk.split('=').map(item => item.trim()))) { for (const [key, value] of record.map(chunk => chunk.split('=').map(item => item.trim()))) {
if (key == 'type' && (value == 'local' || value == 'tar')) { if (key == 'type' && (value == 'local' || value == 'tar')) {
return true; return true;
} }
@ -97,8 +98,8 @@ export function isLocalOrTarExporter(outputs: string[]): Boolean {
return false; return false;
} }
export function hasGitAuthToken(secrets: string[]): Boolean { export function hasGitAuthToken(secrets: string[]): boolean {
for (let secret of secrets) { for (const secret of secrets) {
if (secret.startsWith('GIT_AUTH_TOKEN=')) { if (secret.startsWith('GIT_AUTH_TOKEN=')) {
return true; return true;
} }
@ -106,9 +107,10 @@ export function hasGitAuthToken(secrets: string[]): Boolean {
return false; return false;
} }
export async function isAvailable(): Promise<Boolean> { export async function isAvailable(standalone?: boolean): Promise<boolean> {
const cmd = getCommand([], standalone);
return await exec return await exec
.getExecOutput('docker', ['buildx'], { .getExecOutput(cmd.command, cmd.args, {
ignoreReturnCode: true, ignoreReturnCode: true,
silent: true silent: true
}) })
@ -117,12 +119,17 @@ export async function isAvailable(): Promise<Boolean> {
return false; return false;
} }
return res.exitCode == 0; return res.exitCode == 0;
})
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.catch(error => {
return false;
}); });
} }
export async function getVersion(): Promise<string> { export async function getVersion(standalone?: boolean): Promise<string> {
const cmd = getCommand(['version'], standalone);
return await exec return await exec
.getExecOutput('docker', ['buildx', 'version'], { .getExecOutput(cmd.command, cmd.args, {
ignoreReturnCode: true, ignoreReturnCode: true,
silent: true silent: true
}) })
@ -145,3 +152,10 @@ export function parseVersion(stdout: string): string {
export function satisfies(version: string, range: string): boolean { export function satisfies(version: string, range: string): boolean {
return semver.satisfies(version, range) || /^[0-9a-f]{7}$/.exec(version) !== null; return semver.satisfies(version, range) || /^[0-9a-f]{7}$/.exec(version) !== null;
} }
export function getCommand(args: Array<string>, standalone?: boolean) {
return {
command: standalone ? 'buildx' : 'docker',
args: standalone ? args : ['buildx', ...args]
};
}

View File

@ -1,14 +1,11 @@
import csvparse from 'csv-parse/lib/sync';
import * as fs from 'fs'; import * as fs from 'fs';
import * as os from 'os'; import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import * as tmp from 'tmp'; 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 buildx from './buildx';
import * as core from '@actions/core';
import * as github from '@actions/github';
import {parse} from 'csv-parse/sync';
import * as handlebars from 'handlebars'; import * as handlebars from 'handlebars';
let _defaultContext, _tmpDir: string; let _defaultContext, _tmpDir: string;
@ -28,6 +25,7 @@ export interface Inputs {
load: boolean; load: boolean;
network: string; network: string;
noCache: boolean; noCache: boolean;
noCacheFilters: string[];
outputs: string[]; outputs: string[];
platforms: string[]; platforms: string[];
pull: boolean; pull: boolean;
@ -83,6 +81,7 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
load: core.getBooleanInput('load'), load: core.getBooleanInput('load'),
network: core.getInput('network'), network: core.getInput('network'),
noCache: core.getBooleanInput('no-cache'), noCache: core.getBooleanInput('no-cache'),
noCacheFilters: await getInputList('no-cache-filters'),
outputs: await getInputList('outputs', true), outputs: await getInputList('outputs', true),
platforms: await getInputList('platforms'), platforms: await getInputList('platforms'),
pull: core.getBooleanInput('pull'), pull: core.getBooleanInput('pull'),
@ -99,15 +98,17 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
} }
export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> { export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
let args: Array<string> = ['buildx']; const context = handlebars.compile(inputs.context)({defaultContext});
args.push.apply(args, await getBuildArgs(inputs, defaultContext, buildxVersion)); // prettier-ignore
args.push.apply(args, await getCommonArgs(inputs, buildxVersion)); return [
args.push(handlebars.compile(inputs.context)({defaultContext})); ...await getBuildArgs(inputs, defaultContext, context, buildxVersion),
return args; ...await getCommonArgs(inputs, buildxVersion),
context
];
} }
async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> { async function getBuildArgs(inputs: Inputs, defaultContext: string, context: string, buildxVersion: string): Promise<Array<string>> {
let args: Array<string> = ['build']; const args: Array<string> = ['build'];
await asyncForEach(inputs.addHosts, async addHost => { await asyncForEach(inputs.addHosts, async addHost => {
args.push('--add-host', addHost); args.push('--add-host', addHost);
}); });
@ -140,6 +141,9 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
await asyncForEach(inputs.labels, async label => { await asyncForEach(inputs.labels, async label => {
args.push('--label', label); args.push('--label', label);
}); });
await asyncForEach(inputs.noCacheFilters, async noCacheFilter => {
args.push('--no-cache-filter', noCacheFilter);
});
await asyncForEach(inputs.outputs, async output => { await asyncForEach(inputs.outputs, async output => {
args.push('--output', output); args.push('--output', output);
}); });
@ -160,7 +164,7 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
core.warning(err.message); core.warning(err.message);
} }
}); });
if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) { if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && context.startsWith(defaultContext)) {
args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
} }
if (inputs.shmSize) { if (inputs.shmSize) {
@ -182,7 +186,7 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
} }
async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> { async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> {
let args: Array<string> = []; const args: Array<string> = [];
if (inputs.builder) { if (inputs.builder) {
args.push('--builder', inputs.builder); args.push('--builder', inputs.builder);
} }
@ -208,27 +212,29 @@ async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Arr
} }
export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> { export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> {
let res: Array<string> = []; const res: Array<string> = [];
const items = core.getInput(name); const items = core.getInput(name);
if (items == '') { if (items == '') {
return res; return res;
} }
for (let output of (await csvparse(items, { const records = await parse(items, {
columns: false, columns: false,
relax: true, relaxQuotes: true,
relaxColumnCount: true, relaxColumnCount: true,
skipLinesWithEmptyValues: true skipEmptyLines: true
})) as Array<string[]>) { });
if (output.length == 1) {
res.push(output[0]); for (const record of records as Array<string[]>) {
if (record.length == 1) {
res.push(record[0]);
continue; continue;
} else if (!ignoreComma) { } else if (!ignoreComma) {
res.push(...output); res.push(...record);
continue; continue;
} }
res.push(output.join(',')); res.push(record.join(','));
} }
return res.filter(item => item).map(pat => pat.trim()); return res.filter(item => item).map(pat => pat.trim());
@ -239,8 +245,3 @@ export const asyncForEach = async (array, callback) => {
await callback(array[index], index, array); await callback(array[index], index, array);
} }
}; };
// FIXME: Temp fix https://github.com/actions/toolkit/issues/777
export function setOutput(name: string, value: any): void {
issueCommand('set-output', {name}, value);
}

19
src/docker.ts Normal file
View File

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

View File

@ -1,35 +1,55 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as buildx from './buildx'; import * as buildx from './buildx';
import * as context from './context'; import * as context from './context';
import * as docker from './docker';
import * as stateHelper from './state-helper'; import * as stateHelper from './state-helper';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
async function run(): Promise<void> { async function run(): Promise<void> {
try { try {
const defContext = context.defaultContext();
const inputs: context.Inputs = await context.getInputs(defContext);
// standalone if docker cli not available
const standalone = !(await docker.isAvailable());
core.startGroup(`Docker info`); core.startGroup(`Docker info`);
await exec.exec('docker', ['version']); if (standalone) {
await exec.exec('docker', ['info']); core.info(`Docker info skipped in standalone mode`);
} else {
await exec.exec('docker', ['version'], {
failOnStdErr: false
});
await exec.exec('docker', ['info'], {
failOnStdErr: false
});
}
core.endGroup(); core.endGroup();
if (!(await buildx.isAvailable())) { if (!(await buildx.isAvailable(standalone))) {
core.setFailed(`Docker buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`); core.setFailed(`Docker buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`);
return; return;
} }
stateHelper.setTmpDir(context.tmpDir()); stateHelper.setTmpDir(context.tmpDir());
const buildxVersion = await buildx.getVersion(); const buildxVersion = await buildx.getVersion(standalone);
const defContext = context.defaultContext(); await core.group(`Buildx version`, async () => {
let inputs: context.Inputs = await context.getInputs(defContext); const versionCmd = buildx.getCommand(['version'], standalone);
await exec.exec(versionCmd.command, versionCmd.args, {
failOnStdErr: false
});
});
const args: string[] = await context.getArgs(inputs, defContext, buildxVersion); const args: string[] = await context.getArgs(inputs, defContext, buildxVersion);
const buildCmd = buildx.getCommand(args, standalone);
await exec await exec
.getExecOutput('docker', args, { .getExecOutput(buildCmd.command, buildCmd.args, {
ignoreReturnCode: true ignoreReturnCode: true
}) })
.then(res => { .then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) { if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)![0].trim()}`); throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
} }
}); });
@ -40,19 +60,19 @@ async function run(): Promise<void> {
if (imageID) { if (imageID) {
await core.group(`ImageID`, async () => { await core.group(`ImageID`, async () => {
core.info(imageID); core.info(imageID);
context.setOutput('imageid', imageID); core.setOutput('imageid', imageID);
}); });
} }
if (digest) { if (digest) {
await core.group(`Digest`, async () => { await core.group(`Digest`, async () => {
core.info(digest); core.info(digest);
context.setOutput('digest', digest); core.setOutput('digest', digest);
}); });
} }
if (metadata) { if (metadata) {
await core.group(`Metadata`, async () => { await core.group(`Metadata`, async () => {
core.info(metadata); core.info(metadata);
context.setOutput('metadata', metadata); core.setOutput('metadata', metadata);
}); });
} }
} catch (error) { } catch (error) {
@ -63,7 +83,7 @@ async function run(): Promise<void> {
async function cleanup(): Promise<void> { async function cleanup(): Promise<void> {
if (stateHelper.tmpDir.length > 0) { if (stateHelper.tmpDir.length > 0) {
core.startGroup(`Removing temp folder ${stateHelper.tmpDir}`); core.startGroup(`Removing temp folder ${stateHelper.tmpDir}`);
fs.rmdirSync(stateHelper.tmpDir, {recursive: true}); fs.rmSync(stateHelper.tmpDir, {recursive: true});
core.endGroup(); core.endGroup();
} }
} }

View File

@ -1,3 +1,3 @@
# syntax=docker/dockerfile:1
FROM alpine FROM alpine
RUN echo "Hello world!" RUN echo "Hello world!"

View File

@ -1,2 +1,3 @@
# syntax=docker/dockerfile:1
FROM busybox FROM busybox
RUN cat /etc/hosts RUN cat /etc/hosts

View File

@ -1,3 +1,3 @@
# syntax=docker/dockerfile-upstream:master # syntax=docker/dockerfile:1
FROM alpine FROM alpine
RUN cat /etc/*release RUN cat /etc/*release

View File

@ -1,2 +1,3 @@
# syntax=docker/dockerfile:1
FROM alpine FROM alpine
RUN cat /proc/self/cgroup RUN cat /proc/self/cgroup

View File

@ -1,9 +1,8 @@
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:alpine AS build FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM ARG TARGETPLATFORM
ARG BUILDPLATFORM ARG BUILDPLATFORM
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
RUN apk --update --no-cache add \ RUN apk --update --no-cache add \
shadow \ shadow \
sudo \ sudo \
@ -17,6 +16,5 @@ RUN sudo chown buildx. /log
USER root USER root
FROM alpine FROM alpine
COPY --from=build /log /log COPY --from=build /log /log
RUN ls -al /log RUN ls -al /log

View File

@ -1,3 +1,4 @@
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:alpine AS build FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM ARG TARGETPLATFORM

View 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

4
test/secret.Dockerfile Normal file
View File

@ -0,0 +1,4 @@
# syntax=docker/dockerfile:1
FROM busybox
RUN --mount=type=secret,id=MYSECRET \
echo "MYSECRET=$(cat /run/secrets/MYSECRET)"

View File

@ -1,2 +1,3 @@
# syntax=docker/dockerfile:1
FROM busybox FROM busybox
RUN mount | grep /dev/shm RUN mount | grep /dev/shm

View File

@ -1,2 +1,3 @@
# syntax=docker/dockerfile:1
FROM busybox FROM busybox
RUN ulimit -a RUN ulimit -a

View File

@ -2,20 +2,18 @@
"compilerOptions": { "compilerOptions": {
"target": "es6", "target": "es6",
"module": "commonjs", "module": "commonjs",
"lib": [
"es6",
"dom"
],
"newLine": "lf", "newLine": "lf",
"outDir": "./lib", "outDir": "./lib",
"rootDir": "./src", "rootDir": "./src",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true, "strict": true,
"noImplicitAny": false, "noImplicitAny": false,
"esModuleInterop": true, "useUnknownInCatchVariables": false,
"sourceMap": true
}, },
"exclude": [ "exclude": [
"node_modules", "node_modules",
"**/*.test.ts" "**/*.test.ts",
"jest.config.ts"
] ]
} }

3273
yarn.lock

File diff suppressed because it is too large Load Diff