Compare commits

..

117 Commits

Author SHA1 Message Date
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
ac9327eae2 Merge pull request #563 from crazy-max/new-inputs
`build-contexts` input
2022-03-14 20:15:50 +01:00
7c41daf2a5 build-contexts input
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-14 20:09:15 +01:00
e115266953 Merge pull request #569 from crazy-max/imageid-digest
add imageid output and use metadata to set digest output
2022-03-14 20:03:35 +01:00
50fa0058d9 add imageid output and use metadata to set digest output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-14 19:30:54 +01:00
309fb9180f Merge pull request #568 from docker/dependabot/github_actions/actions/checkout-3
Bump actions/checkout from 2 to 3
2022-03-04 19:16:11 +01:00
db68526220 Bump actions/checkout from 2 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-02 11:03:44 +00:00
fe02965b48 Merge pull request #559 from crazy-max/outputs
Enhance outputs display
2022-02-09 11:41:29 +01:00
5af8693d82 Enhance outputs display
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-09 11:32:44 +01:00
7f9d37fa54 Merge pull request #555 from crazy-max/fix-add-host
Fix add-hosts context
2022-01-31 11:53:18 +01:00
d7458455bb Fix add-hosts context
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-31 11:47:45 +01:00
1ca185b339 Merge pull request #553 from crazy-max/add-host
`add-host` input
2022-01-31 10:14:02 +01:00
eebf87aed1 add-host input
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-30 18:33:31 +01:00
d8b0ca6f0e Merge pull request #552 from crazy-max/readme
Fix git context subdir example and improve README
2022-01-30 18:15:27 +01:00
da767377fb Fix git context subdir example and improve README
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-30 18:12:55 +01:00
8c76bb76c2 Merge pull request #549 from docker/dependabot/npm_and_yarn/node-fetch-2.6.7
Bump node-fetch from 2.6.1 to 2.6.7
2022-01-27 13:57:49 +01:00
b598b2a3bd Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-27 13:55:08 +01:00
eb2857f4ca Bump node-fetch from 2.6.1 to 2.6.7
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-27 11:58:42 +00:00
f4cf574474 Merge pull request #548 from crazy-max/e2e-acr
Add e2e tests for ACR
2022-01-27 12:58:15 +01:00
5c924147ba Add e2e tests for ACR
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-27 11:38:10 +01:00
253376207c Merge pull request #544 from KMConner/readme-add-token-option
Add description on `github-token` option to README
2022-01-25 19:15:53 +01:00
6f7a604875 Add description on github-token option to README
Signed-off-by: KMConner <KMConner@users.noreply.github.com>
2022-01-24 20:28:48 +09:00
604f033158 Merge pull request #542 from crazy-max/update-readme
Note about new inputs
2022-01-18 15:02:20 +01:00
5645ea7274 Note about new inputs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-18 14:57:36 +01:00
1814d3dfb3 Merge pull request #531 from BeyondEvil/subdir-with-default-context
Add subdirectory for Git context
2022-01-12 13:49:37 +01:00
fc5a732e0c Add subdirectory for Git context
Since v0.9.0 of BuildKit (BuildX v0.7.0) you can provide a subdirectory
to the default Git context.

Closes #460
Closes #528

Signed-off-by: Jim Brännlund <jimbrannlund@fastmail.com>
2022-01-06 01:38:18 +01:00
b1aeb1103e Merge pull request #510 from crazy-max/venv
ci: virtual env file system info
2021-12-02 19:47:58 +01:00
e31f93ab9f ci: virtual env file system info
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-12-02 19:45:34 +01:00
9ed5823618 Merge pull request #501 from crazy-max/new-inputs
add `cgroup-parent`, `shm-size`, `ulimit` inputs
2021-11-17 08:21:46 +01:00
4222161e3e Merge pull request #500 from crazy-max/readme
readme: remove v1 section
2021-11-16 20:50:23 +01:00
67ff4df4b7 add cgroup-parent, shm-size, ulimit inputs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-16 07:19:39 +01:00
91274a04da sort flags
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-16 05:19:44 +01:00
ff329397c0 readme: remove v1 section
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-16 05:01:51 +01:00
04841f2a72 Merge pull request #499 from crazy-max/update-workflow
dev: update workflow
2021-11-16 04:57:00 +01:00
049b7cab08 dev: update workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-16 04:53:10 +01:00
0a196c9deb Merge pull request #495 from crazy-max/images
ci: list preloaded docker images
2021-11-10 12:06:46 +01:00
94e0a28d6a ci: list preloaded docker images
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-10 12:04:28 +01:00
5e11b373bf Merge pull request #478 from crazy-max/virtual-envs
ci: update virtual envs
2021-10-05 10:58:16 +02:00
6f3b90dea1 ci: update virtual envs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-05 10:56:09 +02:00
f71a68fb09 Merge pull request #474 from docker/dependabot/npm_and_yarn/actions/core-1.6.0
Bump @actions/core from 1.5.0 to 1.6.0
2021-10-04 13:13:49 +02:00
82446970f9 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-04 13:11:37 +02:00
2cf7b61533 Merge pull request #476 from crazy-max/metadata-example
docs: example to sanitize tags with metadata-action
2021-10-02 18:43:57 +02:00
0732bea0f8 docs: example to sanitize tags with metadata-action
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-02 18:37:02 +02:00
96daefdf52 Merge pull request #475 from crazy-max/fix-docs
docs: wrong syntax to sanitize repo slug
2021-10-02 18:25:34 +02:00
9f46d13e71 docs: wrong syntax to sanitize repo slug
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-02 18:23:03 +02:00
a8f79af565 Bump @actions/core from 1.5.0 to 1.6.0
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.5.0 to 1.6.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>
2021-09-29 11:03:05 +00:00
04d5124fcb Merge pull request #473 from akhilerm/patch-1
docs: update tag-push-action to v2
2021-09-28 11:49:58 +02:00
541dfa92f4 update tag-push-action to v2
update tag push action to v2 which uses crane instead of containerd
for pushing the images

Signed-off-by: Akhil Mohan <akhil.mohan@mayadata.io>
2021-09-28 12:43:43 +05:30
291bae5a41 Merge pull request #470 from crazy-max/fix-outputs
Don't set outputs if empty or nil
2021-09-24 16:52:57 +02:00
91520dfd9f Don't set outputs if empty or nil
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-24 16:49:17 +02:00
a41d90ba13 Merge pull request #469 from docker/dependabot/npm_and_yarn/ansi-regex-5.0.1
Bump ansi-regex from 5.0.0 to 5.0.1
2021-09-24 14:52:51 +02:00
22baeb6cdf Bump ansi-regex from 5.0.0 to 5.0.1
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-24 12:07:06 +00:00
6061a365d8 Merge pull request #465 from docker/dependabot/npm_and_yarn/tmpl-1.0.5
Bump tmpl from 1.0.4 to 1.0.5
2021-09-24 14:06:38 +02:00
9962be8aaf Bump tmpl from 1.0.4 to 1.0.5
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-22 02:08:36 +00:00
375f72aff6 Merge pull request #459 from docker/dependabot/npm_and_yarn/csv-parse-4.16.3
Bump csv-parse from 4.16.2 to 4.16.3
2021-09-03 13:21:09 +02:00
8ba85ead00 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-03 13:18:53 +02:00
c6dca826de Bump csv-parse from 4.16.2 to 4.16.3
Bumps [csv-parse](https://github.com/wdavidw/node-csv-parse) from 4.16.2 to 4.16.3.
- [Release notes](https://github.com/wdavidw/node-csv-parse/releases)
- [Commits](https://github.com/wdavidw/node-csv-parse/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-03 11:03:15 +00:00
0c3d31c275 Merge pull request #451 from docker/dependabot/npm_and_yarn/csv-parse-4.16.2
Bump csv-parse from 4.16.0 to 4.16.2
2021-09-02 18:36:50 +02:00
5681933133 Update generated content
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-02 18:35:05 +02:00
821890eae4 Merge pull request #443 from alextes/patch-1
fix typo
2021-09-02 11:04:46 +02:00
d0931a71a9 Merge pull request #455 from crazy-max/doc
Test before pushing your image (docs)
2021-09-01 21:14:14 +02:00
326ec1ede4 Test before pushing your image (docs)
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-01 16:47:59 +02:00
b0c26e5619 fix typo
Signed-off-by: Alexander Tesfamichael <alex.tesfamichael@gmail.com>
2021-08-31 15:35:22 +02:00
3139e8d280 Bump csv-parse from 4.16.0 to 4.16.2
Bumps [csv-parse](https://github.com/wdavidw/node-csv-parse) from 4.16.0 to 4.16.2.
- [Release notes](https://github.com/wdavidw/node-csv-parse/releases)
- [Commits](https://github.com/wdavidw/node-csv-parse/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-30 11:03:34 +00:00
49 changed files with 3864 additions and 19533 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"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -4,10 +4,10 @@ on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: branches:
- master - 'master'
pull_request: pull_request:
branches: branches:
- master - 'master'
jobs: jobs:
minimal: minimal:
@ -15,21 +15,17 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
with: with:
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
- -
name: Build name: Build
uses: ./action uses: ./action
with: with:
file: ./test/Dockerfile file: ./test/Dockerfile
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
git-context: git-context:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -41,16 +37,16 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
with: with:
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: latest
driver-opts: network=host driver-opts: network=host
@ -77,10 +73,6 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
git-context-secret: git-context-secret:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -92,16 +84,16 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
with: with:
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 driver-opts: network=host
- -
@ -137,10 +129,6 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
path-context: path-context:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -158,14 +146,14 @@ 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
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: ${{ matrix.buildx-version }} version: ${{ matrix.buildx-version }}
driver-opts: network=host driver-opts: network=host
@ -192,17 +180,13 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
error: error:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Stop docker name: Stop docker
run: | run: |
@ -223,23 +207,19 @@ jobs:
echo "::error::Should have failed" echo "::error::Should have failed"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
error-buildx: error-buildx:
runs-on: ubuntu-latest runs-on: ubuntu-latest
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
id: docker_build id: docker_build
@ -259,10 +239,6 @@ jobs:
echo "::error::Should have failed" echo "::error::Should have failed"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
docker-driver: docker-driver:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -274,7 +250,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Build name: Build
id: docker_build id: docker_build
@ -284,17 +260,13 @@ jobs:
file: ./test/Dockerfile file: ./test/Dockerfile
push: true push: true
tags: localhost:5000/name/app:latest tags: localhost:5000/name/app:latest
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
export-docker: export-docker:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- -
name: Build name: Build
uses: ./ uses: ./
@ -307,20 +279,16 @@ jobs:
name: Inspect name: Inspect
run: | run: |
docker image inspect myimage:latest docker image inspect myimage:latest
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
network: network:
runs-on: ubuntu-latest runs-on: ubuntu-latest
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: List networks name: List networks
run: docker network ls run: docker network ls
@ -331,10 +299,130 @@ jobs:
context: ./test context: ./test
tags: name/app:latest tags: name/app:latest
network: host network: host
shm-size:
runs-on: ubuntu-latest
steps:
- -
name: Dump context name: Checkout
if: always() uses: actions/checkout@v3
uses: crazy-max/ghaction-dump-context@v1 -
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: |
image=moby/buildkit:master
-
name: Build
uses: ./
with:
context: ./test
file: ./test/shmsize.Dockerfile
tags: name/app:latest
shm-size: 2g
ulimit:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: |
image=moby/buildkit:master
-
name: Build
uses: ./
with:
context: ./test
file: ./test/ulimit.Dockerfile
tags: name/app:latest
ulimit: |
nofile=1024:1024
nproc=3
cgroup-parent:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: |
image=moby/buildkit:master
-
name: Build
uses: ./
with:
context: ./test
file: ./test/cgroup.Dockerfile
tags: name/app:latest
cgroup-parent: foo
add-hosts:
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: ./
with:
context: ./test
file: ./test/addhost.Dockerfile
tags: name/app:latest
add-hosts: |
docker:10.180.0.1
foo:10.0.0.1
build-contexts:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build
uses: ./
with:
context: ./test
file: ./test/buildcontext.Dockerfile
build-contexts: |
alpine=docker-image://debian:stable-slim
tags: name/app:latest
no-cache-filters:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
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
@ -355,14 +443,14 @@ 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
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
version: ${{ matrix.buildx-version }} version: ${{ matrix.buildx-version }}
driver-opts: network=host driver-opts: network=host
@ -390,10 +478,93 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
digest:
runs-on: ubuntu-latest
env:
DOCKER_IMAGE: localhost:5000/name/app
strategy:
fail-fast: false
matrix:
driver:
- docker
- docker-container
load:
- true
- false
push:
- true
- false
exclude:
- driver: docker
load: true
push: true
- driver: docker-container
load: true
push: true
- driver: docker
load: false
push: false
- driver: docker-container
load: false
push: false
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- -
name: Dump context name: Checkout
if: always() uses: actions/checkout@v3
uses: crazy-max/ghaction-dump-context@v1 -
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver: ${{ matrix.driver }}
driver-opts: |
network=host
-
name: Build
id: docker_build
uses: ./
with:
context: ./test
load: ${{ matrix.load }}
push: ${{ matrix.push }}
tags: ${{ env.DOCKER_IMAGE }}:latest
platforms: ${{ matrix.platforms }}
-
name: Docker images
run: |
docker image ls --no-trunc
-
name: Check digest
if: ${{ matrix.push }}
run: |
if [ -z "${{ steps.docker_build.outputs.digest }}" ]; then
echo "::error::Digest should not be empty"
exit 1
fi
-
name: Check manifest
if: ${{ matrix.push }}
run: |
set -x
docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}@${{ steps.docker_build.outputs.digest }} --format '{{json .}}'
-
name: Check image ID
run: |
if [ -z "${{ steps.docker_build.outputs.imageid }}" ]; then
echo "::error::Image ID should not be empty"
exit 1
fi
-
name: Inspect image
if: ${{ matrix.load }}
run: |
set -x
docker image inspect ${{ steps.docker_build.outputs.imageid }}
registry-cache: registry-cache:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -405,14 +576,14 @@ 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
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
driver-opts: | driver-opts: |
network=host network=host
@ -480,10 +651,6 @@ jobs:
echo "::error::Digests should be identical" echo "::error::Digests should be identical"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
local-cache-first: local-cache-first:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -497,20 +664,20 @@ 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
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
driver-opts: | driver-opts: |
network=host network=host
- -
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-local-${{ github.sha }} key: ${{ runner.os }}-buildx-local-${{ github.sha }}
@ -546,10 +713,6 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
local-cache-hit: local-cache-hit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -562,20 +725,20 @@ 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
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v2
with: with:
driver-opts: | driver-opts: |
network=host network=host
- -
name: Cache Docker layers name: Cache Docker layers
uses: actions/cache@v2 uses: actions/cache@v3
id: cache id: cache
with: with:
path: /tmp/.buildx-cache path: /tmp/.buildx-cache
@ -619,10 +782,6 @@ jobs:
- -
name: Cache hit name: Cache hit
run: echo ${{ steps.cache.outputs.cache-hit }} run: echo ${{ steps.cache.outputs.cache-hit }}
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
github-cache: github-cache:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -640,13 +799,13 @@ 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:
version: ${{ matrix.buildx_version }} version: ${{ matrix.buildx_version }}
driver-opts: | driver-opts: |
@ -669,7 +828,23 @@ 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: Dump context name: Checkout
if: always() uses: actions/checkout@v3
uses: crazy-max/ghaction-dump-context@v1 -
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
-
name: Build
uses: ./
with:
context: ./test
file: ./test/Dockerfile

View File

@ -3,10 +3,10 @@ name: e2e
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
- cron: '0 10 * * *' # everyday at 10am - cron: '0 10 * * *'
push: push:
branches: branches:
- master - 'master'
tags: tags:
- v* - v*
@ -52,26 +52,31 @@ jobs:
slug: gcr.io/sandbox-298914/test-docker-action slug: gcr.io/sandbox-298914/test-docker-action
username_secret: GCR_USERNAME username_secret: GCR_USERNAME
password_secret: GCR_JSON_KEY password_secret: GCR_JSON_KEY
-
registry: officialgithubactions.azurecr.io
slug: officialgithubactions.azurecr.io/test-docker-action
username_secret: AZURE_CLIENT_ID
password_secret: AZURE_CLIENT_SECRET
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:
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
- -
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] }}

View File

@ -1,9 +1,9 @@
# This workflow is provided just as an usage example and not for repo testing/verification # This workflow is provided just as an example and not for repo testing/verification
name: example name: example
on: on:
schedule: schedule:
- cron: '0 10 * * 0' # everyday sunday at 10am - cron: '0 10 * * 0'
push: push:
branches: branches:
- '**' - '**'
@ -25,11 +25,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:
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
- -

View File

@ -14,19 +14,19 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 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

@ -3,7 +3,17 @@ name: virtual-env
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
- cron: '0 10 * * *' # everyday at 10am - 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,25 +23,49 @@ jobs:
matrix: matrix:
os: os:
- ubuntu-latest - ubuntu-latest
- ubuntu-22.04
- ubuntu-20.04 - ubuntu-20.04
- ubuntu-18.04 - ubuntu-18.04
- ubuntu-16.04
steps: steps:
-
name: File system
run: df -ah
-
name: Mounts
run: mount
-
name: Node info
run: node -p process
-
name: NPM version
run: npm version
- -
name: List install packages 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
- -
name: containerd version name: containerd version
run: containerd --version run: containerd --version
-
name: Docker images
run: docker image ls
- -
name: Dump context name: Dump context
if: always() if: always()

145
README.md
View File

@ -4,15 +4,6 @@
[![Test workflow](https://img.shields.io/github/workflow/status/docker/build-push-action/test?label=test&logo=github&style=flat-square)](https://github.com/docker/build-push-action/actions?workflow=test) [![Test workflow](https://img.shields.io/github/workflow/status/docker/build-push-action/test?label=test&logo=github&style=flat-square)](https://github.com/docker/build-push-action/actions?workflow=test)
[![Codecov](https://img.shields.io/codecov/c/github/docker/build-push-action?logo=codecov&style=flat-square)](https://codecov.io/gh/docker/build-push-action) [![Codecov](https://img.shields.io/codecov/c/github/docker/build-push-action?logo=codecov&style=flat-square)](https://codecov.io/gh/docker/build-push-action)
## Upgrade from v1
`v2` of this action includes significant updates and now uses Docker [Buildx](https://github.com/docker/buildx). It's
also rewritten as a [typescript-action](https://github.com/actions/typescript-action/) to be as close as possible
of the [GitHub Runner](https://github.com/actions/virtual-environments) during its execution.
[Upgrade notes](UPGRADE.md) with many [usage examples](#advanced-usage) have been added to handle most use cases but
`v1` is still available through [`releases/v1` branch](https://github.com/docker/build-push-action/tree/releases/v1).
## 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) with full support of the
@ -36,6 +27,7 @@ ___
* [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)
* [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 DockerHub repo description](docs/advanced/dockerhub-desc.md)
* [Customizing](#customizing) * [Customizing](#customizing)
@ -46,17 +38,7 @@ ___
## Usage ## Usage
By default, this action uses the [Git context](#git-context) so you don't need to use the In the examples below we are also using 3 other actions:
[`actions/checkout`](https://github.com/actions/checkout/) action to checkout the repository because this will be
done directly by 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)
and will result in the following context: `https://github.com/<owner>/<repo>.git#<ref>`.
Be careful because **any file mutation in the steps that precede the build step will be ignored, including processing of the `.dockerignore` file** since
the context is based on the git reference. However, you can use the [Path context](#path-context) using the
[`context` input](#inputs) alongside the [`actions/checkout`](https://github.com/actions/checkout/) action to remove
this restriction.
In the examples below we are 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 create and boot a builder using by
default the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver). default the `docker-container` [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver).
@ -67,13 +49,20 @@ to add emulation support with QEMU to be able to build against more platforms.
### Git context ### Git context
By default, this action uses the [Git context](#git-context) so you don't need
to use the [`actions/checkout`](https://github.com/actions/checkout/) action to
check out the repository because this will be done directly by [BuildKit](https://github.com/moby/buildkit).
The git reference will be based on the [event that triggered your workflow](https://docs.github.com/en/actions/reference/events-that-trigger-workflows)
and will result in the following context: `https://github.com/<owner>/<repo>.git#<ref>`.
```yaml ```yaml
name: ci name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -81,34 +70,55 @@ 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 DockerHub
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
id: docker_build uses: docker/build-push-action@v3
uses: docker/build-push-action@v2
with: with:
push: true push: true
tags: user/app:latest tags: user/app:latest
``` ```
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) Be careful because **any file mutation in the steps that precede the build step
so it does not need to be passed. If you want to authenticate against another private repository, you have to use will be ignored, including processing of the `.dockerignore` file** since
a [secret](docs/advanced/secrets.md) named `GIT_AUTH_TOKEN` to be able to authenticate against it with buildx: the context is based on the Git reference. However, you can use the
[Path context](#path-context) using the [`context` input](#inputs) alongside
the [`actions/checkout`](https://github.com/actions/checkout/) action to remove
this restriction.
Default Git context can also be provided using the [Handlebars template](https://handlebarsjs.com/guide/)
expression `{{defaultContext}}`. Here we can use it to provide a subdirectory
to the default Git context:
```yaml ```yaml
- -
name: Build and push name: Build and push
id: docker_build uses: docker/build-push-action@v3
uses: docker/build-push-action@v2 with:
context: "{{defaultContext}}:mysubdir"
push: true
tags: user/app:latest
```
> :warning: Subdirectory for Git context is not yet available for the buildx [`docker` driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver).
Building from the current repository automatically uses the [GitHub Token](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token)
so it does not need to be passed. If you want to authenticate against another
private repository, you have to use a [secret](docs/advanced/secrets.md) named
`GIT_AUTH_TOKEN` to be able to authenticate against it with buildx:
```yaml
-
name: Build and push
uses: docker/build-push-action@v3
with: with:
push: true push: true
tags: user/app:latest tags: user/app:latest
@ -124,7 +134,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -132,22 +142,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 DockerHub
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
@ -165,6 +175,7 @@ jobs:
* [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)
* [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 DockerHub repo description](docs/advanced/dockerhub-desc.md)
@ -186,37 +197,45 @@ 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 |
|---------------------|----------|------------------------------------| |--------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `allow` | List/CSV | List of [extra privileged entitlement](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#allow) (eg. `network.host,security.insecure`) | | `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`) |
| `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) | | `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`) |
| `build-args` | List | List of build-time variables | | `builder` | String | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) |
| `cache-from` | List | List of [external cache sources](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-from) (eg. `type=local,src=path/to/dir`) | | `build-args` | List | List of [build-time variables](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#build-arg) |
| `cache-to` | List | List of [cache export destinations](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#cache-to) (eg. `type=local,dest=path/to/dir`) | | `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`) |
| `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)) | | `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`) |
| `file` | String | Path to the Dockerfile. (default `{context}/Dockerfile`) | | `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`) |
| `labels` | List | List of metadata for an image | | `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 |
| `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`) | | `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)) |
| `network` | String | Set the networking mode for the `RUN` instructions during build | | `file` | String | Path to the Dockerfile. (default `{context}/Dockerfile`) |
| `no-cache` | Bool | Do not use cache when building the image (default `false`) | | `labels` | List | List of metadata for an image |
| `outputs` | List | List of [output destinations](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#output) (format: `type=local,dest=path`) | | `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`) |
| `platforms` | List/CSV | List of [target platforms](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#platform) for build | | `network` | String | Set the networking mode for the `RUN` instructions during build |
| `pull` | Bool | Always attempt to pull a newer version of the image (default `false`) | | `no-cache` | Bool | Do not use cache when building the image (default `false`) |
| `push` | Bool | [Push](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#push) is a shorthand for `--output=type=registry` (default `false`) | | `no-cache-filters` | List/CSV | Do not cache specified stages |
| `secrets` | List | List of secrets to expose to the build (eg. `key=string`, `GIT_AUTH_TOKEN=mytoken`) | | `outputs` | List | List of [output destinations](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#output) (format: `type=local,dest=path`) |
| `secret-files` | List | List of secret files to expose to the build (eg. `key=filename`, `MY_SECRET=./secret.txt`) | | `platforms` | List/CSV | List of [target platforms](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#platform) for build |
| `ssh` | List | List of SSH agent socket or keys to expose to the build | | `pull` | Bool | Always attempt to pull all referenced images (default `false`) |
| `tags` | List/CSV | List of tags | | `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`) |
| `target` | String | Sets the target stage to build | | `secrets` | List | List of [secrets](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#secret) to expose to the build (e.g., `key=string`, `GIT_AUTH_TOKEN=mytoken`) |
| `secret-files` | List | List of [secret files](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#secret) to expose to the build (e.g., `key=filename`, `MY_SECRET=./secret.txt`) |
| `shm-size` | String | Size of [`/dev/shm`](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#-size-of-devshm---shm-size) (e.g., `2g`) |
| `ssh` | List | List of [SSH agent socket or keys](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#ssh) to expose to the build |
| `tags` | List/CSV | List of tags |
| `target` | String | Sets the target stage to build |
| `ulimit` | List | [Ulimit](https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md#-set-ulimits---ulimit) options (e.g., `nofile=1024:1024`) |
| `github-token` | String | GitHub Token used to authenticate against a repository for [Git context](#git-context) (default `${{ github.token }}`) |
### outputs ### outputs
Following outputs are available Following outputs are available
| Name | Type | Description | | Name | Type | Description |
|-------------------|---------|---------------------------------------| |------------|---------|-----------------------------------------|
| `digest` | String | Image content-addressable identifier also called a digest | | `imageid` | String | Image ID |
| `metadata` | JSON | Build result metadata | | `digest` | String | Image digest |
| `metadata` | JSON | Build result metadata |
## Troubleshooting ## Troubleshooting

View File

@ -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
@ -100,18 +100,36 @@ or a cache reference:
``` ```
To fix this issue you can use our [metadata action](https://github.com/docker/metadata-action) To fix this issue you can use our [metadata action](https://github.com/docker/metadata-action)
to generate sanitized tags, or a dedicated step to sanitize the slug: to generate sanitized tags:
```yaml
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: ghcr.io/${{ github.repository }}
tags: latest
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
```
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 code
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 code
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 code
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,13 +1,13 @@
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';
const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
const digest = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9'; const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
const metadata = `{ const metadata = `{
"containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd", "containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd",
"containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c" "containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
@ -28,115 +28,72 @@ jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
describe('getImageID', () => { describe('getImageID', () => {
it('matches', async () => { it('matches', async () => {
const imageIDFile = await buildx.getImageIDFile(); const imageIDFile = await buildx.getImageIDFile();
console.log(`imageIDFile: ${imageIDFile}`); await fs.writeFileSync(imageIDFile, imageID);
await fs.writeFileSync(imageIDFile, digest); const expected = await buildx.getImageID();
const imageID = await buildx.getImageID(); expect(expected).toEqual(imageID);
console.log(`imageID: ${imageID}`);
expect(imageID).toEqual(digest);
}); });
}); });
describe('getMetadata', () => { describe('getMetadata', () => {
it('matches', async () => { it('matches', async () => {
const metadataFile = await buildx.getMetadataFile(); const metadataFile = await buildx.getMetadataFile();
console.log(`metadataFile: ${metadataFile}`);
await fs.writeFileSync(metadataFile, metadata); await fs.writeFileSync(metadataFile, metadata);
const expected = await buildx.getMetadata(); const expected = await buildx.getMetadata();
console.log(`metadata: ${expected}`);
expect(expected).toEqual(metadata); expect(expected).toEqual(metadata);
}); });
}); });
describe('getDigest', () => {
it('matches', async () => {
const metadataFile = await buildx.getMetadataFile();
await fs.writeFileSync(metadataFile, metadata);
const expected = await buildx.getDigest(metadata);
expect(expected).toEqual('sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c');
});
});
describe('isLocalOrTarExporter', () => { 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();
console.log(`version: ${version}`);
expect(semver.valid(version)).not.toBeNull();
},
100000
);
}); });
describe('parseVersion', () => { describe('parseVersion', () => {
@ -179,12 +136,11 @@ describe('getSecret', () => {
secret = await buildx.getSecretString(kvp); secret = await buildx.getSecretString(kvp);
} }
expect(true).toBe(!invalid); expect(true).toBe(!invalid);
console.log(`secret: ${secret}`);
expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`); expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`);
const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8'); const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8');
console.log(`secretValue: ${secretValue}`);
expect(secretValue).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,3 +1,4 @@
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 os from 'os';
import * as path from 'path'; import * as path from 'path';
@ -140,32 +141,32 @@ describe('getArgs', () => {
// prettier-ignore // prettier-ignore
test.each([ test.each([
[ [
0,
'0.4.1', '0.4.1',
new Map<string, string>([ new Map<string, string>([
['context', '.'], ['context', '.'],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'.' '.'
] ]
], ],
[ [
1,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['build-args', 'MY_ARG=val1,val2,val3\nARG=val'], ['build-args', 'MY_ARG=val1,val2,val3\nARG=val'],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['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',
@ -174,24 +175,25 @@ describe('getArgs', () => {
] ]
], ],
[ [
2,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['tags', 'name/app:7.4, name/app:latest'], ['tags', 'name/app:7.4, name/app:latest'],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--tag', 'name/app:7.4', '--tag', 'name/app:7.4',
'--tag', 'name/app:latest', '--tag', 'name/app:latest',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'https://github.com/docker/build-push-action.git#refs/heads/test-jest' 'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
] ]
], ],
[ [
3,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['context', '.'], ['context', '.'],
@ -200,10 +202,9 @@ describe('getArgs', () => {
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['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',
@ -212,6 +213,7 @@ describe('getArgs', () => {
] ]
], ],
[ [
4,
'0.4.1', '0.4.1',
new Map<string, string>([ new Map<string, string>([
['context', '.'], ['context', '.'],
@ -219,32 +221,32 @@ describe('getArgs', () => {
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--platform', 'linux/amd64,linux/arm64', '--platform', 'linux/amd64,linux/arm64',
'.' '.'
] ]
], ],
[ [
5,
'0.4.1', '0.4.1',
new Map<string, string>([ new Map<string, string>([
['context', '.'], ['context', '.'],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'.' '.'
] ]
], ],
[ [
6,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['context', '.'], ['context', '.'],
@ -252,10 +254,9 @@ describe('getArgs', () => {
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['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',
@ -263,6 +264,7 @@ describe('getArgs', () => {
] ]
], ],
[ [
7,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['github-token', 'abcdefghijklmno0123456789'], ['github-token', 'abcdefghijklmno0123456789'],
@ -270,10 +272,9 @@ describe('getArgs', () => {
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['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',
@ -281,6 +282,7 @@ describe('getArgs', () => {
] ]
], ],
[ [
8,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'], ['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
@ -292,21 +294,21 @@ describe('getArgs', () => {
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'true'], ['push', 'true'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--platform', 'linux/amd64,linux/arm64',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--file', './test/Dockerfile', '--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--platform', 'linux/amd64,linux/arm64',
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--builder', 'builder-git-context-2', '--builder', 'builder-git-context-2',
'--push', '--push',
'https://github.com/docker/build-push-action.git#refs/heads/master' 'https://github.com/docker/build-push-action.git#refs/heads/master'
] ]
], ],
[ [
9,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'], ['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
@ -326,24 +328,24 @@ ccc"`],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'true'], ['push', 'true'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--platform', 'linux/amd64,linux/arm64', '--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--platform', 'linux/amd64,linux/arm64',
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--file', './test/Dockerfile',
'--builder', 'builder-git-context-2', '--builder', 'builder-git-context-2',
'--push', '--push',
'https://github.com/docker/build-push-action.git#refs/heads/master' 'https://github.com/docker/build-push-action.git#refs/heads/master'
] ]
], ],
[ [
10,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'], ['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
@ -363,24 +365,24 @@ ccc`],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'true'], ['push', 'true'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--platform', 'linux/amd64,linux/arm64', '--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--platform', 'linux/amd64,linux/arm64',
'--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--file', './test/Dockerfile',
'--builder', 'builder-git-context-2', '--builder', 'builder-git-context-2',
'--push', '--push',
'https://github.com/docker/build-push-action.git#refs/heads/master' 'https://github.com/docker/build-push-action.git#refs/heads/master'
] ]
], ],
[ [
11,
'0.5.1', '0.5.1',
new Map<string, string>([ new Map<string, string>([
['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'], ['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'],
@ -392,14 +394,13 @@ ccc`],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'true'], ['push', 'true'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile', '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', '--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
'--file', './test/Dockerfile',
'--builder', 'builder-git-context-2', '--builder', 'builder-git-context-2',
'--network', 'host', '--network', 'host',
'--push', '--push',
@ -407,6 +408,7 @@ ccc`],
] ]
], ],
[ [
12,
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['context', '.'], ['context', '.'],
@ -415,10 +417,9 @@ ccc`],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'false'], ['push', 'false'],
['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)"',
@ -427,39 +428,87 @@ ccc`],
] ]
], ],
[ [
13,
'0.6.0', '0.6.0',
new Map<string, string>([ new Map<string, string>([
['context', '.'], ['context', '.'],
['tag', 'localhost:5000/name/app:latest'], ['tag', 'localhost:5000/name/app:latest'],
['file', './test/Dockerfile'], ['file', './test/Dockerfile'],
['add-hosts', 'docker:10.180.0.1,foo:10.0.0.1'],
['network', 'host'], ['network', 'host'],
['load', 'false'], ['load', 'false'],
['no-cache', 'false'], ['no-cache', 'false'],
['push', 'true'], ['push', 'true'],
['pull', 'false'] ['pull', 'false'],
]), ]),
[ [
'buildx',
'build', 'build',
'--add-host', 'docker:10.180.0.1',
'--add-host', 'foo:10.0.0.1',
'--file', './test/Dockerfile',
'--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',
'--file', './test/Dockerfile',
'--network', 'host', '--network', 'host',
'--push', '--push',
'.' '.'
] ]
], ],
[
14,
'0.7.0',
new Map<string, string>([
['context', '.'],
['file', './test/Dockerfile'],
['add-hosts', 'docker:10.180.0.1\nfoo:10.0.0.1'],
['cgroup-parent', 'foo'],
['shm-size', '2g'],
['ulimit', `nofile=1024:1024
nproc=3`],
['load', 'false'],
['no-cache', 'false'],
['push', 'false'],
['pull', 'false'],
]),
[
'build',
'--add-host', 'docker:10.180.0.1',
'--add-host', 'foo:10.0.0.1',
'--cgroup-parent', 'foo',
'--file', './test/Dockerfile',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--shm-size', '2g',
'--ulimit', 'nofile=1024:1024',
'--ulimit', 'nproc=3',
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
'.'
]
],
[
15,
'0.7.0',
new Map<string, string>([
['context', '{{defaultContext}}:docker'],
['load', 'false'],
['no-cache', 'false'],
['push', 'false'],
['pull', 'false'],
]),
[
'build',
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
'https://github.com/docker/build-push-action.git#refs/heads/test-jest:docker'
]
],
])( ])(
'given %p with %p as inputs, returns %p', '[%d] given %p with %p as inputs, returns %p',
async (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();
const inp = await context.getInputs(defContext); const inp = await context.getInputs(defContext);
console.log(inp);
const res = await context.getArgs(inp, defContext, buildxVersion); const res = await context.getArgs(inp, defContext, buildxVersion);
console.log(res);
expect(res).toEqual(expected); expect(res).toEqual(expected);
} }
); );
@ -469,63 +518,54 @@ describe('getInputList', () => {
it('single line correctly', async () => { it('single line correctly', async () => {
await setInput('foo', 'bar'); await setInput('foo', 'bar');
const res = await context.getInputList('foo'); const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar']); expect(res).toEqual(['bar']);
}); });
it('multiline correctly', async () => { it('multiline correctly', async () => {
setInput('foo', 'bar\nbaz'); setInput('foo', 'bar\nbaz');
const res = await context.getInputList('foo'); const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz']); expect(res).toEqual(['bar', 'baz']);
}); });
it('empty lines correctly', async () => { it('empty lines correctly', async () => {
setInput('foo', 'bar\n\nbaz'); setInput('foo', 'bar\n\nbaz');
const res = await context.getInputList('foo'); const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz']); expect(res).toEqual(['bar', 'baz']);
}); });
it('comma correctly', async () => { it('comma correctly', async () => {
setInput('foo', 'bar,baz'); setInput('foo', 'bar,baz');
const res = await context.getInputList('foo'); const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz']); expect(res).toEqual(['bar', 'baz']);
}); });
it('empty result correctly', async () => { it('empty result correctly', async () => {
setInput('foo', 'bar,baz,'); setInput('foo', 'bar,baz,');
const res = await context.getInputList('foo'); const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz']); expect(res).toEqual(['bar', 'baz']);
}); });
it('different new lines correctly', async () => { it('different new lines correctly', async () => {
setInput('foo', 'bar\r\nbaz'); setInput('foo', 'bar\r\nbaz');
const res = await context.getInputList('foo'); const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz']); expect(res).toEqual(['bar', 'baz']);
}); });
it('different new lines and comma correctly', async () => { it('different new lines and comma correctly', async () => {
setInput('foo', 'bar\r\nbaz,bat'); setInput('foo', 'bar\r\nbaz,bat');
const res = await context.getInputList('foo'); const res = await context.getInputList('foo');
console.log(res);
expect(res).toEqual(['bar', 'baz', 'bat']); expect(res).toEqual(['bar', 'baz', 'bat']);
}); });
it('multiline and ignoring comma correctly', async () => { it('multiline and ignoring comma correctly', async () => {
setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir'); setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir');
const res = await context.getInputList('cache-from', true); const res = await context.getInputList('cache-from', true);
console.log(res);
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']); expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
}); });
it('different new lines and ignoring comma correctly', async () => { it('different new lines and ignoring comma correctly', async () => {
setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir'); setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir');
const res = await context.getInputList('cache-from', true); const res = await context.getInputList('cache-from', true);
console.log(res);
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']); expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
}); });
@ -539,7 +579,6 @@ ccccccccc"
FOO=bar` FOO=bar`
); );
const res = await context.getInputList('secrets', true); const res = await context.getInputList('secrets', true);
console.log(res);
expect(res).toEqual([ expect(res).toEqual([
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
`MYSECRET=aaaaaaaa `MYSECRET=aaaaaaaa
@ -563,7 +602,6 @@ bbbb
ccc"` ccc"`
); );
const res = await context.getInputList('secrets', true); const res = await context.getInputList('secrets', true);
console.log(res);
expect(res).toEqual([ expect(res).toEqual([
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
`MYSECRET=aaaaaaaa `MYSECRET=aaaaaaaa
@ -587,7 +625,6 @@ ccccccccc
FOO=bar` FOO=bar`
); );
const res = await context.getInputList('secrets', true); const res = await context.getInputList('secrets', true);
console.log(res);
expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']); expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']);
}); });
@ -598,7 +635,6 @@ FOO=bar`
FOO=bar` FOO=bar`
); );
const res = await context.getInputList('secrets', true); const res = await context.getInputList('secrets', true);
console.log(res);
expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']); expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']);
}); });
@ -612,11 +648,10 @@ ccccccccc"
FOO=bar` FOO=bar`
); );
const res = await context.getInputList('secrets', true); const res = await context.getInputList('secrets', true);
console.log(res);
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'
]); ]);
@ -638,19 +673,22 @@ describe('asyncForEach', () => {
describe('setOutput', () => { describe('setOutput', () => {
beforeEach(() => { beforeEach(() => {
process.stdout.write = jest.fn(); process.stdout.write = jest.fn() as typeof process.stdout.write;
}); });
// eslint-disable-next-line jest/expect-expect
it('setOutput produces the correct command', () => { it('setOutput produces the correct command', () => {
context.setOutput('some output', 'some value'); context.setOutput('some output', 'some value');
assertWriteCalls([`::set-output name=some output::some value${os.EOL}`]); assertWriteCalls([`::set-output name=some output::some value${os.EOL}`]);
}); });
// eslint-disable-next-line jest/expect-expect
it('setOutput handles bools', () => { it('setOutput handles bools', () => {
context.setOutput('some output', false); context.setOutput('some output', false);
assertWriteCalls([`::set-output name=some output::false${os.EOL}`]); assertWriteCalls([`::set-output name=some output::false${os.EOL}`]);
}); });
// eslint-disable-next-line jest/expect-expect
it('setOutput handles numbers', () => { it('setOutput handles numbers', () => {
context.setOutput('some output', 1.01); context.setOutput('some output', 1.01);
assertWriteCalls([`::set-output name=some output::1.01${os.EOL}`]); assertWriteCalls([`::set-output name=some output::1.01${os.EOL}`]);

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

@ -7,20 +7,29 @@ branding:
color: 'blue' color: 'blue'
inputs: inputs:
add-hosts:
description: "List of a customs host-to-IP mapping (e.g., docker:10.180.0.1)"
required: false
allow: allow:
description: "List of extra privileged entitlement (eg. network.host,security.insecure)" description: "List of extra privileged entitlement (e.g., network.host,security.insecure)"
required: false required: false
build-args: build-args:
description: "List of build-time variables" description: "List of build-time variables"
required: false required: false
build-contexts:
description: "List of additional build contexts (e.g., name=path)"
required: false
builder: builder:
description: "Builder instance" description: "Builder instance"
required: false required: false
cache-from: cache-from:
description: "List of external cache sources for buildx (eg. user/app:cache, type=local,src=path/to/dir)" description: "List of external cache sources for buildx (e.g., user/app:cache, type=local,src=path/to/dir)"
required: false required: false
cache-to: cache-to:
description: "List of cache export destinations for buildx (eg. user/app:cache, type=local,dest=path/to/dir)" description: "List of cache export destinations for buildx (e.g., user/app:cache, type=local,dest=path/to/dir)"
required: false
cgroup-parent:
description: "Optional parent cgroup for the container used in the build"
required: false required: false
context: context:
description: "Build's context is the set of files located in the specified PATH or URL" description: "Build's context is the set of files located in the specified PATH or URL"
@ -42,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
@ -49,7 +61,7 @@ inputs:
description: "List of target platforms for build" description: "List of target platforms for build"
required: false required: false
pull: pull:
description: "Always attempt to pull a newer version of the image" description: "Always attempt to pull all referenced images"
required: false required: false
default: 'false' default: 'false'
push: push:
@ -57,10 +69,13 @@ inputs:
required: false required: false
default: 'false' default: 'false'
secrets: secrets:
description: "List of secrets to expose to the build (eg. key=string, GIT_AUTH_TOKEN=mytoken)" description: "List of secrets to expose to the build (e.g., key=string, GIT_AUTH_TOKEN=mytoken)"
required: false required: false
secret-files: secret-files:
description: "List of secret files to expose to the build (eg. key=filename, MY_SECRET=./secret.txt)" description: "List of secret files to expose to the build (e.g., key=filename, MY_SECRET=./secret.txt)"
required: false
shm-size:
description: "Size of /dev/shm (e.g., 2g)"
required: false required: false
ssh: ssh:
description: "List of SSH agent socket or keys to expose to the build" description: "List of SSH agent socket or keys to expose to the build"
@ -71,18 +86,23 @@ inputs:
target: target:
description: "Sets the target stage to build" description: "Sets the target stage to build"
required: false required: false
ulimit:
description: "Ulimit options (e.g., nofile=1024:1024)"
required: false
github-token: github-token:
description: "GitHub Token used to authenticate against a repository for Git context" description: "GitHub Token used to authenticate against a repository for Git context"
default: ${{ github.token }} default: ${{ github.token }}
required: false required: false
outputs: outputs:
imageid:
description: 'Image ID'
digest: digest:
description: 'Image content-addressable identifier also called a digest' description: 'Image digest'
metadata: metadata:
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'

78
dev.Dockerfile Normal file
View File

@ -0,0 +1,78 @@
# syntax=docker/dockerfile:1.4
ARG NODE_VERSION=16
ARG DOCKER_VERSION=20.10.13
ARG BUILDX_VERSION=0.8.0
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git
WORKDIR /src
FROM base AS deps
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn install && mkdir /vendor && cp yarn.lock /vendor
FROM scratch AS vendor-update
COPY --from=deps /vendor /
FROM deps AS vendor-validate
RUN --mount=type=bind,target=.,rw <<EOT
set -e
git add -A
cp -rf /vendor/* .
if [ -n "$(git status --porcelain -- yarn.lock)" ]; then
echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'
git status --porcelain -- yarn.lock
exit 1
fi
EOT
FROM deps AS build
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run build && mkdir /out && cp -Rf dist /out/
FROM scratch AS build-update
COPY --from=build /out /
FROM build AS build-validate
RUN --mount=type=bind,target=.,rw <<EOT
set -e
git add -A
cp -rf /out/* .
if [ -n "$(git status --porcelain -- dist)" ]; then
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
git status --porcelain -- dist
exit 1
fi
EOT
FROM deps AS format
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run format \
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out
FROM scratch AS format-update
COPY --from=format /out /
FROM deps AS lint
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run lint
FROM docker:${DOCKER_VERSION} as docker
FROM docker/buildx-bin:${BUILDX_VERSION} as buildx
FROM deps AS test
ENV RUNNER_TEMP=/tmp/github_runner
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
--mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
--mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \
yarn run test --coverageDirectory=/tmp/coverage
FROM scratch AS test-coverage
COPY --from=test /tmp/coverage /

17094
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

1045
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,51 +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"]
} }
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"]
} }
target "vendor-update" { target "vendor-update" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/vendor.Dockerfile" target = "vendor-update"
target = "update"
output = ["."] output = ["."]
} }
target "vendor-validate" { target "vendor-validate" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/vendor.Dockerfile" target = "vendor-validate"
target = "validate" output = ["type=cacheonly"]
} }
target "test" { target "test" {
inherits = ["node-version"] dockerfile = "dev.Dockerfile"
dockerfile = "./hack/test.Dockerfile"
target = "test-coverage" target = "test-coverage"
output = ["./coverage"] output = ["./coverage"]
} }

View File

@ -10,7 +10,7 @@
## Inline cache ## Inline cache
In most case 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/moby/buildkit#inline-push-image-and-cache-together).
However, note that the `inline` cache exporter only supports `min` cache mode. To enable `max` cache mode, push the 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).
@ -20,7 +20,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -28,19 +28,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 DockerHub
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
@ -60,7 +60,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -68,19 +68,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 DockerHub
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
@ -110,7 +110,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -118,19 +118,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 DockerHub
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
@ -154,7 +154,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -162,13 +162,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: 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 }}
@ -176,13 +176,13 @@ jobs:
${{ runner.os }}-buildx- ${{ runner.os }}-buildx-
- -
name: Login to DockerHub name: Login to DockerHub
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

@ -12,7 +12,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -20,36 +20,36 @@ 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 - # quay and ghcr logins for pushing image after testing
name: Login to Quay Registry name: Login to Quay Registry
uses: docker/login-action@v1 uses: docker/login-action@v2
with: with:
registry: quay.io registry: quay.io
username: ${{ secrets.QUAY_USERNAME }} username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_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 name: Login to DockerHub
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
@ -62,7 +62,7 @@ jobs:
run: make tests run: make tests
- # copy multiplatform image from dockerhub to quay and ghcr - # copy multiplatform image from dockerhub to quay and ghcr
name: Push Image to multiple registries name: Push Image to multiple registries
uses: akhilerm/tag-push-action@v1.0.0 uses: akhilerm/tag-push-action@v2.0.0
with: with:
src: docker.io/user/app:1.0.0 src: docker.io/user/app:1.0.0
dst: | dst: |

View File

@ -10,7 +10,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -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 DockerHub
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

@ -9,7 +9,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -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

@ -6,7 +6,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -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

@ -8,7 +8,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -21,18 +21,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

@ -12,7 +12,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -20,22 +20,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 DockerHub
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

@ -14,7 +14,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -22,29 +22,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 DockerHub
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

@ -22,7 +22,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -30,16 +30,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

View File

@ -11,7 +11,7 @@ name: ci
on: on:
push: push:
branches: branches:
- 'master' - 'main'
jobs: jobs:
build: build:
@ -19,20 +19,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 +43,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,7 +1,6 @@
# Handle tags and labels # Handle tags and labels
If you come from [`v1`](https://github.com/docker/build-push-action/tree/releases/v1#readme) and want an If you want an "automatic" tag management and [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md)
"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 the [Docker metadata action](https://github.com/docker/metadata-action)
to handle tags and labels based on GitHub actions events and Git metadata. to handle tags and labels based on GitHub actions events and Git metadata.
@ -10,7 +9,7 @@ name: ci
on: on:
schedule: schedule:
- cron: '0 10 * * *' # everyday at 10am - cron: '0 10 * * *'
push: push:
branches: branches:
- '**' - '**'
@ -18,7 +17,7 @@ on:
- 'v*.*.*' - 'v*.*.*'
pull_request: pull_request:
branches: branches:
- 'master' - 'main'
jobs: jobs:
docker: docker:
@ -26,11 +25,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: |
@ -47,28 +46,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 DockerHub
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

@ -0,0 +1,64 @@
# Test your image before pushing it
In some cases, you might want to validate that the image works as expected
before pushing it.
The workflow below will be composed of several steps to achieve this:
* Build and export the image to Docker
* Test your image
* Multi-platform build and push the image
```yaml
name: ci
on:
push:
branches:
- 'main'
env:
TEST_TAG: user/myapp:test
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and export to Docker
uses: docker/build-push-action@v3
with:
context: .
load: true
tags: ${{ env.TEST_TAG }}
-
name: Test
run: |
docker run --rm ${{ env.TEST_TAG }}
-
name: Build and push
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: user/app:latest
```
> :bulb: Build time will not be increased with this workflow because internal
> cache for `linux/amd64` will be used from previous step on `Build and push`
> step so only `linux/arm64` will be actually built.

View File

@ -1,42 +0,0 @@
# syntax=docker/dockerfile:1.2
ARG NODE_VERSION
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git
WORKDIR /src
FROM base AS deps
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn install
FROM deps AS build
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run build && mkdir /out && cp -Rf dist /out/
FROM scratch AS build-update
COPY --from=build /out /
FROM build AS build-validate
RUN --mount=type=bind,target=.,rw \
git add -A && cp -rf /out/* .; \
if [ -n "$(git status --porcelain -- dist)" ]; then \
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'; \
git status --porcelain -- dist; \
exit 1; \
fi
FROM deps AS format
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run format \
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out
FROM scratch AS format-update
COPY --from=format /out /
FROM deps AS format-validate
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run format-check \

View File

@ -1,28 +0,0 @@
# syntax=docker/dockerfile:1.2
ARG NODE_VERSION
ARG DOCKER_VERSION=20.10.7
ARG BUILDX_VERSION=0.6.0
FROM docker:${DOCKER_VERSION} as docker
FROM docker/buildx-bin:${BUILDX_VERSION} as buildx
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache git
WORKDIR /src
FROM base AS deps
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn install
FROM deps AS test
ENV RUNNER_TEMP=/tmp/github_runner
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
--mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
--mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \
yarn run test --coverageDirectory=/tmp/coverage
FROM scratch AS test-coverage
COPY --from=test /tmp/coverage /

View File

@ -1,23 +0,0 @@
# syntax=docker/dockerfile:1.2
ARG NODE_VERSION
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache git
WORKDIR /src
FROM base AS vendored
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn install && mkdir /out && cp yarn.lock /out
FROM scratch AS update
COPY --from=vendored /out /
FROM vendored AS validate
RUN --mount=type=bind,target=.,rw \
git add -A && cp -rf /out/* .; \
if [ -n "$(git status --porcelain -- yarn.lock)" ]; then \
echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'; \
git status --porcelain -- yarn.lock; \
exit 1; \
fi

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,26 +28,31 @@
], ],
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@actions/core": "^1.5.0", "@actions/core": "^1.9.0",
"@actions/exec": "^1.1.0", "@actions/exec": "^1.1.1",
"@actions/github": "^5.0.0", "@actions/github": "^5.0.3",
"csv-parse": "^4.16.0", "csv-parse": "^5.3.0",
"semver": "^7.3.5", "handlebars": "^4.7.7",
"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';
@ -15,7 +15,7 @@ export async function getImageID(): Promise<string | undefined> {
if (!fs.existsSync(iidFile)) { if (!fs.existsSync(iidFile)) {
return undefined; return undefined;
} }
return fs.readFileSync(iidFile, {encoding: 'utf-8'}); return fs.readFileSync(iidFile, {encoding: 'utf-8'}).trim();
} }
export async function getMetadataFile(): Promise<string> { export async function getMetadataFile(): Promise<string> {
@ -27,7 +27,22 @@ export async function getMetadata(): Promise<string | undefined> {
if (!fs.existsSync(metadataFile)) { if (!fs.existsSync(metadataFile)) {
return undefined; return undefined;
} }
return fs.readFileSync(metadataFile, {encoding: 'utf-8'}); const content = fs.readFileSync(metadataFile, {encoding: 'utf-8'}).trim();
if (content === 'null') {
return undefined;
}
return content;
}
export async function getDigest(metadata: string | undefined): Promise<string | undefined> {
if (metadata === undefined) {
return undefined;
}
const metadataJSON = JSON.parse(metadata);
if (metadataJSON['containerimage.digest']) {
return metadataJSON['containerimage.digest'];
}
return undefined;
} }
export async function getSecretString(kvp: string): Promise<string> { export async function getSecretString(kvp: string): Promise<string> {
@ -61,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;
} }
@ -82,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;
} }
@ -91,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
}) })
@ -102,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
}) })
@ -130,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,4 +1,4 @@
import csvparse from 'csv-parse/lib/sync'; import {parse} from 'csv-parse/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';
@ -9,30 +9,37 @@ import {issueCommand} from '@actions/core/lib/command';
import * as github from '@actions/github'; import * as github from '@actions/github';
import * as buildx from './buildx'; import * as buildx from './buildx';
import * as handlebars from 'handlebars';
let _defaultContext, _tmpDir: string; let _defaultContext, _tmpDir: string;
export interface Inputs { export interface Inputs {
addHosts: string[];
allow: string[]; allow: string[];
buildArgs: string[]; buildArgs: string[];
buildContexts: string[];
builder: string; builder: string;
cacheFrom: string[]; cacheFrom: string[];
cacheTo: string[]; cacheTo: string[];
cgroupParent: string;
context: string; context: string;
file: string; file: string;
labels: string[]; labels: string[];
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;
push: boolean; push: boolean;
secrets: string[]; secrets: string[];
secretFiles: string[]; secretFiles: string[];
shmSize: string;
ssh: string[]; ssh: string[];
tags: string[]; tags: string[];
target: string; target: string;
ulimit: string[];
githubToken: string; githubToken: string;
} }
@ -63,66 +70,60 @@ export function tmpNameSync(options?: tmp.TmpNameOptions): string {
export async function getInputs(defaultContext: string): Promise<Inputs> { export async function getInputs(defaultContext: string): Promise<Inputs> {
return { return {
addHosts: await getInputList('add-hosts'),
allow: await getInputList('allow'), allow: await getInputList('allow'),
buildArgs: await getInputList('build-args', true), buildArgs: await getInputList('build-args', true),
buildContexts: await getInputList('build-contexts', true),
builder: core.getInput('builder'), builder: core.getInput('builder'),
cacheFrom: await getInputList('cache-from', true), cacheFrom: await getInputList('cache-from', true),
cacheTo: await getInputList('cache-to', true), cacheTo: await getInputList('cache-to', true),
cgroupParent: core.getInput('cgroup-parent'),
context: core.getInput('context') || defaultContext, context: core.getInput('context') || defaultContext,
file: core.getInput('file'), file: core.getInput('file'),
labels: await getInputList('labels', true), labels: await getInputList('labels', true),
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'),
push: core.getBooleanInput('push'), push: core.getBooleanInput('push'),
secrets: await getInputList('secrets', true), secrets: await getInputList('secrets', true),
secretFiles: await getInputList('secret-files', true), secretFiles: await getInputList('secret-files', true),
shmSize: core.getInput('shm-size'),
ssh: await getInputList('ssh'), ssh: await getInputList('ssh'),
tags: await getInputList('tags'), tags: await getInputList('tags'),
target: core.getInput('target'), target: core.getInput('target'),
ulimit: await getInputList('ulimit', true),
githubToken: core.getInput('github-token') githubToken: core.getInput('github-token')
}; };
} }
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']; // prettier-ignore
args.push.apply(args, await getBuildArgs(inputs, defaultContext, buildxVersion)); return [
args.push.apply(args, await getCommonArgs(inputs)); ...await getBuildArgs(inputs, defaultContext, buildxVersion),
args.push(inputs.context); ...await getCommonArgs(inputs, buildxVersion),
return args; handlebars.compile(inputs.context)({defaultContext})
];
} }
async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> { async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
let args: Array<string> = ['build']; const args: Array<string> = ['build'];
await asyncForEach(inputs.buildArgs, async buildArg => { await asyncForEach(inputs.addHosts, async addHost => {
args.push('--build-arg', buildArg); args.push('--add-host', addHost);
}); });
await asyncForEach(inputs.labels, async label => {
args.push('--label', label);
});
await asyncForEach(inputs.tags, async tag => {
args.push('--tag', tag);
});
if (inputs.target) {
args.push('--target', inputs.target);
}
if (inputs.allow.length > 0) { if (inputs.allow.length > 0) {
args.push('--allow', inputs.allow.join(',')); args.push('--allow', inputs.allow.join(','));
} }
if (inputs.platforms.length > 0) { await asyncForEach(inputs.buildArgs, async buildArg => {
args.push('--platform', inputs.platforms.join(',')); args.push('--build-arg', buildArg);
}
await asyncForEach(inputs.outputs, async output => {
args.push('--output', output);
}); });
if (!buildx.isLocalOrTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || buildx.satisfies(buildxVersion, '>=0.4.2'))) { if (buildx.satisfies(buildxVersion, '>=0.8.0')) {
args.push('--iidfile', await buildx.getImageIDFile()); await asyncForEach(inputs.buildContexts, async buildContext => {
} args.push('--build-context', buildContext);
if (buildx.satisfies(buildxVersion, '>=0.6.0')) { });
args.push('--metadata-file', await buildx.getMetadataFile());
} }
await asyncForEach(inputs.cacheFrom, async cacheFrom => { await asyncForEach(inputs.cacheFrom, async cacheFrom => {
args.push('--cache-from', cacheFrom); args.push('--cache-from', cacheFrom);
@ -130,6 +131,27 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
await asyncForEach(inputs.cacheTo, async cacheTo => { await asyncForEach(inputs.cacheTo, async cacheTo => {
args.push('--cache-to', cacheTo); args.push('--cache-to', cacheTo);
}); });
if (inputs.cgroupParent) {
args.push('--cgroup-parent', inputs.cgroupParent);
}
if (inputs.file) {
args.push('--file', inputs.file);
}
if (!buildx.isLocalOrTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || buildx.satisfies(buildxVersion, '>=0.4.2'))) {
args.push('--iidfile', await buildx.getImageIDFile());
}
await asyncForEach(inputs.labels, async label => {
args.push('--label', label);
});
await asyncForEach(inputs.noCacheFilters, async noCacheFilter => {
args.push('--no-cache-filter', noCacheFilter);
});
await asyncForEach(inputs.outputs, async output => {
args.push('--output', output);
});
if (inputs.platforms.length > 0) {
args.push('--platform', inputs.platforms.join(','));
}
await asyncForEach(inputs.secrets, async secret => { await asyncForEach(inputs.secrets, async secret => {
try { try {
args.push('--secret', await buildx.getSecretString(secret)); args.push('--secret', await buildx.getSecretString(secret));
@ -147,32 +169,44 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) { if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == 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) {
args.push('--shm-size', inputs.shmSize);
}
await asyncForEach(inputs.ssh, async ssh => { await asyncForEach(inputs.ssh, async ssh => {
args.push('--ssh', ssh); args.push('--ssh', ssh);
}); });
if (inputs.file) { await asyncForEach(inputs.tags, async tag => {
args.push('--file', inputs.file); args.push('--tag', tag);
});
if (inputs.target) {
args.push('--target', inputs.target);
} }
await asyncForEach(inputs.ulimit, async ulimit => {
args.push('--ulimit', ulimit);
});
return args; return args;
} }
async function getCommonArgs(inputs: Inputs): Promise<Array<string>> { async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> {
let args: Array<string> = []; const args: Array<string> = [];
if (inputs.noCache) {
args.push('--no-cache');
}
if (inputs.builder) { if (inputs.builder) {
args.push('--builder', inputs.builder); args.push('--builder', inputs.builder);
} }
if (inputs.pull) {
args.push('--pull');
}
if (inputs.load) { if (inputs.load) {
args.push('--load'); args.push('--load');
} }
if (buildx.satisfies(buildxVersion, '>=0.6.0')) {
args.push('--metadata-file', await buildx.getMetadataFile());
}
if (inputs.network) { if (inputs.network) {
args.push('--network', inputs.network); args.push('--network', inputs.network);
} }
if (inputs.noCache) {
args.push('--no-cache');
}
if (inputs.pull) {
args.push('--pull');
}
if (inputs.push) { if (inputs.push) {
args.push('--push'); args.push('--push');
} }
@ -180,27 +214,29 @@ async function getCommonArgs(inputs: Inputs): Promise<Array<string>> {
} }
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());
@ -213,6 +249,6 @@ export const asyncForEach = async (array, callback) => {
}; };
// FIXME: Temp fix https://github.com/actions/toolkit/issues/777 // FIXME: Temp fix https://github.com/actions/toolkit/issues/777
export function setOutput(name: string, value: any): void { export function setOutput(name: string, value: unknown): void {
issueCommand('set-output', {name}, value); 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,50 +1,80 @@
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'}`);
} }
}); });
await core.group(`Setting outputs`, async () => { const imageID = await buildx.getImageID();
const imageID = await buildx.getImageID(); const metadata = await buildx.getMetadata();
const metadata = await buildx.getMetadata(); const digest = await buildx.getDigest(metadata);
if (imageID) {
core.info(`digest=${imageID}`); if (imageID) {
context.setOutput('digest', imageID); await core.group(`ImageID`, async () => {
} core.info(imageID);
if (metadata) { context.setOutput('imageid', imageID);
core.info(`metadata=${metadata}`); });
}
if (digest) {
await core.group(`Digest`, async () => {
core.info(digest);
context.setOutput('digest', digest);
});
}
if (metadata) {
await core.group(`Metadata`, async () => {
core.info(metadata);
context.setOutput('metadata', metadata); context.setOutput('metadata', metadata);
} });
}); }
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }

2
test/addhost.Dockerfile Normal file
View File

@ -0,0 +1,2 @@
FROM busybox
RUN cat /etc/hosts

View File

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

2
test/cgroup.Dockerfile Normal file
View File

@ -0,0 +1,2 @@
FROM alpine
RUN cat /proc/self/cgroup

View File

@ -0,0 +1,8 @@
FROM busybox AS base
RUN echo "Hello world!" > /hello
FROM alpine AS build
COPY --from=base /hello /hello
RUN uname -a
FROM build

2
test/shmsize.Dockerfile Normal file
View File

@ -0,0 +1,2 @@
FROM busybox
RUN mount | grep /dev/shm

2
test/ulimit.Dockerfile Normal file
View File

@ -0,0 +1,2 @@
FROM busybox
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"
] ]
} }

3332
yarn.lock

File diff suppressed because it is too large Load Diff