Compare commits

...

411 Commits

Author SHA1 Message Date
CrazyMax
7ab28f9678 Merge pull request #841 from crazy-max/sigstore-multi-images
Some checks failed
publish / publish (push) Has been cancelled
sigstore: multi image names support for signing
2025-11-04 14:03:26 +01:00
CrazyMax
6bd8db31fe sigstore: multi image names support for signing
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-04 13:36:03 +01:00
CrazyMax
b449e6efd0 Merge pull request #836 from docker/dependabot/npm_and_yarn/npm_and_yarn-a40929283c
build(deps): bump the npm_and_yarn group across 1 directory with 2 updates
2025-11-03 23:03:40 +01:00
dependabot[bot]
764b218deb build(deps): bump the npm_and_yarn group across 1 directory with 2 updates
Bumps the npm_and_yarn group with 2 updates in the / directory: [@octokit/request-error](https://github.com/octokit/request-error.js) and [@octokit/request](https://github.com/octokit/request.js).


Updates `@octokit/request-error` from 5.0.0 to 5.1.1
- [Release notes](https://github.com/octokit/request-error.js/releases)
- [Commits](https://github.com/octokit/request-error.js/compare/v5.0.0...v5.1.1)

Updates `@octokit/request` from 8.1.1 to 8.4.1
- [Release notes](https://github.com/octokit/request.js/releases)
- [Commits](https://github.com/octokit/request.js/compare/v8.1.1...v8.4.1)

---
updated-dependencies:
- dependency-name: "@octokit/request-error"
  dependency-version: 5.1.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: "@octokit/request"
  dependency-version: 8.4.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 16:45:09 +00:00
CrazyMax
f592739bbc Merge pull request #838 from crazy-max/fix-toolkit-class
Some checks failed
publish / publish (push) Has been cancelled
toolkit: add missing classes
2025-11-03 12:34:58 +01:00
CrazyMax
dd7595981f Merge pull request #839 from crazy-max/lima-timeout-env
docker(install): LIMA_START_TIMEOUT env var
2025-11-03 12:34:39 +01:00
CrazyMax
8ba2bc9036 docker(install): LIMA_START_TIMEOUT env var
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-03 12:29:57 +01:00
CrazyMax
18535e8207 toolkit: add missing classes
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-03 12:27:34 +01:00
CrazyMax
8032ed96f6 Merge pull request #837 from crazy-max/lima-dns
docker(install): don't use local system resolver with lima and increase timeouts
2025-11-03 12:10:21 +01:00
CrazyMax
efa21ec9ac Merge pull request #830 from crazy-max/signing-manifest
sigstore: sign and verify BuildKit attestation manifests
2025-11-03 11:42:27 +01:00
CrazyMax
3588cc8ad4 docker(install): increase lima start timeout
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-03 11:39:42 +01:00
CrazyMax
bbd652b087 docker(install): increase dockerd startup timeout
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-03 11:39:31 +01:00
CrazyMax
e85f11c5bd docker(install): don't use local system resolver with lima
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-03 11:09:16 +01:00
CrazyMax
5d9b7822a6 sigstore: sign and verify BuildKit attestation manifests
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-03 09:35:07 +01:00
CrazyMax
b4f8e5f0f9 Merge pull request #820 from crazy-max/signing
sigstore class to sign and verify buildkit provenance blobs
2025-11-03 09:34:37 +01:00
CrazyMax
3ed33f61c4 Merge pull request #835 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-11-02 01:58:56 +01:00
crazy-max
a61e8fdb65 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-01 00:35:16 +00:00
CrazyMax
364d8e8cda sigstore: verifySignedArtifacts func
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-30 15:52:34 +01:00
CrazyMax
1c0dc52a0e sigstore: always set TSA server endpoint to provide trusted timestamping
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-30 15:52:34 +01:00
CrazyMax
36cc95143c sigstore class to sign buildkit provenance blobs
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-30 15:52:33 +01:00
CrazyMax
24b234cb06 Merge pull request #823 from crazy-max/buildx-attestations-digest
buildx(imagetools): return attestations digests
2025-10-30 15:52:12 +01:00
CrazyMax
b2a04264d7 Merge pull request #829 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-10-30 13:20:56 +01:00
crazy-max
019e7ff457 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-30 12:10:27 +00:00
CrazyMax
0ea9d89ee1 Merge pull request #828 from crazy-max/cosign-skip-state
cosign(install): skipState opt to directly upload to GHA cache
2025-10-30 13:09:52 +01:00
CrazyMax
1764424b68 cosign(install): skipState opt to directly upload to GHA cache
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-30 12:17:33 +01:00
CrazyMax
dfe6c8d9e5 Merge pull request #827 from crazy-max/cosign-version
cosign version
2025-10-30 09:56:24 +01:00
CrazyMax
0f9a1c9368 cosign version
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-29 18:24:42 +01:00
CrazyMax
6b0ff671bc Merge pull request #826 from crazy-max/cosign-install
cosign install
2025-10-29 18:24:27 +01:00
CrazyMax
5b8fb95ca3 cosign install
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-29 16:18:29 +01:00
CrazyMax
9ada6fdf12 Merge pull request #825 from docker/bot/cosign-releases-json
Update `.github/cosign-releases.json`
2025-10-29 14:46:33 +01:00
crazy-max
b0b427d52f github: update .github/cosign-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-29 13:46:15 +00:00
CrazyMax
0a93f2f5be Merge pull request #824 from crazy-max/cosign-releases-json
ci: cosign releases json workflow
2025-10-29 14:45:48 +01:00
CrazyMax
1de1c446bf ci: cosign releases json workflow
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-29 14:44:20 +01:00
CrazyMax
16d264a310 Merge pull request #821 from crazy-max/update-lima-images
docker(install): update lima images
2025-10-29 13:31:59 +01:00
CrazyMax
1dc98594b3 Merge pull request #819 from crazy-max/install-cdn-token
use github token to fetch releases JSON from CDN if available
2025-10-29 11:07:18 +01:00
CrazyMax
e436a08992 docker(install): update lima images
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-29 10:39:38 +01:00
CrazyMax
75cde1582a Merge pull request #822 from crazy-max/ci-macos-15-intel
ci(test): update to macos-15-intel
2025-10-28 13:40:24 +01:00
CrazyMax
2bef6ba8d9 ci(test): update to macos-15-intel
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-28 12:31:25 +01:00
CrazyMax
437b1870cc buildx(imagetools): return attestations digests
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-28 11:35:08 +01:00
CrazyMax
2acf5409f8 Merge pull request #817 from docker/dependabot/github_actions/actions/download-artifact-6
build(deps): bump actions/download-artifact from 5 to 6
2025-10-28 10:43:19 +01:00
CrazyMax
0d894f0870 Merge pull request #818 from docker/dependabot/npm_and_yarn/actions/artifact-4.0.0
build(deps): bump @actions/artifact from 2.3.2 to 4.0.0
2025-10-28 10:30:53 +01:00
CrazyMax
f8d7170ef4 ci: update crazy-max/.github/.github/workflows/releases-json to 34fd436
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-28 09:46:22 +01:00
CrazyMax
d970614050 github: use github token to fetch releases JSON from CDN if available
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-28 09:35:50 +01:00
CrazyMax
503a033f4a github: use github token to download releases with actions/tool-cache if available
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-28 09:35:50 +01:00
CrazyMax
8e64b4303b releases: mutualize releases handling logic and move it to github class
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-28 09:35:50 +01:00
dependabot[bot]
3249537c32 build(deps): bump @actions/artifact from 2.3.2 to 4.0.0
Bumps [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) from 2.3.2 to 4.0.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/artifact/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/@actions/cache@4.0.0/packages/artifact)

---
updated-dependencies:
- dependency-name: "@actions/artifact"
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-24 22:07:10 +00:00
dependabot[bot]
dd7082cfe3 build(deps): bump actions/download-artifact from 5 to 6
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-24 22:06:06 +00:00
CrazyMax
5568d95611 Merge pull request #816 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-10-23 09:12:28 +02:00
crazy-max
3c7308e1e3 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-23 00:34:20 +00:00
CrazyMax
08239d0545 Merge pull request #814 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-10-22 13:22:12 +02:00
crazy-max
660f4c287e github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-18 00:31:51 +00:00
Paweł Gronowski
779136b849 Merge pull request #813 from crazy-max/docker-install-fix-version
Some checks failed
publish / publish (push) Has been cancelled
docker(install): fix source archive version
2025-10-16 12:01:01 +02:00
CrazyMax
0c5ce444d7 docker(install): fix source archive version
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-15 12:38:08 +02:00
CrazyMax
907e9d8118 Merge pull request #812 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-10-15 12:17:46 +02:00
crazy-max
c9db613fce github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-15 10:15:16 +00:00
CrazyMax
73904748dc Merge pull request #811 from crazy-max/moby-releases-json-fix
ci: fix docker releases json workflow
2025-10-15 12:14:47 +02:00
CrazyMax
40cb100aa4 ci: fix docker releases json workflow
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-15 11:13:31 +02:00
CrazyMax
6b7c32c45e Merge pull request #810 from docker/dependabot/github_actions/actions/setup-node-6
build(deps): bump actions/setup-node from 5 to 6
2025-10-15 10:21:48 +02:00
dependabot[bot]
e6b5804ee1 build(deps): bump actions/setup-node from 5 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-14 22:05:03 +00:00
CrazyMax
f219785672 Merge pull request #739 from docker/dependabot/npm_and_yarn/csv-parse-6.1.0
build(deps): bump csv-parse from 5.6.0 to 6.1.0
2025-10-13 16:27:25 +02:00
CrazyMax
87262f28a1 Merge pull request #808 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-10-09 11:04:10 +02:00
crazy-max
dd8f44d9e0 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-09 00:30:26 +00:00
CrazyMax
edee0fa2c0 Merge pull request #806 from docker/dependabot/github_actions/github/codeql-action-4
build(deps): bump github/codeql-action from 3 to 4
2025-10-08 08:55:06 +02:00
CrazyMax
fa3bc45740 Merge pull request #807 from docker/dependabot/npm_and_yarn/multi-c9330d5d78
build(deps): bump semver and @types/semver
2025-10-08 08:54:49 +02:00
dependabot[bot]
69c6b19130 build(deps): bump semver and @types/semver
Bumps [semver](https://github.com/npm/node-semver) and [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver). These dependencies needed to be updated together.

Updates `semver` from 7.7.2 to 7.7.3
- [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.7.2...v7.7.3)

Updates `@types/semver` from 7.7.0 to 7.7.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

---
updated-dependencies:
- dependency-name: semver
  dependency-version: 7.7.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: "@types/semver"
  dependency-version: 7.7.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-07 22:06:45 +00:00
dependabot[bot]
445300bbc6 build(deps): bump github/codeql-action from 3 to 4
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-07 22:05:23 +00:00
CrazyMax
d57a631bdc Merge pull request #805 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-10-06 15:53:39 +02:00
crazy-max
2169fa7066 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-06 12:14:18 +00:00
CrazyMax
7b4f4f5e38 Merge pull request #804 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-10-03 15:34:52 +02:00
crazy-max
46ecfc67a8 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-03 13:25:49 +00:00
CrazyMax
063e15b4d1 Merge pull request #803 from crazy-max/buildx-0.29.1
update buildx to 0.29.1
2025-10-03 15:25:15 +02:00
CrazyMax
eff67f5f78 update buildx to 0.29.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-10-03 15:06:55 +02:00
CrazyMax
45a37f0bfd Merge pull request #801 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-10-03 14:41:34 +02:00
CrazyMax
4422472369 Merge pull request #802 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-10-03 14:41:20 +02:00
crazy-max
e5b030e66b github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-03 12:40:58 +00:00
crazy-max
97dcad9699 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-03 00:29:34 +00:00
CrazyMax
01f6429e21 Merge pull request #794 from docker/dependabot/npm_and_yarn/actions/cache-4.1.0
build(deps): bump @actions/cache from 4.0.5 to 4.1.0
2025-10-02 11:52:06 +02:00
CrazyMax
29e291e74b Merge pull request #800 from jsternberg/buildkit-update
update buildkit to 0.25.0 and buildx to 0.29.0
2025-10-02 11:51:45 +02:00
CrazyMax
94f3c26bb6 Merge pull request #799 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-10-02 11:43:39 +02:00
Jonathan A. Sternberg
7caef13745 update buildkit to 0.25.0 and buildx to 0.29.0
Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
2025-10-01 10:27:40 -05:00
crazy-max
063adad3cf github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-01 00:26:00 +00:00
CrazyMax
05c231f81d Merge pull request #795 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-09-29 09:26:22 +02:00
CrazyMax
de12a30676 Merge pull request #793 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-09-29 09:26:05 +02:00
crazy-max
73653a12a4 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-29 07:26:05 +00:00
CrazyMax
395917aada Merge pull request #792 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-09-29 09:25:45 +02:00
dependabot[bot]
e93e6442aa build(deps): bump @actions/cache from 4.0.5 to 4.1.0
Bumps [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) from 4.0.5 to 4.1.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/cache)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 22:06:37 +00:00
crazy-max
237511a26b github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-24 12:09:05 +00:00
crazy-max
fb411f67b8 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-19 12:13:14 +00:00
CrazyMax
41c2b21211 Merge pull request #789 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-09-09 14:27:47 +02:00
crazy-max
1599ebac93 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-09 12:14:31 +00:00
CrazyMax
f52ee8216e Merge pull request #788 from crazy-max/fix-setup-node
ci: fix setup node on windows
2025-09-05 15:01:41 +02:00
CrazyMax
73cdd9ca0c ci: fix setup node on windows
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-09-05 14:27:10 +02:00
CrazyMax
73a0026f5d Merge pull request #785 from docker/dependabot/github_actions/actions/setup-node-5
build(deps): bump actions/setup-node from 4 to 5
2025-09-05 14:17:54 +02:00
CrazyMax
47fe3b74db Merge pull request #784 from docker/dependabot/github_actions/actions/github-script-8
build(deps): bump actions/github-script from 7 to 8
2025-09-05 14:17:36 +02:00
CrazyMax
f8afff957a Merge pull request #786 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-09-05 14:17:13 +02:00
crazy-max
da5c7028c4 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-05 12:16:55 +00:00
CrazyMax
ddbc043c1b Merge pull request #787 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-09-05 14:16:31 +02:00
crazy-max
14bc533241 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-05 12:07:53 +00:00
dependabot[bot]
0c7d839e0b build(deps): bump actions/setup-node from 4 to 5
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 5.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 22:05:44 +00:00
dependabot[bot]
58031512a9 build(deps): bump actions/github-script from 7 to 8
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 22:05:40 +00:00
CrazyMax
1172cc928e Merge pull request #777 from crazy-max/buildx-0.28.0
update buildkit to 0.24.0 and buildx to 0.28.0
2025-09-04 10:40:47 +02:00
CrazyMax
65f39025a8 Merge pull request #783 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-09-04 10:27:44 +02:00
CrazyMax
4f494c037c update buildkit to 0.24.0 and buildx to 0.28.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-09-04 10:26:04 +02:00
tonistiigi
d4aa70d4c0 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-04 00:13:09 +00:00
Tõnis Tiigi
6e168cc25e Merge pull request #782 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-09-03 17:12:46 -07:00
tonistiigi
35991a06a0 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-04 00:12:00 +00:00
CrazyMax
50543349b4 Merge pull request #781 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-09-02 14:49:56 +02:00
crazy-max
00e0ea4a5b github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-02 12:12:58 +00:00
CrazyMax
e804718f2d Merge pull request #780 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-09-01 16:56:36 +02:00
crazy-max
266da332cd github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-01 12:12:34 +00:00
CrazyMax
bd65081400 update buildkit to 0.24.0-rc2 and buildx to 0.28.0-rc2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-31 08:39:45 +02:00
CrazyMax
ea6ea13a87 Merge pull request #779 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-08-31 08:36:44 +02:00
CrazyMax
ea895c7e4e Merge pull request #778 from docker/bot/regclient-releases-json
Update `.github/regclient-releases.json`
2025-08-31 08:36:27 +02:00
crazy-max
7e457f7c85 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-30 00:21:31 +00:00
crazy-max
db3ff5c1eb github: update .github/regclient-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-30 00:11:11 +00:00
CrazyMax
b2ffab917f update buildkit to 0.24.0-rc1 and buildx to 0.28.0-rc1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-28 10:25:29 +02:00
CrazyMax
83a325be96 Merge pull request #775 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-08-28 10:21:04 +02:00
crazy-max
af8a156cc2 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-28 00:22:41 +00:00
dependabot[bot]
cda43ae9ae build(deps): bump csv-parse from 5.6.0 to 6.1.0
Bumps [csv-parse](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-parse) from 5.6.0 to 6.1.0.
- [Changelog](https://github.com/adaltas/node-csv/blob/master/packages/csv-parse/CHANGELOG.md)
- [Commits](https://github.com/adaltas/node-csv/commits/csv-parse@6.1.0/packages/csv-parse)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-27 14:20:18 +00:00
CrazyMax
b11e480862 Merge pull request #774 from docker/bot/regclient-releases-json
Update `.github/regclient-releases.json`
2025-08-27 16:17:34 +02:00
crazy-max
1c5138ccdd github: update .github/regclient-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-25 00:12:25 +00:00
CrazyMax
c006aedf93 Merge pull request #773 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-08-23 17:02:28 +02:00
crazy-max
f06b6e729c github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-23 00:20:05 +00:00
CrazyMax
2bf380ec27 Merge pull request #770 from crazy-max/buildx-0.27.0
update buildx to 0.27.0
2025-08-20 14:25:17 +02:00
CrazyMax
6d37992f6f update buildx to 0.27.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-20 11:53:01 +02:00
CrazyMax
ee56fb8ef5 Merge pull request #771 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-08-20 11:52:12 +02:00
crazy-max
118c87c80f github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-20 09:51:20 +00:00
CrazyMax
138224b138 update buildx to 0.27.0-rc1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-14 10:51:40 +02:00
CrazyMax
633bcf1936 Merge pull request #767 from crazy-max/ci-node24
ci: test node 24
2025-08-14 10:48:01 +02:00
CrazyMax
414bfa4864 Merge pull request #769 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-08-14 10:47:47 +02:00
crazy-max
126f70ef0b github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-14 08:47:30 +00:00
CrazyMax
349c31e4be ci: test node 24
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-12 11:00:49 +02:00
CrazyMax
8b99173e2f Merge pull request #766 from docker/dependabot/github_actions/actions/checkout-5
build(deps): bump actions/checkout from 4 to 5
2025-08-12 09:38:58 +02:00
dependabot[bot]
7f18246934 build(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [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/v4...v5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 06:27:06 +00:00
CrazyMax
5cab49bf34 Merge pull request #764 from docker/dependabot/npm_and_yarn/tmp-0.2.5
build(deps): bump tmp from 0.2.4 to 0.2.5
2025-08-09 19:45:03 +02:00
CrazyMax
4c0aba7764 Merge pull request #765 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-08-09 19:44:47 +02:00
crazy-max
20f83fbb18 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-09 00:35:41 +00:00
dependabot[bot]
6c1bec71a0 build(deps): bump tmp from 0.2.4 to 0.2.5
Bumps [tmp](https://github.com/raszi/node-tmp) from 0.2.4 to 0.2.5.
- [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/raszi/node-tmp/compare/v0.2.4...v0.2.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 22:31:25 +00:00
CrazyMax
2e23307cfd Merge pull request #763 from crazy-max/docker-install-xdg
docker(install): set missing XDG_RUNTIME_DIR env
2025-08-08 10:26:35 +02:00
CrazyMax
7f3d74b83d docker(install): set missing XDG_RUNTIME_DIR env
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-08 10:11:33 +02:00
CrazyMax
b58200a858 Merge pull request #762 from docker/dependabot/npm_and_yarn/actions/cache-4.0.5
build(deps): bump @actions/cache from 4.0.3 to 4.0.5
2025-08-08 08:09:56 +02:00
dependabot[bot]
e0b40bb755 build(deps): bump @actions/cache from 4.0.3 to 4.0.5
Bumps [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) from 4.0.3 to 4.0.5.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/cache)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-07 22:49:20 +00:00
CrazyMax
70344da3c1 Merge pull request #758 from crazy-max/update-docker
dockerfile: update docker to 28.3
2025-08-06 20:56:26 +02:00
CrazyMax
28eac7018d dockerfile: update docker to 28.3
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-06 20:36:34 +02:00
CrazyMax
62d7dc4060 Merge pull request #759 from crazy-max/update-compose
dockerfile: update compose to 2.39.1
2025-08-06 20:30:23 +02:00
CrazyMax
06b1747c94 dockerfile: update compose to 2.39.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-06 18:56:54 +02:00
CrazyMax
6ffec23867 Merge pull request #757 from docker/dependabot/npm_and_yarn/brace-expansion-1.1.12
build(deps): bump brace-expansion from 1.1.11 to 1.1.12
2025-08-06 17:23:21 +02:00
CrazyMax
70bdb203ef Merge pull request #755 from docker/dependabot/npm_and_yarn/tar-6.2.1
build(deps): bump tar from 6.1.13 to 6.2.1
2025-08-06 17:18:54 +02:00
CrazyMax
e80250a7ec Merge pull request #756 from docker/dependabot/npm_and_yarn/undici-5.29.0
build(deps): bump undici from 5.28.4 to 5.29.0
2025-08-06 17:18:37 +02:00
dependabot[bot]
49eec7eec9 build(deps): bump brace-expansion from 1.1.11 to 1.1.12
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.11 to 1.1.12.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.12)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 15:07:37 +00:00
dependabot[bot]
42e32959ef build(deps): bump undici from 5.28.4 to 5.29.0
Bumps [undici](https://github.com/nodejs/undici) from 5.28.4 to 5.29.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.28.4...v5.29.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 5.29.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 15:07:32 +00:00
dependabot[bot]
0723bdfc3e build(deps): bump tar from 6.1.13 to 6.2.1
Bumps [tar](https://github.com/isaacs/node-tar) from 6.1.13 to 6.2.1.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v6.1.13...v6.2.1)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 6.2.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 15:07:31 +00:00
CrazyMax
512e9bf560 Merge pull request #752 from docker/dependabot/github_actions/actions/download-artifact-5
build(deps): bump actions/download-artifact from 4 to 5
2025-08-06 15:23:05 +02:00
CrazyMax
2dc44d5d81 Merge pull request #753 from docker/dependabot/github_actions/peter-evans/create-pull-request-7.0.8
build(deps): bump peter-evans/create-pull-request from 7.0.5 to 7.0.8
2025-08-06 14:10:11 +02:00
dependabot[bot]
5fa7bea59b build(deps): bump peter-evans/create-pull-request from 7.0.5 to 7.0.8
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.5 to 7.0.8.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](5e914681df...271a8d0340)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: 7.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 11:58:36 +00:00
dependabot[bot]
a6055db0a1 build(deps): bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 11:58:24 +00:00
CrazyMax
76f06a5079 Merge pull request #751 from crazy-max/yarn-update
Some checks failed
publish / publish (push) Has been cancelled
update yarn to 4.9.2
2025-08-06 12:57:49 +02:00
CrazyMax
f59da75486 update yarn to 4.9.2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-06 12:41:29 +02:00
CrazyMax
1d5755a47e Merge pull request #750 from crazy-max/update-dependencies
update dependencies
2025-08-06 12:04:41 +02:00
CrazyMax
b692e6d7ee test: increase timeout
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-06 11:39:14 +02:00
CrazyMax
4720b49f24 bump tmp from 0.2.3 to 0.2.4
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-06 11:39:14 +02:00
CrazyMax
f5a8b11574 update dev dependencies
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-06 11:39:13 +02:00
CrazyMax
f7f2c7014b bump @octokit/plugin-rest-endpoint-methods from 10.4.0 to 10.4.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-06 10:18:42 +02:00
CrazyMax
02f5c6520e bump @octokit/core from 5.1.0 to 5.2.2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-08-06 10:18:02 +02:00
CrazyMax
8afe7117e7 Merge pull request #749 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-08-05 15:17:37 +02:00
crazy-max
6135b49e29 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-29 12:14:05 +00:00
CrazyMax
ada84b3298 Merge pull request #748 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-07-25 16:18:37 +02:00
crazy-max
7c6fb390df github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-25 00:38:07 +00:00
CrazyMax
bc5018ec16 Merge pull request #746 from crazy-max/buildx-0.26.1
update buildx to 0.26.1
2025-07-24 14:20:21 +02:00
CrazyMax
284fe3b3af Merge pull request #747 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-07-24 14:19:47 +02:00
crazy-max
f879c028cb github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-24 12:14:32 +00:00
CrazyMax
a9ecb0c114 update buildx to 0.26.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-07-22 18:30:08 +02:00
CrazyMax
d94dcc623b Merge pull request #745 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-07-22 18:29:10 +02:00
crazy-max
f0ea685edd github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-22 16:28:29 +00:00
CrazyMax
133c9694f3 Merge pull request #743 from docker/dependabot/npm_and_yarn/form-data-2.5.5
build(deps): bump form-data from 2.5.1 to 2.5.5
2025-07-22 14:28:01 +02:00
CrazyMax
f55e3b3f37 Merge pull request #744 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-07-22 14:27:38 +02:00
crazy-max
467c3685fd github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-22 12:08:30 +00:00
dependabot[bot]
63869fed42 build(deps): bump form-data from 2.5.1 to 2.5.5
---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 2.5.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-22 07:55:42 +00:00
Tõnis Tiigi
85e65d7025 Merge pull request #742 from crazy-max/buildx-0.26.0
update buildx to 0.26.0
2025-07-21 10:17:08 -07:00
CrazyMax
26fda91092 update buildx to 0.26.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-07-21 18:05:29 +02:00
CrazyMax
424b98ba19 Merge pull request #741 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-07-21 17:57:27 +02:00
crazy-max
cdd85dddec github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-21 15:41:04 +00:00
CrazyMax
6202649b3b Merge pull request #740 from crazy-max/buildx-0.26.0-rc1
update buildx to 0.26.0-rc1
2025-07-21 10:21:42 +02:00
CrazyMax
28cb27f01f update buildx to 0.26.0-rc1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-07-21 09:49:52 +02:00
CrazyMax
99eda99314 Merge pull request #738 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-07-21 09:48:06 +02:00
CrazyMax
852552a317 Merge pull request #737 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-07-21 09:47:48 +02:00
crazy-max
2e0033b995 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-16 00:34:47 +00:00
crazy-max
f3b6010231 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-16 00:25:07 +00:00
CrazyMax
73ce67c895 Merge pull request #734 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-07-15 17:05:22 +02:00
crazy-max
d9a8918b85 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-10 00:33:59 +00:00
CrazyMax
abfc9c328e Merge pull request #733 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-07-08 15:07:38 +02:00
CrazyMax
fcf78a4555 Merge pull request #732 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-07-08 15:07:22 +02:00
crazy-max
6cdc93adc5 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-08 12:14:20 +00:00
crazy-max
084dec0e7b github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-03 00:33:34 +00:00
CrazyMax
e24930f9b6 Merge pull request #731 from crazy-max/dockerfile-secret-env
dockerfile: use secret as env
2025-07-02 12:10:18 +02:00
CrazyMax
b01c83d8ba dockerfile: use secret as env
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-07-02 12:00:01 +02:00
CrazyMax
256057c80c Merge pull request #730 from crazy-max/buildkit-0.23.2
ci: update buildkit to 0.23.2
2025-07-02 11:57:55 +02:00
CrazyMax
9d13ced5ec ci: update buildkit to 0.23.2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-07-02 10:43:24 +02:00
CrazyMax
a7603d5893 Merge pull request #728 from crazy-max/update-arm-runner
ci: update ubuntu runner to 24.04
2025-07-02 10:33:41 +02:00
CrazyMax
1f18959d76 ci: update ubuntu runner to 24.04
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-07-02 10:09:13 +02:00
CrazyMax
de3d72c03e Merge pull request #729 from crazy-max/test-increase-timeout
test: increase timeout for regctl integration tests
2025-07-02 10:08:33 +02:00
CrazyMax
784a4d75f3 test: increase timeout for regctl integration tests
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-07-02 00:23:58 +02:00
CrazyMax
70d55f7fa2 Merge pull request #727 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-07-01 16:17:19 +02:00
CrazyMax
2910ea5cdb Merge pull request #726 from docker/bot/regclient-releases-json
Update `.github/regclient-releases.json`
2025-07-01 16:17:00 +02:00
crazy-max
e03210d324 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-01 00:41:31 +00:00
crazy-max
38e2ddbdf4 github: update .github/regclient-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-01 00:14:00 +00:00
CrazyMax
8c9de189c5 Merge pull request #725 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-06-25 09:39:18 +02:00
crazy-max
933da017c7 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-25 00:33:40 +00:00
CrazyMax
ae8086d624 Merge pull request #724 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-06-24 17:06:06 +02:00
crazy-max
8ac845da3d github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-24 15:05:42 +00:00
CrazyMax
3b7de7949e Merge pull request #723 from docker/bot/compose-lab-releases-json
Update `.github/compose-lab-releases.json`
2025-06-23 09:14:43 +02:00
crazy-max
19211b29ba github: update .github/compose-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-23 00:37:09 +00:00
CrazyMax
1fa551e525 Merge pull request #720 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-06-21 12:25:19 +02:00
CrazyMax
5488358f5e Merge pull request #721 from docker/bot/compose-lab-releases-json
Update `.github/compose-lab-releases.json`
2025-06-21 12:25:00 +02:00
crazy-max
7e4151a9f9 github: update .github/compose-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-21 10:24:50 +00:00
crazy-max
fd2b858d39 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-21 10:24:48 +00:00
CrazyMax
834f65080b Merge pull request #722 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-06-21 12:24:29 +02:00
crazy-max
5bed554061 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-21 00:35:25 +00:00
CrazyMax
42e6cecf05 Merge pull request #718 from crazy-max/buildkit-0.23.1
ci: update buildkit to 0.23.1
2025-06-20 14:30:51 +02:00
CrazyMax
e1fe1e9bf0 Merge pull request #719 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-06-20 14:30:26 +02:00
crazy-max
e2bb58898d github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-20 12:08:16 +00:00
CrazyMax
f70c2911e7 ci: update buildkit to 0.23.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-06-20 11:45:48 +02:00
CrazyMax
2ef044b120 Merge pull request #717 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-06-19 18:25:02 +02:00
crazy-max
46954a73c3 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-19 00:33:30 +00:00
CrazyMax
c0eab67a94 Merge pull request #715 from jsternberg/buildkit-bump
ci: update buildkit to 0.23.0 and buildx to 0.25.0
2025-06-18 10:37:02 +02:00
CrazyMax
426d5f68b3 Merge pull request #716 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-06-18 10:36:29 +02:00
jsternberg
726db5a47a github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-17 18:33:55 +00:00
Jonathan A. Sternberg
664bc50587 ci: update buildkit to 0.23.0 and buildx to 0.25.0
Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
2025-06-17 13:31:15 -05:00
CrazyMax
c8e714a354 Merge pull request #714 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-06-17 11:29:40 +02:00
crazy-max
e9303368d1 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-17 09:28:36 +00:00
CrazyMax
9671601b41 Merge pull request #713 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-06-17 11:28:11 +02:00
crazy-max
5204ff2122 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-17 00:33:16 +00:00
CrazyMax
dc75e74ba5 Merge pull request #712 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-06-12 15:25:46 +02:00
crazy-max
868117a604 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-12 12:13:38 +00:00
CrazyMax
b01158e255 Merge pull request #710 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-06-12 10:51:53 +02:00
crazy-max
d1d39a2073 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-12 08:51:02 +00:00
CrazyMax
7728f28325 Merge pull request #709 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-06-11 11:22:42 +02:00
crazy-max
511fe6a3ad github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-06 00:35:16 +00:00
CrazyMax
316aad663d Merge pull request #708 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-06-02 09:03:53 +02:00
crazy-max
f472c05360 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-31 00:31:50 +00:00
CrazyMax
88d39b6b65 Merge pull request #707 from crazy-max/fix-dbc-summary
Some checks failed
publish / publish (push) Has been cancelled
github: fix summary handling for dbc
2025-05-27 17:22:06 +02:00
CrazyMax
8c0b64dc2d github: fix summary handling for dbc
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-27 16:58:48 +02:00
CrazyMax
34ddc492b5 Merge pull request #690 from crazy-max/history-export-finalize
Some checks failed
publish / publish (push) Has been cancelled
history: finalize when exporting
2025-05-27 13:23:15 +02:00
CrazyMax
793f1ea4f4 history: finalize when exporting
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-27 13:09:52 +02:00
CrazyMax
a4662bb97e Merge pull request #705 from crazy-max/test-skip-windows-docker-install
ci: skip image source on windows runner for docker install
2025-05-26 13:24:01 +02:00
CrazyMax
2525b9b8d5 ci: skip image source on windows runner for docker install
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-26 12:01:55 +02:00
CrazyMax
d10fb805e1 Merge pull request #704 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-05-26 09:54:29 +02:00
crazy-max
0fc1c66aa9 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-26 07:54:14 +00:00
CrazyMax
255a1acd5c Merge pull request #703 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-05-26 09:53:25 +02:00
crazy-max
9b0a40cd16 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-24 00:31:13 +00:00
CrazyMax
6691b2b0c0 Merge pull request #686 from crazy-max/gh-summary-cloud-driver
github: support cloud build URL when writing summary
2025-05-23 15:44:42 +02:00
CrazyMax
b16fac0b68 github: support multiple refs with build URL for summary
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-23 10:21:15 +02:00
CrazyMax
cc1a989b3a github: support build URL when writing summary
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-22 15:17:01 +02:00
CrazyMax
1e2fcf0428 buildx(history): add platform in summary struct
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-22 15:17:01 +02:00
CrazyMax
ee9866a77d Merge pull request #702 from crazy-max/buildkit-0.22.0
update buildkit to v0.22.0 and buildx to 0.24.0
2025-05-21 19:07:01 +02:00
CrazyMax
de6233751c update buildkit to v0.22.0 and buildx to 0.24.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-21 18:40:51 +02:00
CrazyMax
85a5355fe3 Merge pull request #701 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-05-21 18:39:07 +02:00
crazy-max
e5d6bb0f2d github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-21 16:38:34 +00:00
CrazyMax
f6f1c2a529 Merge pull request #697 from crazy-max/docker-install-constructor-fix
docker(install): fix constructor
2025-05-21 11:10:53 +02:00
CrazyMax
2ac8bbf481 docker(install): fix constructor
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-20 17:42:49 +02:00
CrazyMax
b39426e79d Merge pull request #695 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-05-20 09:59:14 +02:00
crazy-max
77b856179e github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-20 07:58:10 +00:00
CrazyMax
c4e9006a17 Merge pull request #694 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-05-20 09:57:34 +02:00
CrazyMax
634a701c58 Merge pull request #693 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-05-20 09:57:17 +02:00
crazy-max
0cf2dd4875 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-20 00:36:11 +00:00
crazy-max
170581741c github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-20 00:33:33 +00:00
CrazyMax
0144d89bcb Merge pull request #689 from crazy-max/buildkit-0.22-buildx-0.24
update buildkit to v0.22.0-rc1 and buildx to 0.24.0-rc1
2025-05-19 09:24:10 +02:00
CrazyMax
6c4b7e3eec Merge pull request #692 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-05-19 09:23:18 +02:00
crazy-max
10a61cac65 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-19 00:22:18 +00:00
CrazyMax
1a0ad8897c Merge pull request #691 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-05-16 08:47:44 +02:00
crazy-max
7fc7da70b2 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-16 00:32:32 +00:00
CrazyMax
6bdec1ac0a Merge pull request #687 from docker/dependabot/npm_and_yarn/multi-1172310dfd
build(deps): bump semver and @types/semver
2025-05-15 10:44:12 +02:00
CrazyMax
2376759217 update buildkit to v0.22.0-rc1 and buildx to 0.24.0-rc1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-05-15 08:53:50 +02:00
CrazyMax
c9d77f0994 Merge pull request #688 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-05-15 08:51:27 +02:00
crazy-max
d39a6106a7 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-15 00:22:20 +00:00
dependabot[bot]
ed434d90f8 build(deps): bump semver and @types/semver
Bumps [semver](https://github.com/npm/node-semver) and [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver). These dependencies needed to be updated together.

Updates `semver` from 7.7.1 to 7.7.2
- [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.7.1...v7.7.2)

Updates `@types/semver` from 7.5.8 to 7.7.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

---
updated-dependencies:
- dependency-name: semver
  dependency-version: 7.7.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: "@types/semver"
  dependency-version: 7.7.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 22:27:21 +00:00
CrazyMax
ba0e8d7ed8 Merge pull request #683 from docker/dependabot/npm_and_yarn/actions/github-6.0.1
build(deps): bump @actions/github from 6.0.0 to 6.0.1
2025-05-08 20:55:46 +02:00
CrazyMax
b1674ba4f9 Merge pull request #682 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-05-08 20:54:29 +02:00
CrazyMax
d3666a8896 Merge pull request #681 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-05-08 20:54:06 +02:00
dependabot[bot]
252649554a build(deps): bump @actions/github from 6.0.0 to 6.0.1
Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 6.0.0 to 6.0.1.
- [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-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-07 22:10:34 +00:00
crazy-max
e1533840b8 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-07 12:14:00 +00:00
crazy-max
2d519db022 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-30 00:20:35 +00:00
CrazyMax
ff509b09e3 Merge pull request #680 from crazy-max/fix-jest-itg
Some checks failed
publish / publish (push) Has been cancelled
fix jest config for integration tests
2025-04-24 10:20:35 +02:00
CrazyMax
794148e937 Merge pull request #679 from docker/bot/regclient-releases-json
Update `.github/regclient-releases.json`
2025-04-24 10:06:26 +02:00
CrazyMax
68fd63a69e fix jest config for integration tests
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-24 10:04:34 +02:00
crazy-max
a619d07b13 github: update .github/regclient-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-24 00:11:24 +00:00
Tõnis Tiigi
7a2707542f Merge pull request #604 from crazy-max/inspect-devices
buildx(builder): inspect devices and new gc policy opts support
2025-04-23 10:39:44 -07:00
CrazyMax
b9e1a8724d Merge pull request #567 from crazy-max/docker-install-undock
docker(install): use undock to extract image
2025-04-23 19:14:47 +02:00
CrazyMax
68633e712c Merge pull request #678 from crazy-max/pr-assign-author
pr-assign-author workflow
2025-04-23 14:24:23 +02:00
CrazyMax
8a5874c915 pr-assign-author workflow
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-23 14:12:48 +02:00
CrazyMax
121f70dc94 Merge pull request #652 from crazy-max/buildx-history-cmd
Some checks failed
publish / publish (push) Has been cancelled
history: export build using history command support
2025-04-23 09:44:51 +02:00
CrazyMax
ad06f2a639 docker(install): use undock to extract image
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-22 14:54:18 +02:00
CrazyMax
b6da7a2050 Merge pull request #676 from crazy-max/test-fix-timeout
test: set proper timeout when downloading binaries
2025-04-22 14:53:40 +02:00
CrazyMax
bb3b1ba599 Merge pull request #675 from crazy-max/undock-fix-itg
undock: fix integration test
2025-04-22 14:25:47 +02:00
CrazyMax
ea697eb50e Merge pull request #674 from crazy-max/fix-codecov
ci: fix missing source for codecov
2025-04-22 14:22:23 +02:00
CrazyMax
7b4015430d test: set proper timeout when downloading binaries
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-22 14:13:52 +02:00
CrazyMax
1bfdd1d8c0 undock: fix integration test
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-22 14:13:31 +02:00
CrazyMax
c7a53cd33e ci: fix missing source for codecov
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-22 14:06:12 +02:00
CrazyMax
976ef75074 Merge pull request #673 from docker/bot/compose-lab-releases-json
Update `.github/compose-lab-releases.json`
2025-04-21 14:21:59 +02:00
crazy-max
b23c9810de github: update .github/compose-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-21 12:12:26 +00:00
CrazyMax
5ab8d39173 Merge pull request #672 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-04-19 18:44:58 +02:00
crazy-max
fec5979e2a github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-18 12:11:32 +00:00
CrazyMax
edf0c6e0df Merge pull request #671 from crazy-max/update-undock
dockerfile: update undock to 0.10.0
2025-04-18 12:06:19 +02:00
CrazyMax
41439563c4 undock: run integration test
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-18 11:51:43 +02:00
CrazyMax
5e5ef36a8e dockerfile: update undock to 0.10.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-18 11:44:53 +02:00
CrazyMax
c09122e635 Merge pull request #670 from docker/bot/undock-releases-json
Update `.github/undock-releases.json`
2025-04-18 11:35:39 +02:00
crazy-max
aa82a2fc79 github: update .github/undock-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-18 09:35:17 +00:00
CrazyMax
bcb7741d19 Merge pull request #668 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-04-18 09:28:12 +02:00
CrazyMax
58866dcebd Merge pull request #669 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-04-18 09:27:58 +02:00
crazy-max
09bf2161e9 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-18 00:33:04 +00:00
crazy-max
6f40bf1fe2 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-18 00:30:30 +00:00
CrazyMax
04e7d5416b Merge pull request #667 from crazy-max/regctl-manifest
regctl: manifestGet and blobGet funcs
2025-04-17 14:04:32 +02:00
CrazyMax
4dc0686a1f regctl: blobGet func
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-17 13:45:01 +02:00
CrazyMax
5a20e819d2 regctl: manifestGet
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-17 13:45:00 +02:00
CrazyMax
be98587238 Merge pull request #666 from crazy-max/regctl
regclient: regctl version
2025-04-17 11:28:59 +02:00
CrazyMax
d1f4283ae5 regclient: regctl version
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-17 11:05:59 +02:00
CrazyMax
fccce81f9c Merge pull request #665 from crazy-max/regclient-install
regclient install
2025-04-17 10:39:01 +02:00
CrazyMax
0e821a0c1f regclient install
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-16 22:17:53 +02:00
CrazyMax
a4f2334d09 Merge pull request #663 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-04-16 20:13:31 +02:00
CrazyMax
b2c080aba3 Merge pull request #664 from docker/bot/regclient-releases-json
Update `.github/regclient-releases.json`
2025-04-16 20:13:15 +02:00
crazy-max
6d5e976102 github: update .github/regclient-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-16 18:09:34 +00:00
crazy-max
a874a29054 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-16 18:09:29 +00:00
CrazyMax
feaf48d463 Merge pull request #662 from crazy-max/ci-regclient-releases
ci: regclient releases json workflow
2025-04-16 20:08:50 +02:00
CrazyMax
ce74df3e8c ci: regclient releases json workflow
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-16 19:39:33 +02:00
CrazyMax
3d078e8211 Merge pull request #661 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-04-16 14:16:15 +02:00
crazy-max
43f27ccecf github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-16 12:07:50 +00:00
CrazyMax
4731c96418 history: export command support
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-16 10:25:03 +02:00
CrazyMax
e1c74199da history: inspect command support
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-16 10:23:09 +02:00
CrazyMax
e12c042e86 util: formatDuration func
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-16 10:23:09 +02:00
CrazyMax
f630d6c05e Merge pull request #650 from crazy-max/buildkit-0.21.0
update buildkit to v0.21.0
2025-04-16 10:11:47 +02:00
CrazyMax
5dba2fe582 Merge pull request #659 from crazy-max/buildx-0.23.0
dockerfile: update buildx to 0.23.0
2025-04-16 10:08:26 +02:00
CrazyMax
fea2daff92 update buildkit to v0.21.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-16 09:57:28 +02:00
CrazyMax
28314383db dockerfile: update buildx to 0.23.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-16 09:56:20 +02:00
CrazyMax
495227c371 Merge pull request #660 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-04-16 09:54:47 +02:00
crazy-max
232976be61 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-16 00:22:43 +00:00
CrazyMax
c8b99c2422 update buildkit to v0.21.0-rc2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-14 10:47:09 +02:00
CrazyMax
044181df46 update buildkit to v0.21.0-rc1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-14 10:46:24 +02:00
CrazyMax
990a226a96 dockerfile: update buildx to 0.23.0-rc2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-14 10:45:34 +02:00
CrazyMax
238b35d5ec Merge pull request #658 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-04-14 10:42:15 +02:00
crazy-max
70df5c1471 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-12 12:37:42 +00:00
CrazyMax
94a5190281 Merge pull request #657 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-04-12 14:37:08 +02:00
crazy-max
81aefc93a4 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-12 00:21:45 +00:00
CrazyMax
3b90a8be48 Merge pull request #655 from crazy-max/rm-ubuntu-20
ci: update ubuntu runners to latest
2025-04-11 09:36:54 +02:00
CrazyMax
bc8619386e Merge pull request #656 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-04-11 09:36:27 +02:00
crazy-max
34677a2e0a github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-11 00:33:32 +00:00
CrazyMax
46ff1377e2 ci: update ubuntu runners to latest
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-11 01:52:08 +02:00
CrazyMax
59501e62b4 Merge pull request #649 from crazy-max/buildx-0.23.0
dockerfile: update buildx to 0.23.0-rc1
2025-04-10 14:22:21 +02:00
CrazyMax
fa8b332d39 dockerfile: update buildx to 0.23.0-rc1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-10 10:52:55 +02:00
CrazyMax
1a0e910dd6 Merge pull request #648 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-04-10 10:48:00 +02:00
fiam
ce1befb3f6 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-10 06:31:48 +00:00
Alberto García Hierro
edd4df2160 Merge pull request #647 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-04-10 07:31:18 +01:00
crazy-max
052fb0d672 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-10 00:19:44 +00:00
CrazyMax
b7b0b4c90e Merge pull request #645 from crazy-max/secret-enforce-redact
Some checks failed
publish / publish (push) Has been cancelled
buildx(build): always register as secret the value passed as build secret string
2025-04-08 13:24:59 +02:00
CrazyMax
6ddae4e63e buildx(build): always register as secret the value passed as build secret string
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-04-07 11:23:49 +02:00
CrazyMax
01c877d58f Merge pull request #644 from docker/bot/compose-lab-releases-json
Update `.github/compose-lab-releases.json`
2025-04-02 15:32:16 +02:00
crazy-max
53963b9b70 github: update .github/compose-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-02 12:12:11 +00:00
Alberto García Hierro
c04b6bed97 Merge pull request #642 from docker/bot/buildx-lab-releases-json
Some checks failed
publish / publish (push) Has been cancelled
Update `.github/buildx-lab-releases.json`
2025-03-31 18:19:12 +01:00
fiam
3f7ebbd664 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-31 17:17:49 +00:00
CrazyMax
7361719af0 Merge pull request #641 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-03-31 16:23:32 +02:00
crazy-max
dc66f26c9f github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-31 14:22:51 +00:00
CrazyMax
b14c41d999 Merge pull request #640 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-03-31 14:32:26 +02:00
crazy-max
9209bef96d github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-31 12:32:08 +00:00
CrazyMax
f473a29cad Merge pull request #639 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-03-31 14:31:39 +02:00
crazy-max
1f0b6fae3c github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-26 00:29:57 +00:00
CrazyMax
447ec66e02 Merge pull request #638 from jsternberg/buildkit-0.20.2
dockerfile: update buildkit to 0.20.2
2025-03-25 14:41:46 +01:00
Jonathan A. Sternberg
d3a8ffa1b2 dockerfile: update buildkit to 0.20.2
Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
2025-03-24 16:00:58 -05:00
CrazyMax
204c4d7e38 Merge pull request #637 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-03-20 10:32:11 +01:00
crazy-max
201d5c7c28 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-20 08:13:52 +00:00
CrazyMax
6c78ea88af Merge pull request #635 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-03-20 09:13:20 +01:00
crazy-max
6da579582a github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-20 00:19:05 +00:00
CrazyMax
62a0cec76c Merge pull request #631 from docker/dependabot/npm_and_yarn/actions/cache-4.0.3
build(deps): bump @actions/cache from 4.0.2 to 4.0.3
2025-03-19 15:07:02 +01:00
dependabot[bot]
f3e619ac0d build(deps): bump @actions/cache from 4.0.2 to 4.0.3
Bumps [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) from 4.0.2 to 4.0.3.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/cache)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-19 12:45:12 +00:00
CrazyMax
86e6d2d813 Merge pull request #633 from docker/dependabot/npm_and_yarn/actions/artifact-2.3.2
build(deps): bump @actions/artifact from 2.3.1 to 2.3.2
2025-03-19 13:42:54 +01:00
CrazyMax
3f928383ff Merge pull request #634 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-03-19 13:42:30 +01:00
crazy-max
1b5a7ad8cb github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-19 00:19:29 +00:00
dependabot[bot]
b381f09fbb build(deps): bump @actions/artifact from 2.3.1 to 2.3.2
Bumps [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) from 2.3.1 to 2.3.2.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/artifact/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/artifact)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-18 22:26:55 +00:00
CrazyMax
88374b9d89 Merge pull request #623 from crazy-max/buildx-0.22
dockerfile: update buildx to 0.22.0
2025-03-18 15:36:38 +01:00
CrazyMax
2eb7c42ef6 Merge pull request #630 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-03-18 15:29:51 +01:00
CrazyMax
c87163fbe4 dockerfile: update buildx to 0.22.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-03-18 15:25:51 +01:00
crazy-max
e9c2b861e8 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-18 14:25:51 +00:00
CrazyMax
be2b07b476 dockerfile: update buildx to 0.22.0-rc2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-03-17 21:26:44 +01:00
CrazyMax
e6e9ee8c00 Merge pull request #629 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-03-17 21:26:01 +01:00
crazy-max
fa1fc6bf68 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-17 20:25:19 +00:00
CrazyMax
21d9e67d3d Merge pull request #627 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-03-17 18:28:58 +01:00
crazy-max
aaaec24fee github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-17 17:21:30 +00:00
CrazyMax
739fe4a80c Merge pull request #625 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-03-14 13:33:22 +01:00
crazy-max
8c4124d200 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-14 12:27:08 +00:00
CrazyMax
76c63e19da Merge pull request #626 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-03-14 13:26:37 +01:00
crazy-max
ace326f534 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-14 12:12:08 +00:00
CrazyMax
d439fcbe10 Merge pull request #624 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-03-14 09:09:37 +01:00
crazy-max
5891a8ba9c github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-14 00:18:41 +00:00
CrazyMax
c574cb7c80 dockerfile: update buildx to 0.22.0-rc1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-03-12 10:35:28 +01:00
CrazyMax
091de209c9 Merge pull request #621 from docker/dependabot/npm_and_yarn/actions/artifact-2.3.1
build(deps): bump @actions/artifact from 2.3.0 to 2.3.1
2025-03-12 10:04:20 +01:00
CrazyMax
c369f5eabd Merge pull request #622 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-03-12 10:03:42 +01:00
crazy-max
bad91fef5a github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-12 00:21:17 +00:00
dependabot[bot]
eec732af11 build(deps): bump @actions/artifact from 2.3.0 to 2.3.1
Bumps [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) from 2.3.0 to 2.3.1.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/artifact/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/artifact)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-11 22:40:23 +00:00
CrazyMax
6ddef8a463 Merge pull request #620 from docker/dependabot/npm_and_yarn/actions/artifact-2.3.0
Some checks failed
publish / publish (push) Has been cancelled
build(deps): bump @actions/artifact from 2.2.2 to 2.3.0
2025-03-11 00:07:34 +01:00
dependabot[bot]
1de251545a build(deps): bump @actions/artifact from 2.2.2 to 2.3.0
Bumps [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) from 2.2.2 to 2.3.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/artifact/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/artifact)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 22:49:14 +00:00
CrazyMax
af76018577 Merge pull request #619 from crazy-max/update-lima-cfg
docker(install): update lima images
2025-03-10 14:52:40 +01:00
CrazyMax
7c54b0d570 docker(install): update lima images
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-03-10 12:55:47 +01:00
CrazyMax
977644b1c4 Merge pull request #618 from crazy-max/buildkit-0.20.1
update buildkit to 0.20.1
2025-03-06 13:55:36 +01:00
CrazyMax
d5da34a80b update buildkit to 0.20.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-03-05 17:10:02 +01:00
CrazyMax
de3328fb33 Merge pull request #616 from crazy-max/buildx-0.21.2
dockerfile: update buildx to 0.21.2
2025-03-05 13:27:59 +01:00
CrazyMax
391c776af6 Merge pull request #617 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-03-05 13:27:12 +01:00
crazy-max
8d2c24dd89 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-05 12:07:41 +00:00
CrazyMax
43b8598a0b dockerfile: update buildx to 0.21.2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-03-03 17:36:30 +01:00
CrazyMax
5a96697651 Merge pull request #615 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-03-03 17:35:25 +01:00
crazy-max
02d0feb7df github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-03 16:33:40 +00:00
CrazyMax
b5f9106e08 Merge pull request #613 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-02-27 09:26:11 +01:00
crazy-max
f93cd6712c github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-27 00:28:51 +00:00
CrazyMax
62397de881 buildx(builder): inspect devices and new gc policy opts support
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-02-24 10:24:19 +01:00
91 changed files with 23571 additions and 4570 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6526
.github/cosign-releases.json vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,221 @@
{
"latest": {
"id": 201152110,
"tag_name": "v28.0.0",
"html_url": "https://github.com/moby/moby/releases/tag/v28.0.0",
"assets": []
},
"v28.0.0": {
"id": 201152110,
"tag_name": "v28.0.0",
"html_url": "https://github.com/moby/moby/releases/tag/v28.0.0",
"id": 252833798,
"tag_name": "v28.5.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.5.1",
"assets": []
},
"edge": {
"id": 258289954,
"tag_name": "docker-v29.0.0-rc.2",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.0-rc.2",
"assets": []
},
"v29.0.0-rc.2": {
"id": 258289954,
"tag_name": "docker-v29.0.0-rc.2",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.0-rc.2",
"assets": []
},
"v29.0.0-rc.1": {
"id": 252020476,
"tag_name": "docker-v29.0.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.0-rc.1",
"assets": []
},
"v28.5.1": {
"id": 252833798,
"tag_name": "v28.5.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.5.1",
"assets": []
},
"v28.5.0": {
"id": 251798390,
"tag_name": "v28.5.0",
"html_url": "https://github.com/moby/moby/releases/tag/v28.5.0",
"assets": []
},
"v28.5.0-rc.1": {
"id": 249763924,
"tag_name": "v28.5.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.5.0-rc.1",
"assets": []
},
"v28.4.0": {
"id": 244504005,
"tag_name": "v28.4.0",
"html_url": "https://github.com/moby/moby/releases/tag/v28.4.0",
"assets": []
},
"v28.4.0-rc.2": {
"id": 244065281,
"tag_name": "v28.4.0-rc.2",
"html_url": "https://github.com/moby/moby/releases/tag/v28.4.0-rc.2",
"assets": []
},
"v28.4.0-rc.1": {
"id": 243821467,
"tag_name": "v28.4.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.4.0-rc.1",
"assets": []
},
"v25.0.13": {
"id": 244806783,
"tag_name": "v25.0.13",
"html_url": "https://github.com/moby/moby/releases/tag/v25.0.13",
"assets": []
},
"v28.3.3": {
"id": 235196329,
"tag_name": "v28.3.3",
"html_url": "https://github.com/moby/moby/releases/tag/v28.3.3",
"assets": []
},
"v25.0.12": {
"id": 232634573,
"tag_name": "v25.0.12",
"html_url": "https://github.com/moby/moby/releases/tag/v25.0.12",
"assets": []
},
"v28.3.2": {
"id": 231184033,
"tag_name": "v28.3.2",
"html_url": "https://github.com/moby/moby/releases/tag/v28.3.2",
"assets": []
},
"v28.3.1": {
"id": 229534501,
"tag_name": "v28.3.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.3.1",
"assets": []
},
"v28.3.0": {
"id": 227302240,
"tag_name": "v28.3.0",
"html_url": "https://github.com/moby/moby/releases/tag/v28.3.0",
"assets": []
},
"v28.3.0-rc.2": {
"id": 226745561,
"tag_name": "v28.3.0-rc.2",
"html_url": "https://github.com/moby/moby/releases/tag/v28.3.0-rc.2",
"assets": []
},
"v25.0.11": {
"id": 226304708,
"tag_name": "v25.0.11",
"html_url": "https://github.com/moby/moby/releases/tag/v25.0.11",
"assets": []
},
"v28.3.0-rc.1": {
"id": 225132759,
"tag_name": "v28.3.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.3.0-rc.1",
"assets": []
},
"v28.2.2": {
"id": 222034216,
"tag_name": "v28.2.2",
"html_url": "https://github.com/moby/moby/releases/tag/v28.2.2",
"assets": []
},
"v28.2.1": {
"id": 221664376,
"tag_name": "v28.2.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.2.1",
"assets": []
},
"v28.2.0": {
"id": 221225663,
"tag_name": "v28.2.0",
"html_url": "https://github.com/moby/moby/releases/tag/v28.2.0",
"assets": []
},
"v28.2.0-rc.2": {
"id": 220155575,
"tag_name": "v28.2.0-rc.2",
"html_url": "https://github.com/moby/moby/releases/tag/v28.2.0-rc.2",
"assets": []
},
"v28.2.0-rc.1": {
"id": 218898330,
"tag_name": "v28.2.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.2.0-rc.1",
"assets": []
},
"v25.0.10": {
"id": 218958962,
"tag_name": "v25.0.10",
"html_url": "https://github.com/moby/moby/releases/tag/v25.0.10",
"assets": []
},
"v25.0.9": {
"id": 218957753,
"tag_name": "v25.0.9",
"html_url": "https://github.com/moby/moby/releases/tag/v25.0.9",
"assets": []
},
"v23.0.18": {
"id": 218962082,
"tag_name": "v23.0.18",
"html_url": "https://github.com/moby/moby/releases/tag/v23.0.18",
"assets": []
},
"v23.0.17": {
"id": 218961915,
"tag_name": "v23.0.17",
"html_url": "https://github.com/moby/moby/releases/tag/v23.0.17",
"assets": []
},
"v28.1.1": {
"id": 213296967,
"tag_name": "v28.1.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.1.1",
"assets": []
},
"v28.1.0": {
"id": 213053128,
"tag_name": "v28.1.0",
"html_url": "https://github.com/moby/moby/releases/tag/v28.1.0",
"assets": []
},
"v28.1.0-rc.2": {
"id": 212786864,
"tag_name": "v28.1.0-rc.2",
"html_url": "https://github.com/moby/moby/releases/tag/v28.1.0-rc.2",
"assets": []
},
"v28.1.0-rc.1": {
"id": 211865941,
"tag_name": "v28.1.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.1.0-rc.1",
"assets": []
},
"v28.0.4": {
"id": 208163246,
"tag_name": "v28.0.4",
"html_url": "https://github.com/moby/moby/releases/tag/v28.0.4",
"assets": []
},
"v28.0.3": {
"id": 208121902,
"tag_name": "v28.0.3",
"html_url": "https://github.com/moby/moby/releases/tag/v28.0.3",
"assets": []
},
"v28.0.2": {
"id": 205678192,
"tag_name": "v28.0.2",
"html_url": "https://github.com/moby/moby/releases/tag/v28.0.2",
"assets": []
},
"v28.0.1": {
"id": 202550735,
"tag_name": "v28.0.1",
"html_url": "https://github.com/moby/moby/releases/tag/v28.0.1",
"assets": []
},
"v28.0.0": {
"id": 201152110,
"tag_name": "v28.0.0",
"html_url": "https://github.com/moby/moby/releases/tag/v28.0.0",

1163
.github/regclient-releases.json vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +1,90 @@
{
"latest": {
"id": 192171889,
"tag_name": "v0.9.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.9.0",
"id": 213293369,
"tag_name": "v0.10.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.10.0",
"assets": [
"https://github.com/crazy-max/undock/releases/download/v0.9.0/checksums.txt",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv5.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv5.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv5.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv6.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv6.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv6.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv7.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv7.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv7.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_ppc64le.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_ppc64le.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_ppc64le.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_riscv64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_riscv64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_riscv64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_s390x.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_s390x.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_s390x.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_amd64.zip",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_arm64.zip"
"https://github.com/crazy-max/undock/releases/download/v0.10.0/checksums.txt",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.zip",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.zip"
]
},
"v0.10.0": {
"id": 213293369,
"tag_name": "v0.10.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.10.0",
"assets": [
"https://github.com/crazy-max/undock/releases/download/v0.10.0/checksums.txt",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.zip",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.zip"
]
},
"v0.9.0": {
@@ -153,47 +197,47 @@
]
},
"edge": {
"id": 192171889,
"tag_name": "v0.9.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.9.0",
"id": 213293369,
"tag_name": "v0.10.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.10.0",
"assets": [
"https://github.com/crazy-max/undock/releases/download/v0.9.0/checksums.txt",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_darwin_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv5.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv5.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv5.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv6.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv6.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv6.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv7.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv7.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_armv7.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_ppc64le.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_ppc64le.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_ppc64le.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_riscv64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_riscv64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_riscv64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_s390x.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_s390x.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_linux_s390x.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_amd64.zip",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.9.0/undock_0.9.0_windows_arm64.zip"
"https://github.com/crazy-max/undock/releases/download/v0.10.0/checksums.txt",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_darwin_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv5.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv6.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_armv7.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_ppc64le.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_riscv64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_s390x.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_amd64.zip",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_windows_arm64.zip"
]
},
"v0.7.0-rc.1": {

View File

@@ -19,6 +19,7 @@ jobs:
fail-fast: false
matrix:
node_version:
- 24
- 20
- 18
steps:

View File

@@ -17,7 +17,7 @@ on:
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@7f83a5a887650a38e4d0e05d5262309cfaa31459
uses: crazy-max/.github/.github/workflows/releases-json.yml@34fd436075cac6431d2036d5f6f1c3f3d4687ac5
with:
repository: docker/buildx-desktop
artifact_name: buildx-lab-releases-json
@@ -25,17 +25,17 @@ jobs:
secrets: inherit
open-pr:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request'
needs:
- generate
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: buildx-lab-releases-json
path: .github
@@ -45,7 +45,7 @@ jobs:
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
base: main
branch: bot/buildx-lab-releases-json

View File

@@ -17,7 +17,7 @@ on:
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@7f83a5a887650a38e4d0e05d5262309cfaa31459
uses: crazy-max/.github/.github/workflows/releases-json.yml@34fd436075cac6431d2036d5f6f1c3f3d4687ac5
with:
repository: docker/buildx
artifact_name: buildx-releases-json
@@ -25,17 +25,17 @@ jobs:
secrets: inherit
open-pr:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request'
needs:
- generate
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: buildx-releases-json
path: .github
@@ -45,7 +45,7 @@ jobs:
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
base: main
branch: bot/buildx-releases-json

View File

@@ -20,7 +20,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Enable corepack
run: |
@@ -28,19 +28,19 @@ jobs:
yarn --version
-
name: Set up Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
-
name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: javascript-typescript
-
name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v4
-
name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: "/language:javascript-typescript"

View File

@@ -17,7 +17,7 @@ on:
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@7f83a5a887650a38e4d0e05d5262309cfaa31459
uses: crazy-max/.github/.github/workflows/releases-json.yml@34fd436075cac6431d2036d5f6f1c3f3d4687ac5
with:
repository: docker/compose-desktop
artifact_name: compose-lab-releases-json
@@ -25,17 +25,17 @@ jobs:
secrets: inherit
open-pr:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request'
needs:
- generate
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: compose-lab-releases-json
path: .github
@@ -45,7 +45,7 @@ jobs:
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
base: main
branch: bot/compose-lab-releases-json

View File

@@ -17,7 +17,7 @@ on:
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@7f83a5a887650a38e4d0e05d5262309cfaa31459
uses: crazy-max/.github/.github/workflows/releases-json.yml@34fd436075cac6431d2036d5f6f1c3f3d4687ac5
with:
repository: docker/compose
artifact_name: compose-releases-json
@@ -25,17 +25,17 @@ jobs:
secrets: inherit
open-pr:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request'
needs:
- generate
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: compose-releases-json
path: .github
@@ -45,7 +45,7 @@ jobs:
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
base: main
branch: bot/compose-releases-json

View File

@@ -0,0 +1,58 @@
name: cosign-releases-json
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
schedule:
- cron: '0 */12 * * *'
push:
branches:
- 'main'
pull_request:
paths:
- '.github/workflows/cosign-releases-json.yml'
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@34fd436075cac6431d2036d5f6f1c3f3d4687ac5
with:
repository: sigstore/cosign
artifact_name: cosign-releases-json
filename: cosign-releases.json
secrets: inherit
open-pr:
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request'
needs:
- generate
steps:
-
name: Checkout
uses: actions/checkout@v5
-
name: Download
uses: actions/download-artifact@v6
with:
name: cosign-releases-json
path: .github
-
name: Commit changes
run: |
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
base: main
branch: bot/cosign-releases-json
commit-message: "github: update .github/cosign-releases.json"
signoff: true
delete-branch: true
title: "Update `.github/cosign-releases.json`"
body: |
Update `.github/cosign-releases.json` to keep in sync with [https://github.com/sigstore/cosign](https://github.com/sigstore/cosign).
draft: false

View File

@@ -17,25 +17,26 @@ on:
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@7f83a5a887650a38e4d0e05d5262309cfaa31459
uses: crazy-max/.github/.github/workflows/releases-json.yml@34fd436075cac6431d2036d5f6f1c3f3d4687ac5
with:
repository: moby/moby
artifact_name: docker-releases-json
filename: docker-releases.json
tag_pattern: '^docker-(.*)$'
secrets: inherit
open-pr:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request'
needs:
- generate
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: docker-releases-json
path: .github
@@ -45,7 +46,7 @@ jobs:
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
base: main
branch: bot/docker-releases-json

17
.github/workflows/pr-assign-author.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: pr-assign-author
permissions:
contents: read
on:
pull_request_target:
types:
- opened
- reopened
jobs:
run:
uses: crazy-max/.github/.github/workflows/pr-assign-author.yml@1b673f36fad86812f538c1df9794904038a23cbf
permissions:
contents: read
pull-requests: write

View File

@@ -0,0 +1,58 @@
name: regclient-releases-json
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
schedule:
- cron: '0 */12 * * *'
push:
branches:
- 'main'
pull_request:
paths:
- '.github/workflows/regclient-releases-json.yml'
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@34fd436075cac6431d2036d5f6f1c3f3d4687ac5
with:
repository: regclient/regclient
artifact_name: regclient-releases-json
filename: regclient-releases.json
secrets: inherit
open-pr:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
needs:
- generate
steps:
-
name: Checkout
uses: actions/checkout@v5
-
name: Download
uses: actions/download-artifact@v6
with:
name: regclient-releases-json
path: .github
-
name: Commit changes
run: |
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
base: main
branch: bot/regclient-releases-json
commit-message: "github: update .github/regclient-releases.json"
signoff: true
delete-branch: true
title: "Update `.github/regclient-releases.json`"
body: |
Update `.github/regclient-releases.json` to keep in sync with [https://github.com/regclient/regclient](https://github.com/regclient/regclient).
draft: false

View File

@@ -16,7 +16,7 @@ on:
env:
NODE_VERSION: "20"
BUILDX_VERSION: "edge"
BUILDKIT_IMAGE: "moby/buildkit:v0.20.0"
BUILDKIT_IMAGE: "moby/buildkit:v0.25.0"
jobs:
test:
@@ -26,15 +26,20 @@ jobs:
matrix:
os:
- ubuntu-latest
- ubuntu-22.04-arm
- ubuntu-24.04-arm
node_version:
- 24
- 20
- 18
steps:
-
name: Checkout
uses: actions/checkout@v5
-
name: Test
uses: docker/bake-action@v6
with:
source: .
targets: test-coverage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -64,7 +69,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Enable corepack
run: |
@@ -72,7 +77,7 @@ jobs:
yarn --version
-
name: Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
@@ -82,7 +87,7 @@ jobs:
-
name: Create includes
id: set
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
let tests = [];
@@ -101,19 +106,24 @@ jobs:
});
await core.group(`Set includes`, async () => {
let includes = [];
for (const os of ['ubuntu-latest', 'ubuntu-22.04-arm', 'macos-13', 'windows-latest']) {
for (const os of ['ubuntu-latest', 'ubuntu-24.04-arm', 'macos-15-intel', 'windows-latest']) {
for (const test of tests) {
if (test === 'docker/install.test.itg.ts') {
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'image', docker_install_version: '27.3.1' });
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'image', docker_install_version: 'master' });
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'image', docker_install_version: 'latest' });
if (os !== 'windows-latest') {
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'image', docker_install_version: '27.3.1' });
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'image', docker_install_version: 'master' });
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'image', docker_install_version: 'latest' });
}
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'archive', docker_install_version: 'v26.1.4' });
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'archive', docker_install_version: 'latest' });
includes.push({ os: os, test: test, test_name: 'root', docker_install_type: 'archive', docker_install_version: 'v29.0.0-rc.1', docker_install_channel: 'test' });
if (os === 'ubuntu-latest') {
includes.push({ os: os, test: test, test_name: 'rootless', docker_install_type: 'image', docker_install_version: 'latest' });
includes.push({ os: os, test: test, test_name: 'rootless', docker_install_type: 'archive', docker_install_version: 'latest' });
}
includes.push({ os: os, test: test, test_name: 'tcp', docker_install_type: 'image', docker_install_version: 'latest' });
if (os !== 'windows-latest') {
includes.push({ os: os, test: test, test_name: 'tcp', docker_install_type: 'image', docker_install_version: 'latest' });
}
includes.push({ os: os, test: test, test_name: 'tcp', docker_install_type: 'archive', docker_install_version: 'latest' });
} else {
includes.push({ os: os, test: test });
@@ -136,20 +146,24 @@ jobs:
fail-fast: false
matrix:
include: ${{ fromJson(needs.prepare-itg.outputs.includes) }}
permissions:
contents: read
id-token: write # needed for signing with GitHub OIDC Token
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Expose GitHub Runtime
uses: crazy-max/ghaction-github-runtime@v3
-
# FIXME: Needs to setup node twice on Windows due to a bug with runner
# FIXME: Needs to setup node twice on Windows: https://github.com/actions/setup-node/issues/1357#issuecomment-3254613964
name: Setup Node
if: startsWith(matrix.os, 'windows')
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
package-manager-cache: false
-
name: Enable corepack
run: |
@@ -157,7 +171,7 @@ jobs:
yarn --version
-
name: Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
@@ -182,7 +196,7 @@ jobs:
run: yarn install
-
name: Test
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const testName = `${{ matrix.test_name }}`;
@@ -198,6 +212,7 @@ jobs:
TEST_FOR_SUMMARY: ${{ secrets.TEST_FOR_SUMMARY }}
DOCKER_INSTALL_TYPE: ${{ matrix.docker_install_type }}
DOCKER_INSTALL_VERSION: ${{ matrix.docker_install_version }}
DOCKER_INSTALL_CHANNEL: ${{ matrix.docker_install_channel }}
-
name: Check coverage
run: |

View File

@@ -17,7 +17,7 @@ on:
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@7f83a5a887650a38e4d0e05d5262309cfaa31459
uses: crazy-max/.github/.github/workflows/releases-json.yml@34fd436075cac6431d2036d5f6f1c3f3d4687ac5
with:
repository: crazy-max/undock
artifact_name: undock-releases-json
@@ -25,17 +25,17 @@ jobs:
secrets: inherit
open-pr:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request'
needs:
- generate
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: undock-releases-json
path: .github
@@ -45,7 +45,7 @@ jobs:
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
base: main
branch: bot/undock-releases-json

View File

@@ -15,13 +15,13 @@ on:
jobs:
prepare:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
outputs:
targets: ${{ steps.generate.outputs.targets }}
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
-
name: List targets
id: generate

View File

@@ -23,7 +23,6 @@ jobs:
- ubuntu-latest
- ubuntu-24.04
- ubuntu-22.04
- ubuntu-20.04
- ubuntu-24.04-arm
- ubuntu-22.04-arm
steps:

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,9 @@
# https://yarnpkg.com/configuration/yarnrc
compressionLevel: mixed
enableGlobalCache: false
enableHardenedMode: true
logFilters:
- code: YN0013
level: discard
@@ -5,11 +11,9 @@ logFilters:
level: discard
- code: YN0076
level: discard
- code: YN0086
level: discard
nodeLinker: node-modules
npmAuthToken: "${NODE_AUTH_TOKEN:-fallback}"
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,96 @@
2025/10/31 13:57:03 --> GET https://index.docker.io/v2/
2025/10/31 13:57:03 GET /v2/ HTTP/1.1
Host: index.docker.io
User-Agent: cosign/v3.0.2 (linux; amd64) go-containerregistry/v0.20.6
Accept-Encoding: gzip
2025/10/31 13:57:03 <-- 401 https://index.docker.io/v2/ (191.948348ms)
2025/10/31 13:57:03 HTTP/2.0 401 Unauthorized
Content-Length: 87
Content-Type: application/json
Date: Fri, 31 Oct 2025 13:57:03 GMT
Docker-Distribution-Api-Version: registry/2.0
Strict-Transport-Security: max-age=31536000
Www-Authenticate: ***"https://auth.docker.io/token",service="registry.docker.io"
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":null}]}
2025/10/31 13:57:03 --> GET https://auth.docker.io/token?scope=repository%3Acrazymax%2Fgithub-builder-test%3Apull&service=registry.docker.io [body redacted: basic token response contains credentials]
2025/10/31 13:57:03 GET /token?scope=repository%3Acrazymax%2Fgithub-builder-test%3Apull&service=registry.docker.io HTTP/1.1
Host: auth.docker.io
User-Agent: cosign/v3.0.2 (linux; amd64) go-containerregistry/v0.20.6
Authorization: <redacted>
Accept-Encoding: gzip
2025/10/31 13:57:03 <-- 200 https://auth.docker.io/token?scope=repository%3Acrazymax%2Fgithub-builder-test%3Apull&service=registry.docker.io (180.01561ms) [body redacted: basic token response contains credentials]
2025/10/31 13:57:03 HTTP/2.0 200 OK
Connection: close
Content-Type: application/json
Date: Fri, 31 Oct 2025 13:57:03 GMT
Strict-Transport-Security: max-age=31536000
X-Trace-Id: 8d63fbce36baf5f2a0c5f2542efa7a7a
X-Trace-Sampled: false
2025/10/31 13:57:03 --> GET https://index.docker.io/v2/crazymax/github-builder-test/referrers/sha256:6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0
2025/10/31 13:57:03 GET /v2/crazymax/github-builder-test/referrers/sha256:6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0 HTTP/1.1
Host: index.docker.io
User-Agent: cosign/v3.0.2 (linux; amd64) go-containerregistry/v0.20.6
Accept: application/vnd.oci.image.index.v1+json
Authorization: <redacted>
Accept-Encoding: gzip
2025/10/31 13:57:03 <-- 200 https://index.docker.io/v2/crazymax/github-builder-test/referrers/sha256:6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0 (84.160823ms)
2025/10/31 13:57:03 HTTP/2.0 200 OK
Content-Length: 89
Content-Type: application/vnd.oci.image.index.v1+json
Date: Fri, 31 Oct 2025 13:57:03 GMT
Docker-Distribution-Api-Version: registry/2.0
Strict-Transport-Security: max-age=31536000
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[]}
2025/10/31 13:57:03 --> GET https://index.docker.io/v2/crazymax/github-builder-test/referrers/sha256:6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0
2025/10/31 13:57:03 GET /v2/crazymax/github-builder-test/referrers/sha256:6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0 HTTP/1.1
Host: index.docker.io
User-Agent: cosign/v3.0.2 (linux; amd64) go-containerregistry/v0.20.6
Accept: application/vnd.oci.image.index.v1+json
Authorization: <redacted>
Accept-Encoding: gzip
2025/10/31 13:57:03 <-- 200 https://index.docker.io/v2/crazymax/github-builder-test/referrers/sha256:6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0 (95.303988ms)
2025/10/31 13:57:03 HTTP/2.0 200 OK
Content-Length: 89
Content-Type: application/vnd.oci.image.index.v1+json
Date: Fri, 31 Oct 2025 13:57:03 GMT
Docker-Distribution-Api-Version: registry/2.0
Strict-Transport-Security: max-age=31536000
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[]}
2025/10/31 13:57:03 --> GET https://index.docker.io/v2/crazymax/github-builder-test/manifests/sha256-6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0.sig
2025/10/31 13:57:03 GET /v2/crazymax/github-builder-test/manifests/sha256-6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0.sig HTTP/1.1
Host: index.docker.io
User-Agent: cosign/v3.0.2 (linux; amd64) go-containerregistry/v0.20.6
Accept: application/vnd.docker.distribution.manifest.v1+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json
Authorization: <redacted>
Accept-Encoding: gzip
2025/10/31 13:57:03 <-- 404 https://index.docker.io/v2/crazymax/github-builder-test/manifests/sha256-6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0.sig (66.155995ms)
2025/10/31 13:57:03 HTTP/2.0 404 Not Found
Content-Length: 169
Content-Type: application/json
Date: Fri, 31 Oct 2025 13:57:03 GMT
Docker-Distribution-Api-Version: registry/2.0
Docker-Ratelimit-Source: d2fd3209-1e2e-451f-b428-29c5bbf3b4b7
Strict-Transport-Security: max-age=31536000
{"errors":[{"code":"MANIFEST_UNKNOWN","message":"manifest unknown","detail":"unknown tag=sha256-6cc021c733ae2760b2493f449d9885b1606002962b51a9c4f0d0d1568b6dc5c0.sig"}]}
Error: no signatures found
error during command execution: no signatures found

View File

@@ -0,0 +1,5 @@
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:dccc69dd895968c4f21aa9e43e715f25f0cedfce4b17f1014c88c307928e22fc",
"size": 1599
}

View File

@@ -0,0 +1,141 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"digest": "sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6",
"size": 4654,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:dccc69dd895968c4f21aa9e43e715f25f0cedfce4b17f1014c88c307928e22fc",
"size": 1599,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:1b6bce668653f08e2d0f9f7c9b646675b2cbce94ce8abdf4eb0eabaef4353045",
"size": 1599,
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v7"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:8f251fda6057e9dffc54f7874b249920f15f1813e9b1406a0cebeca5e4ab1ad9",
"size": 1599,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:d306cbc2d506547f136c8e0ea040b929743f298fb2813d9030efdb9d9eee4d51",
"size": 1599,
"platform": {
"architecture": "s390x",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:9d195ff2dc9ef347bb52ebb1c2a6e6587d4bd87019d2ea11df3e7046a3d19708",
"size": 1599,
"platform": {
"architecture": "ppc64le",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:72410c2c4529fca9339ebbcc8db2a1d5cb4d72d72c669f50b6d45d8a0f79fc22",
"size": 1599,
"platform": {
"architecture": "riscv64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:2ba4ad6eae1efcafee73a971953093c7c32b6938f2f9fd4998c8bf4d0fbe76f2",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:dccc69dd895968c4f21aa9e43e715f25f0cedfce4b17f1014c88c307928e22fc",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:0709528fae1747ce17638ad2978ee7936b38a294136eaadaf692e415f64b1e03",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:1b6bce668653f08e2d0f9f7c9b646675b2cbce94ce8abdf4eb0eabaef4353045",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:241b7159129d53923c89708bcc052b3398086a826519896be2f025545916e43e",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:8f251fda6057e9dffc54f7874b249920f15f1813e9b1406a0cebeca5e4ab1ad9",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:97f4a222a7992dba6dc1a43991d0cca1fcffdc25593033c6a3a7ff14c8651cbf",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:d306cbc2d506547f136c8e0ea040b929743f298fb2813d9030efdb9d9eee4d51",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:aa933713d8094b2708120e889acb6f7153dee4e0f3298ccd3e37a584cd0c260d",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:9d195ff2dc9ef347bb52ebb1c2a6e6587d4bd87019d2ea11df3e7046a3d19708",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:d95ca72d4f2a6bc416d4b2f3003b2af9d5f4dea99acec6ad3ab0c2082000a98c",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:72410c2c4529fca9339ebbcc8db2a1d5cb4d72d72c669f50b6d45d8a0f79fc22",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
}
]
}

View File

@@ -0,0 +1,80 @@
[
{
"mediaType":"application/vnd.oci.image.manifest.v1+json",
"digest":"sha256:2ba4ad6eae1efcafee73a971953093c7c32b6938f2f9fd4998c8bf4d0fbe76f2",
"size":1113,
"annotations":{
"vnd.docker.reference.digest":"sha256:dccc69dd895968c4f21aa9e43e715f25f0cedfce4b17f1014c88c307928e22fc",
"vnd.docker.reference.type":"attestation-manifest"
},
"platform":{
"architecture":"unknown",
"os":"unknown"
}
},
{
"mediaType":"application/vnd.oci.image.manifest.v1+json",
"digest":"sha256:0709528fae1747ce17638ad2978ee7936b38a294136eaadaf692e415f64b1e03",
"size":1113,
"annotations":{
"vnd.docker.reference.digest":"sha256:1b6bce668653f08e2d0f9f7c9b646675b2cbce94ce8abdf4eb0eabaef4353045",
"vnd.docker.reference.type":"attestation-manifest"
},
"platform":{
"architecture":"unknown",
"os":"unknown"
}
},
{
"mediaType":"application/vnd.oci.image.manifest.v1+json",
"digest":"sha256:241b7159129d53923c89708bcc052b3398086a826519896be2f025545916e43e",
"size":1113,
"annotations":{
"vnd.docker.reference.digest":"sha256:8f251fda6057e9dffc54f7874b249920f15f1813e9b1406a0cebeca5e4ab1ad9",
"vnd.docker.reference.type":"attestation-manifest"
},
"platform":{
"architecture":"unknown",
"os":"unknown"
}
},
{
"mediaType":"application/vnd.oci.image.manifest.v1+json",
"digest":"sha256:97f4a222a7992dba6dc1a43991d0cca1fcffdc25593033c6a3a7ff14c8651cbf",
"size":1113,
"annotations":{
"vnd.docker.reference.digest":"sha256:d306cbc2d506547f136c8e0ea040b929743f298fb2813d9030efdb9d9eee4d51",
"vnd.docker.reference.type":"attestation-manifest"
},
"platform":{
"architecture":"unknown",
"os":"unknown"
}
},
{
"mediaType":"application/vnd.oci.image.manifest.v1+json",
"digest":"sha256:aa933713d8094b2708120e889acb6f7153dee4e0f3298ccd3e37a584cd0c260d",
"size":1113,
"annotations":{
"vnd.docker.reference.digest":"sha256:9d195ff2dc9ef347bb52ebb1c2a6e6587d4bd87019d2ea11df3e7046a3d19708",
"vnd.docker.reference.type":"attestation-manifest"
},
"platform":{
"architecture":"unknown",
"os":"unknown"
}
},
{
"mediaType":"application/vnd.oci.image.manifest.v1+json",
"digest":"sha256:d95ca72d4f2a6bc416d4b2f3003b2af9d5f4dea99acec6ad3ab0c2082000a98c",
"size":1113,
"annotations":{
"vnd.docker.reference.digest":"sha256:72410c2c4529fca9339ebbcc8db2a1d5cb4d72d72c669f50b6d45d8a0f79fc22",
"vnd.docker.reference.type":"attestation-manifest"
},
"platform":{
"architecture":"unknown",
"os":"unknown"
}
}
]

View File

@@ -0,0 +1,55 @@
Name: nvidia
Driver: docker-container
Last Activity: 2025-02-14 15:57:45 +0000 UTC
Nodes:
Name: nvidia0
Endpoint: unix:///var/run/docker.sock
Driver Options: image="moby/buildkit:local"
Status: running
BuildKit daemon flags: --allow-insecure-entitlement=network.host
BuildKit version: v0.20.0-rc2-4-gd30d8e22c.m
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
Features:
Cache export: true
Docker exporter: true
Multi-platform build: true
OCI exporter: true
Labels:
org.mobyproject.buildkit.worker.executor: oci
org.mobyproject.buildkit.worker.hostname: 76ac9a510d96
org.mobyproject.buildkit.worker.network: host
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
org.mobyproject.buildkit.worker.selinux.enabled: false
org.mobyproject.buildkit.worker.snapshotter: overlayfs
Devices:
Name: nvidia.com/gpu=all
Automatically allowed: true
Annotations:
foo: bar
org.mobyproject.buildkit.device.autoallow: true
Name: docker.com/gpu=venus
Automatically allowed: false
Annotations:
bar: baz
GC Policy rule#0:
All: false
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
Keep Duration: 48h0m0s
Max Used Space: 488.3MiB
GC Policy rule#1:
All: false
Keep Duration: 1440h0m0s
Reserved Space: 9.313GiB
Max Used Space: 93.13GiB
Min Free Space: 188.1GiB
GC Policy rule#2:
All: false
Reserved Space: 9.313GiB
Max Used Space: 93.13GiB
Min Free Space: 188.1GiB
GC Policy rule#3:
All: true
Reserved Space: 9.313GiB
Max Used Space: 93.13GiB
Min Free Space: 188.1GiB

View File

@@ -0,0 +1 @@
Hello, World! This is linux/amd64

View File

@@ -0,0 +1,462 @@
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "hello.txt",
"digest": {
"sha256": "1b37929e66644beb58b3d28d44fba0d82aa90cab03c55a492adb81fe6e833ec8"
}
}
],
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-definitions.md",
"resolvedDependencies": [
{
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "e930c2697be77cb7271d316ecfa78768b5eac73de3b16018ed38eb0ea0b5a7cb"
}
},
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412"
}
},
{
"uri": "https://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"digest": {
"sha1": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
}
}
],
"externalParameters": {
"configSource": {
"uri": "https://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"digest": {
"sha1": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
},
"path": "hello.Dockerfile"
},
"request": {
"frontend": "dockerfile.v0",
"secrets": [
{
"id": "GIT_AUTH_HEADER",
"optional": true
},
{
"id": "GIT_AUTH_TOKEN",
"optional": true
}
]
}
},
"internalParameters": {
"buildConfig": {
"digestMapping": {
"sha256:23dcbc3cce701a8a9bbb1e33f2ea88304527a4a935c89c4564af698095463ac2": "step3",
"sha256:3192c1bd53f90cca959db778dcee30edc9a79f8cd3f9a2c54adc4606507fd3b6": "step0",
"sha256:7f1c9e959980ea3e2cf4af8ef97b6c3797a0926752b436bff11474e436defe7f": "step1",
"sha256:c8737331fb8e5f5bcb6b22320012d975057514982c788e63db13332a4219b984": "step2"
},
"llbDefinition": [
{
"id": "step0",
"op": {
"Op": {
"source": {
"identifier": "docker-image://docker.io/library/alpine:latest@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412"
}
},
"constraints": {},
"platform": {
"Architecture": "amd64",
"OS": "linux"
}
}
},
{
"id": "step1",
"inputs": [
"step0:0"
],
"op": {
"Op": {
"exec": {
"meta": {
"args": [
"/bin/sh",
"-c",
"echo \"Hello, World! This is ${TARGETPLATFORM}\" \u003e /hello.txt"
],
"cwd": "/",
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TARGETPLATFORM=linux/amd64"
],
"removeMountStubsRecursive": true
},
"mounts": [
{
"dest": "/"
}
]
}
},
"constraints": {},
"platform": {
"Architecture": "amd64",
"OS": "linux"
}
}
},
{
"id": "step2",
"inputs": [
"step1:0"
],
"op": {
"Op": {
"file": {
"actions": [
{
"Action": {
"copy": {
"allowEmptyWildcard": true,
"allowWildcard": true,
"createDestPath": true,
"dest": "/",
"dirCopyContents": true,
"followSymlink": true,
"mode": -1,
"src": "/hello.txt",
"timestamp": -1
}
},
"input": -1,
"output": 0,
"secondaryInput": 0
}
]
}
},
"constraints": {}
}
},
{
"id": "step3",
"inputs": [
"step2:0"
],
"op": {
"Op": {}
}
}
]
},
"builderPlatform": "linux/amd64",
"github_actor": "crazy-max",
"github_actor_id": "1951866",
"github_event_name": "workflow_dispatch",
"github_event_payload": {
"enterprise": {
"avatar_url": "https://avatars.githubusercontent.com/b/19176?v=4",
"created_at": "2022-12-30T23:53:17Z",
"description": null,
"html_url": "https://github.com/enterprises/docker",
"id": 19176,
"name": "Docker",
"node_id": "E_kgDNSug",
"slug": "docker",
"updated_at": "2025-10-20T20:39:05Z",
"website_url": null
},
"inputs": null,
"organization": {
"avatar_url": "https://avatars.githubusercontent.com/u/5429470?v=4",
"description": "Docker helps developers bring their ideas to life by conquering the complexity of app development.",
"events_url": "https://api.github.com/orgs/docker/events",
"hooks_url": "https://api.github.com/orgs/docker/hooks",
"id": 5429470,
"issues_url": "https://api.github.com/orgs/docker/issues",
"login": "docker",
"members_url": "https://api.github.com/orgs/docker/members{/member}",
"node_id": "MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=",
"public_members_url": "https://api.github.com/orgs/docker/public_members{/member}",
"repos_url": "https://api.github.com/orgs/docker/repos",
"url": "https://api.github.com/orgs/docker"
},
"ref": "refs/heads/main",
"repository": {
"allow_forking": true,
"archive_url": "https://api.github.com/repos/docker/github-builder-test/{archive_format}{/ref}",
"archived": false,
"assignees_url": "https://api.github.com/repos/docker/github-builder-test/assignees{/user}",
"blobs_url": "https://api.github.com/repos/docker/github-builder-test/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/docker/github-builder-test/branches{/branch}",
"clone_url": "https://github.com/docker/github-builder-test.git",
"collaborators_url": "https://api.github.com/repos/docker/github-builder-test/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/docker/github-builder-test/comments{/number}",
"commits_url": "https://api.github.com/repos/docker/github-builder-test/commits{/sha}",
"compare_url": "https://api.github.com/repos/docker/github-builder-test/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/docker/github-builder-test/contents/{+path}",
"contributors_url": "https://api.github.com/repos/docker/github-builder-test/contributors",
"created_at": "2025-08-19T08:08:29Z",
"custom_properties": {},
"default_branch": "main",
"deployments_url": "https://api.github.com/repos/docker/github-builder-test/deployments",
"description": "Test repo for https://github.com/docker/github-builder-experimental",
"disabled": false,
"downloads_url": "https://api.github.com/repos/docker/github-builder-test/downloads",
"events_url": "https://api.github.com/repos/docker/github-builder-test/events",
"fork": false,
"forks": 0,
"forks_count": 0,
"forks_url": "https://api.github.com/repos/docker/github-builder-test/forks",
"full_name": "docker/github-builder-test",
"git_commits_url": "https://api.github.com/repos/docker/github-builder-test/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/docker/github-builder-test/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/docker/github-builder-test/git/tags{/sha}",
"git_url": "git://github.com/docker/github-builder-test.git",
"has_discussions": false,
"has_downloads": true,
"has_issues": false,
"has_pages": false,
"has_projects": false,
"has_wiki": false,
"homepage": null,
"hooks_url": "https://api.github.com/repos/docker/github-builder-test/hooks",
"html_url": "https://github.com/docker/github-builder-test",
"id": 1040594287,
"is_template": false,
"issue_comment_url": "https://api.github.com/repos/docker/github-builder-test/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/docker/github-builder-test/issues/events{/number}",
"issues_url": "https://api.github.com/repos/docker/github-builder-test/issues{/number}",
"keys_url": "https://api.github.com/repos/docker/github-builder-test/keys{/key_id}",
"labels_url": "https://api.github.com/repos/docker/github-builder-test/labels{/name}",
"language": "Dockerfile",
"languages_url": "https://api.github.com/repos/docker/github-builder-test/languages",
"license": null,
"merges_url": "https://api.github.com/repos/docker/github-builder-test/merges",
"milestones_url": "https://api.github.com/repos/docker/github-builder-test/milestones{/number}",
"mirror_url": null,
"name": "github-builder-test",
"node_id": "R_kgDOPgY1bw",
"notifications_url": "https://api.github.com/repos/docker/github-builder-test/notifications{?since,all,participating}",
"open_issues": 0,
"open_issues_count": 0,
"owner": {
"avatar_url": "https://avatars.githubusercontent.com/u/5429470?v=4",
"events_url": "https://api.github.com/users/docker/events{/privacy}",
"followers_url": "https://api.github.com/users/docker/followers",
"following_url": "https://api.github.com/users/docker/following{/other_user}",
"gists_url": "https://api.github.com/users/docker/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/docker",
"id": 5429470,
"login": "docker",
"node_id": "MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=",
"organizations_url": "https://api.github.com/users/docker/orgs",
"received_events_url": "https://api.github.com/users/docker/received_events",
"repos_url": "https://api.github.com/users/docker/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/docker/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/docker/subscriptions",
"type": "Organization",
"url": "https://api.github.com/users/docker",
"user_view_type": "public"
},
"private": true,
"pulls_url": "https://api.github.com/repos/docker/github-builder-test/pulls{/number}",
"pushed_at": "2025-10-30T10:04:10Z",
"releases_url": "https://api.github.com/repos/docker/github-builder-test/releases{/id}",
"size": 25,
"ssh_url": "git@github.com:docker/github-builder-test.git",
"stargazers_count": 0,
"stargazers_url": "https://api.github.com/repos/docker/github-builder-test/stargazers",
"statuses_url": "https://api.github.com/repos/docker/github-builder-test/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/docker/github-builder-test/subscribers",
"subscription_url": "https://api.github.com/repos/docker/github-builder-test/subscription",
"svn_url": "https://github.com/docker/github-builder-test",
"tags_url": "https://api.github.com/repos/docker/github-builder-test/tags",
"teams_url": "https://api.github.com/repos/docker/github-builder-test/teams",
"topics": [],
"trees_url": "https://api.github.com/repos/docker/github-builder-test/git/trees{/sha}",
"updated_at": "2025-10-30T10:04:14Z",
"url": "https://api.github.com/repos/docker/github-builder-test",
"visibility": "internal",
"watchers": 0,
"watchers_count": 0,
"web_commit_signoff_required": false
},
"sender": {
"avatar_url": "https://avatars.githubusercontent.com/u/1951866?v=4",
"events_url": "https://api.github.com/users/crazy-max/events{/privacy}",
"followers_url": "https://api.github.com/users/crazy-max/followers",
"following_url": "https://api.github.com/users/crazy-max/following{/other_user}",
"gists_url": "https://api.github.com/users/crazy-max/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/crazy-max",
"id": 1951866,
"login": "crazy-max",
"node_id": "MDQ6VXNlcjE5NTE4NjY=",
"organizations_url": "https://api.github.com/users/crazy-max/orgs",
"received_events_url": "https://api.github.com/users/crazy-max/received_events",
"repos_url": "https://api.github.com/users/crazy-max/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/crazy-max/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/crazy-max/subscriptions",
"type": "User",
"url": "https://api.github.com/users/crazy-max",
"user_view_type": "public"
},
"workflow": ".github/workflows/ci.yml"
},
"github_job": "build",
"github_ref": "refs/heads/main",
"github_ref_name": "main",
"github_ref_protected": "false",
"github_ref_type": "branch",
"github_repository": "docker/github-builder-test",
"github_repository_id": "1040594287",
"github_repository_owner": "docker",
"github_repository_owner_id": "5429470",
"github_run_attempt": "1",
"github_run_id": "18937328894",
"github_run_number": "183",
"github_runner_arch": "X64",
"github_runner_environment": "github-hosted",
"github_runner_image_os": "ubuntu24",
"github_runner_image_version": "20250929.60.1",
"github_runner_name": "GitHub Actions 1002376925",
"github_runner_os": "Linux",
"github_runner_tracking_id": "github_7c0a7521-2999-41e5-af30-b7f0681f204f",
"github_server_url": "https://github.com",
"github_triggering_actor": "crazy-max",
"github_workflow": "ci",
"github_workflow_ref": "docker/github-builder-test/.github/workflows/ci.yml@refs/heads/main",
"github_workflow_sha": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
}
},
"runDetails": {
"builder": {
"id": "https://github.com/docker/github-builder-test/actions/runs/18937328894/attempts/1"
},
"metadata": {
"invocationID": "7qg2yuux3iklv02ktbmbtwgeb",
"startedOn": "2025-10-30T10:19:52.868710505Z",
"finishedOn": "2025-10-30T10:19:57.635810119Z",
"buildkit_metadata": {
"source": {
"locations": {
"step0": {
"locations": [
{
"ranges": [
{
"start": {
"line": 1
},
"end": {
"line": 1
}
}
]
}
]
},
"step1": {
"locations": [
{
"ranges": [
{
"start": {
"line": 3
},
"end": {
"line": 3
}
}
]
}
]
},
"step2": {
"locations": [
{
"ranges": [
{
"start": {
"line": 7
},
"end": {
"line": 7
}
}
]
}
]
}
},
"infos": [
{
"filename": "hello.Dockerfile",
"language": "Dockerfile",
"data": "RlJPTSBhbHBpbmUgQVMgYmFzZQpBUkcgVEFSR0VUUExBVEZPUk0KUlVOIGVjaG8gIkhlbGxvLCBXb3JsZCEgVGhpcyBpcyAke1RBUkdFVFBMQVRGT1JNfSIgPiAvaGVsbG8udHh0CkFSRyBCVUlMREtJVF9TQk9NX1NDQU5fU1RBR0U9dHJ1ZQoKRlJPTSBzY3JhdGNoCkNPUFkgLS1mcm9tPWJhc2UgL2hlbGxvLnR4dCAvCg==",
"llbDefinition": [
{
"id": "step0",
"op": {
"Op": {
"source": {
"identifier": "git://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"attrs": {
"git.authheadersecret": "GIT_AUTH_HEADER",
"git.authtokensecret": "GIT_AUTH_TOKEN",
"git.fullurl": "https://github.com/docker/github-builder-test.git"
}
}
},
"constraints": {}
}
},
{
"id": "step1",
"op": {
"Op": {}
},
"inputs": [
"step0:0"
]
}
],
"digestMapping": {
"sha256:47540f0959d81a7ff2fc9742b9ef0bb37d7eca99c13aa6df83b883d06e808ef2": "step0",
"sha256:96933c546ff00debd500304305864192fcb51d348e8c41b6a6e1569a051e66ed": "step1"
}
}
]
},
"layers": {
"step0:0": [
[
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:2d35ebdb57d9971fea0cac1582aa78935adf8058b2cc32db163c98822e5dfa1b",
"size": 3802452
}
]
]
}
},
"buildkit_completeness": {
"request": true,
"resolvedDependencies": true
}
}
}
}
}

View File

@@ -0,0 +1 @@
Hello, World! This is linux/arm64

View File

@@ -0,0 +1,462 @@
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "hello.txt",
"digest": {
"sha256": "870e0065e68cbdeacbf9cec21b598bb579b0ef55bc48b65b71509667edb570bd"
}
}
],
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-definitions.md",
"resolvedDependencies": [
{
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "e930c2697be77cb7271d316ecfa78768b5eac73de3b16018ed38eb0ea0b5a7cb"
}
},
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Farm64",
"digest": {
"sha256": "4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412"
}
},
{
"uri": "https://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"digest": {
"sha1": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
}
}
],
"externalParameters": {
"configSource": {
"uri": "https://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"digest": {
"sha1": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
},
"path": "hello.Dockerfile"
},
"request": {
"frontend": "dockerfile.v0",
"secrets": [
{
"id": "GIT_AUTH_HEADER",
"optional": true
},
{
"id": "GIT_AUTH_TOKEN",
"optional": true
}
]
}
},
"internalParameters": {
"buildConfig": {
"digestMapping": {
"sha256:69f88b22af1cbbe236f4b5d834dfe9c4adb9535c1c602f726fd90212c302a7da": "step0",
"sha256:98c0e3a8b1a38f5aa8db558b99aace8e7645a18b0e24d6807018146d21788ae2": "step2",
"sha256:a560219f1e0cfb232a9727b9bbf9d6735c0b2190f8e00364f844cfc82bd42479": "step1",
"sha256:c7edeef726371083a69f15a3565d6c62be55a91e820f251d9a965f8e36fe3e32": "step3"
},
"llbDefinition": [
{
"id": "step0",
"op": {
"Op": {
"source": {
"identifier": "docker-image://docker.io/library/alpine:latest@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412"
}
},
"constraints": {},
"platform": {
"Architecture": "arm64",
"OS": "linux"
}
}
},
{
"id": "step1",
"inputs": [
"step0:0"
],
"op": {
"Op": {
"exec": {
"meta": {
"args": [
"/bin/sh",
"-c",
"echo \"Hello, World! This is ${TARGETPLATFORM}\" \u003e /hello.txt"
],
"cwd": "/",
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TARGETPLATFORM=linux/arm64"
],
"removeMountStubsRecursive": true
},
"mounts": [
{
"dest": "/"
}
]
}
},
"constraints": {},
"platform": {
"Architecture": "arm64",
"OS": "linux"
}
}
},
{
"id": "step2",
"inputs": [
"step1:0"
],
"op": {
"Op": {
"file": {
"actions": [
{
"Action": {
"copy": {
"allowEmptyWildcard": true,
"allowWildcard": true,
"createDestPath": true,
"dest": "/",
"dirCopyContents": true,
"followSymlink": true,
"mode": -1,
"src": "/hello.txt",
"timestamp": -1
}
},
"input": -1,
"output": 0,
"secondaryInput": 0
}
]
}
},
"constraints": {}
}
},
{
"id": "step3",
"inputs": [
"step2:0"
],
"op": {
"Op": {}
}
}
]
},
"builderPlatform": "linux/amd64",
"github_actor": "crazy-max",
"github_actor_id": "1951866",
"github_event_name": "workflow_dispatch",
"github_event_payload": {
"enterprise": {
"avatar_url": "https://avatars.githubusercontent.com/b/19176?v=4",
"created_at": "2022-12-30T23:53:17Z",
"description": null,
"html_url": "https://github.com/enterprises/docker",
"id": 19176,
"name": "Docker",
"node_id": "E_kgDNSug",
"slug": "docker",
"updated_at": "2025-10-20T20:39:05Z",
"website_url": null
},
"inputs": null,
"organization": {
"avatar_url": "https://avatars.githubusercontent.com/u/5429470?v=4",
"description": "Docker helps developers bring their ideas to life by conquering the complexity of app development.",
"events_url": "https://api.github.com/orgs/docker/events",
"hooks_url": "https://api.github.com/orgs/docker/hooks",
"id": 5429470,
"issues_url": "https://api.github.com/orgs/docker/issues",
"login": "docker",
"members_url": "https://api.github.com/orgs/docker/members{/member}",
"node_id": "MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=",
"public_members_url": "https://api.github.com/orgs/docker/public_members{/member}",
"repos_url": "https://api.github.com/orgs/docker/repos",
"url": "https://api.github.com/orgs/docker"
},
"ref": "refs/heads/main",
"repository": {
"allow_forking": true,
"archive_url": "https://api.github.com/repos/docker/github-builder-test/{archive_format}{/ref}",
"archived": false,
"assignees_url": "https://api.github.com/repos/docker/github-builder-test/assignees{/user}",
"blobs_url": "https://api.github.com/repos/docker/github-builder-test/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/docker/github-builder-test/branches{/branch}",
"clone_url": "https://github.com/docker/github-builder-test.git",
"collaborators_url": "https://api.github.com/repos/docker/github-builder-test/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/docker/github-builder-test/comments{/number}",
"commits_url": "https://api.github.com/repos/docker/github-builder-test/commits{/sha}",
"compare_url": "https://api.github.com/repos/docker/github-builder-test/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/docker/github-builder-test/contents/{+path}",
"contributors_url": "https://api.github.com/repos/docker/github-builder-test/contributors",
"created_at": "2025-08-19T08:08:29Z",
"custom_properties": {},
"default_branch": "main",
"deployments_url": "https://api.github.com/repos/docker/github-builder-test/deployments",
"description": "Test repo for https://github.com/docker/github-builder-experimental",
"disabled": false,
"downloads_url": "https://api.github.com/repos/docker/github-builder-test/downloads",
"events_url": "https://api.github.com/repos/docker/github-builder-test/events",
"fork": false,
"forks": 0,
"forks_count": 0,
"forks_url": "https://api.github.com/repos/docker/github-builder-test/forks",
"full_name": "docker/github-builder-test",
"git_commits_url": "https://api.github.com/repos/docker/github-builder-test/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/docker/github-builder-test/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/docker/github-builder-test/git/tags{/sha}",
"git_url": "git://github.com/docker/github-builder-test.git",
"has_discussions": false,
"has_downloads": true,
"has_issues": false,
"has_pages": false,
"has_projects": false,
"has_wiki": false,
"homepage": null,
"hooks_url": "https://api.github.com/repos/docker/github-builder-test/hooks",
"html_url": "https://github.com/docker/github-builder-test",
"id": 1040594287,
"is_template": false,
"issue_comment_url": "https://api.github.com/repos/docker/github-builder-test/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/docker/github-builder-test/issues/events{/number}",
"issues_url": "https://api.github.com/repos/docker/github-builder-test/issues{/number}",
"keys_url": "https://api.github.com/repos/docker/github-builder-test/keys{/key_id}",
"labels_url": "https://api.github.com/repos/docker/github-builder-test/labels{/name}",
"language": "Dockerfile",
"languages_url": "https://api.github.com/repos/docker/github-builder-test/languages",
"license": null,
"merges_url": "https://api.github.com/repos/docker/github-builder-test/merges",
"milestones_url": "https://api.github.com/repos/docker/github-builder-test/milestones{/number}",
"mirror_url": null,
"name": "github-builder-test",
"node_id": "R_kgDOPgY1bw",
"notifications_url": "https://api.github.com/repos/docker/github-builder-test/notifications{?since,all,participating}",
"open_issues": 0,
"open_issues_count": 0,
"owner": {
"avatar_url": "https://avatars.githubusercontent.com/u/5429470?v=4",
"events_url": "https://api.github.com/users/docker/events{/privacy}",
"followers_url": "https://api.github.com/users/docker/followers",
"following_url": "https://api.github.com/users/docker/following{/other_user}",
"gists_url": "https://api.github.com/users/docker/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/docker",
"id": 5429470,
"login": "docker",
"node_id": "MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=",
"organizations_url": "https://api.github.com/users/docker/orgs",
"received_events_url": "https://api.github.com/users/docker/received_events",
"repos_url": "https://api.github.com/users/docker/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/docker/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/docker/subscriptions",
"type": "Organization",
"url": "https://api.github.com/users/docker",
"user_view_type": "public"
},
"private": true,
"pulls_url": "https://api.github.com/repos/docker/github-builder-test/pulls{/number}",
"pushed_at": "2025-10-30T10:04:10Z",
"releases_url": "https://api.github.com/repos/docker/github-builder-test/releases{/id}",
"size": 25,
"ssh_url": "git@github.com:docker/github-builder-test.git",
"stargazers_count": 0,
"stargazers_url": "https://api.github.com/repos/docker/github-builder-test/stargazers",
"statuses_url": "https://api.github.com/repos/docker/github-builder-test/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/docker/github-builder-test/subscribers",
"subscription_url": "https://api.github.com/repos/docker/github-builder-test/subscription",
"svn_url": "https://github.com/docker/github-builder-test",
"tags_url": "https://api.github.com/repos/docker/github-builder-test/tags",
"teams_url": "https://api.github.com/repos/docker/github-builder-test/teams",
"topics": [],
"trees_url": "https://api.github.com/repos/docker/github-builder-test/git/trees{/sha}",
"updated_at": "2025-10-30T10:04:14Z",
"url": "https://api.github.com/repos/docker/github-builder-test",
"visibility": "internal",
"watchers": 0,
"watchers_count": 0,
"web_commit_signoff_required": false
},
"sender": {
"avatar_url": "https://avatars.githubusercontent.com/u/1951866?v=4",
"events_url": "https://api.github.com/users/crazy-max/events{/privacy}",
"followers_url": "https://api.github.com/users/crazy-max/followers",
"following_url": "https://api.github.com/users/crazy-max/following{/other_user}",
"gists_url": "https://api.github.com/users/crazy-max/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/crazy-max",
"id": 1951866,
"login": "crazy-max",
"node_id": "MDQ6VXNlcjE5NTE4NjY=",
"organizations_url": "https://api.github.com/users/crazy-max/orgs",
"received_events_url": "https://api.github.com/users/crazy-max/received_events",
"repos_url": "https://api.github.com/users/crazy-max/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/crazy-max/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/crazy-max/subscriptions",
"type": "User",
"url": "https://api.github.com/users/crazy-max",
"user_view_type": "public"
},
"workflow": ".github/workflows/ci.yml"
},
"github_job": "build",
"github_ref": "refs/heads/main",
"github_ref_name": "main",
"github_ref_protected": "false",
"github_ref_type": "branch",
"github_repository": "docker/github-builder-test",
"github_repository_id": "1040594287",
"github_repository_owner": "docker",
"github_repository_owner_id": "5429470",
"github_run_attempt": "1",
"github_run_id": "18937328894",
"github_run_number": "183",
"github_runner_arch": "X64",
"github_runner_environment": "github-hosted",
"github_runner_image_os": "ubuntu24",
"github_runner_image_version": "20250929.60.1",
"github_runner_name": "GitHub Actions 1002376925",
"github_runner_os": "Linux",
"github_runner_tracking_id": "github_7c0a7521-2999-41e5-af30-b7f0681f204f",
"github_server_url": "https://github.com",
"github_triggering_actor": "crazy-max",
"github_workflow": "ci",
"github_workflow_ref": "docker/github-builder-test/.github/workflows/ci.yml@refs/heads/main",
"github_workflow_sha": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
}
},
"runDetails": {
"builder": {
"id": "https://github.com/docker/github-builder-test/actions/runs/18937328894/attempts/1"
},
"metadata": {
"invocationID": "7qg2yuux3iklv02ktbmbtwgeb",
"startedOn": "2025-10-30T10:19:52.868710505Z",
"finishedOn": "2025-10-30T10:19:57.635810119Z",
"buildkit_metadata": {
"source": {
"locations": {
"step0": {
"locations": [
{
"ranges": [
{
"start": {
"line": 1
},
"end": {
"line": 1
}
}
]
}
]
},
"step1": {
"locations": [
{
"ranges": [
{
"start": {
"line": 3
},
"end": {
"line": 3
}
}
]
}
]
},
"step2": {
"locations": [
{
"ranges": [
{
"start": {
"line": 7
},
"end": {
"line": 7
}
}
]
}
]
}
},
"infos": [
{
"filename": "hello.Dockerfile",
"language": "Dockerfile",
"data": "RlJPTSBhbHBpbmUgQVMgYmFzZQpBUkcgVEFSR0VUUExBVEZPUk0KUlVOIGVjaG8gIkhlbGxvLCBXb3JsZCEgVGhpcyBpcyAke1RBUkdFVFBMQVRGT1JNfSIgPiAvaGVsbG8udHh0CkFSRyBCVUlMREtJVF9TQk9NX1NDQU5fU1RBR0U9dHJ1ZQoKRlJPTSBzY3JhdGNoCkNPUFkgLS1mcm9tPWJhc2UgL2hlbGxvLnR4dCAvCg==",
"llbDefinition": [
{
"id": "step0",
"op": {
"Op": {
"source": {
"identifier": "git://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"attrs": {
"git.authheadersecret": "GIT_AUTH_HEADER",
"git.authtokensecret": "GIT_AUTH_TOKEN",
"git.fullurl": "https://github.com/docker/github-builder-test.git"
}
}
},
"constraints": {}
}
},
{
"id": "step1",
"op": {
"Op": {}
},
"inputs": [
"step0:0"
]
}
],
"digestMapping": {
"sha256:47540f0959d81a7ff2fc9742b9ef0bb37d7eca99c13aa6df83b883d06e808ef2": "step0",
"sha256:96933c546ff00debd500304305864192fcb51d348e8c41b6a6e1569a051e66ed": "step1"
}
}
]
},
"layers": {
"step0:0": [
[
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:6b59a28fa20117e6048ad0616b8d8c901877ef15ff4c7f18db04e4f01f43bc39",
"size": 4138069
}
]
]
}
},
"buildkit_completeness": {
"request": true,
"resolvedDependencies": true
}
}
}
}
}

View File

@@ -0,0 +1 @@
Hello, World! This is linux/amd64

View File

@@ -0,0 +1,462 @@
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "hello.txt",
"digest": {
"sha256": "1b37929e66644beb58b3d28d44fba0d82aa90cab03c55a492adb81fe6e833ec8"
}
}
],
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-definitions.md",
"resolvedDependencies": [
{
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "e930c2697be77cb7271d316ecfa78768b5eac73de3b16018ed38eb0ea0b5a7cb"
}
},
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412"
}
},
{
"uri": "https://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"digest": {
"sha1": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
}
}
],
"externalParameters": {
"configSource": {
"uri": "https://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"digest": {
"sha1": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
},
"path": "hello.Dockerfile"
},
"request": {
"frontend": "dockerfile.v0",
"secrets": [
{
"id": "GIT_AUTH_HEADER",
"optional": true
},
{
"id": "GIT_AUTH_TOKEN",
"optional": true
}
]
}
},
"internalParameters": {
"buildConfig": {
"digestMapping": {
"sha256:23dcbc3cce701a8a9bbb1e33f2ea88304527a4a935c89c4564af698095463ac2": "step3",
"sha256:3192c1bd53f90cca959db778dcee30edc9a79f8cd3f9a2c54adc4606507fd3b6": "step0",
"sha256:7f1c9e959980ea3e2cf4af8ef97b6c3797a0926752b436bff11474e436defe7f": "step1",
"sha256:c8737331fb8e5f5bcb6b22320012d975057514982c788e63db13332a4219b984": "step2"
},
"llbDefinition": [
{
"id": "step0",
"op": {
"Op": {
"source": {
"identifier": "docker-image://docker.io/library/alpine:latest@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412"
}
},
"constraints": {},
"platform": {
"Architecture": "amd64",
"OS": "linux"
}
}
},
{
"id": "step1",
"inputs": [
"step0:0"
],
"op": {
"Op": {
"exec": {
"meta": {
"args": [
"/bin/sh",
"-c",
"echo \"Hello, World! This is ${TARGETPLATFORM}\" \u003e /hello.txt"
],
"cwd": "/",
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TARGETPLATFORM=linux/amd64"
],
"removeMountStubsRecursive": true
},
"mounts": [
{
"dest": "/"
}
]
}
},
"constraints": {},
"platform": {
"Architecture": "amd64",
"OS": "linux"
}
}
},
{
"id": "step2",
"inputs": [
"step1:0"
],
"op": {
"Op": {
"file": {
"actions": [
{
"Action": {
"copy": {
"allowEmptyWildcard": true,
"allowWildcard": true,
"createDestPath": true,
"dest": "/",
"dirCopyContents": true,
"followSymlink": true,
"mode": -1,
"src": "/hello.txt",
"timestamp": -1
}
},
"input": -1,
"output": 0,
"secondaryInput": 0
}
]
}
},
"constraints": {}
}
},
{
"id": "step3",
"inputs": [
"step2:0"
],
"op": {
"Op": {}
}
}
]
},
"builderPlatform": "linux/amd64",
"github_actor": "crazy-max",
"github_actor_id": "1951866",
"github_event_name": "workflow_dispatch",
"github_event_payload": {
"enterprise": {
"avatar_url": "https://avatars.githubusercontent.com/b/19176?v=4",
"created_at": "2022-12-30T23:53:17Z",
"description": null,
"html_url": "https://github.com/enterprises/docker",
"id": 19176,
"name": "Docker",
"node_id": "E_kgDNSug",
"slug": "docker",
"updated_at": "2025-10-20T20:39:05Z",
"website_url": null
},
"inputs": null,
"organization": {
"avatar_url": "https://avatars.githubusercontent.com/u/5429470?v=4",
"description": "Docker helps developers bring their ideas to life by conquering the complexity of app development.",
"events_url": "https://api.github.com/orgs/docker/events",
"hooks_url": "https://api.github.com/orgs/docker/hooks",
"id": 5429470,
"issues_url": "https://api.github.com/orgs/docker/issues",
"login": "docker",
"members_url": "https://api.github.com/orgs/docker/members{/member}",
"node_id": "MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=",
"public_members_url": "https://api.github.com/orgs/docker/public_members{/member}",
"repos_url": "https://api.github.com/orgs/docker/repos",
"url": "https://api.github.com/orgs/docker"
},
"ref": "refs/heads/main",
"repository": {
"allow_forking": true,
"archive_url": "https://api.github.com/repos/docker/github-builder-test/{archive_format}{/ref}",
"archived": false,
"assignees_url": "https://api.github.com/repos/docker/github-builder-test/assignees{/user}",
"blobs_url": "https://api.github.com/repos/docker/github-builder-test/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/docker/github-builder-test/branches{/branch}",
"clone_url": "https://github.com/docker/github-builder-test.git",
"collaborators_url": "https://api.github.com/repos/docker/github-builder-test/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/docker/github-builder-test/comments{/number}",
"commits_url": "https://api.github.com/repos/docker/github-builder-test/commits{/sha}",
"compare_url": "https://api.github.com/repos/docker/github-builder-test/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/docker/github-builder-test/contents/{+path}",
"contributors_url": "https://api.github.com/repos/docker/github-builder-test/contributors",
"created_at": "2025-08-19T08:08:29Z",
"custom_properties": {},
"default_branch": "main",
"deployments_url": "https://api.github.com/repos/docker/github-builder-test/deployments",
"description": "Test repo for https://github.com/docker/github-builder-experimental",
"disabled": false,
"downloads_url": "https://api.github.com/repos/docker/github-builder-test/downloads",
"events_url": "https://api.github.com/repos/docker/github-builder-test/events",
"fork": false,
"forks": 0,
"forks_count": 0,
"forks_url": "https://api.github.com/repos/docker/github-builder-test/forks",
"full_name": "docker/github-builder-test",
"git_commits_url": "https://api.github.com/repos/docker/github-builder-test/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/docker/github-builder-test/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/docker/github-builder-test/git/tags{/sha}",
"git_url": "git://github.com/docker/github-builder-test.git",
"has_discussions": false,
"has_downloads": true,
"has_issues": false,
"has_pages": false,
"has_projects": false,
"has_wiki": false,
"homepage": null,
"hooks_url": "https://api.github.com/repos/docker/github-builder-test/hooks",
"html_url": "https://github.com/docker/github-builder-test",
"id": 1040594287,
"is_template": false,
"issue_comment_url": "https://api.github.com/repos/docker/github-builder-test/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/docker/github-builder-test/issues/events{/number}",
"issues_url": "https://api.github.com/repos/docker/github-builder-test/issues{/number}",
"keys_url": "https://api.github.com/repos/docker/github-builder-test/keys{/key_id}",
"labels_url": "https://api.github.com/repos/docker/github-builder-test/labels{/name}",
"language": "Dockerfile",
"languages_url": "https://api.github.com/repos/docker/github-builder-test/languages",
"license": null,
"merges_url": "https://api.github.com/repos/docker/github-builder-test/merges",
"milestones_url": "https://api.github.com/repos/docker/github-builder-test/milestones{/number}",
"mirror_url": null,
"name": "github-builder-test",
"node_id": "R_kgDOPgY1bw",
"notifications_url": "https://api.github.com/repos/docker/github-builder-test/notifications{?since,all,participating}",
"open_issues": 0,
"open_issues_count": 0,
"owner": {
"avatar_url": "https://avatars.githubusercontent.com/u/5429470?v=4",
"events_url": "https://api.github.com/users/docker/events{/privacy}",
"followers_url": "https://api.github.com/users/docker/followers",
"following_url": "https://api.github.com/users/docker/following{/other_user}",
"gists_url": "https://api.github.com/users/docker/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/docker",
"id": 5429470,
"login": "docker",
"node_id": "MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=",
"organizations_url": "https://api.github.com/users/docker/orgs",
"received_events_url": "https://api.github.com/users/docker/received_events",
"repos_url": "https://api.github.com/users/docker/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/docker/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/docker/subscriptions",
"type": "Organization",
"url": "https://api.github.com/users/docker",
"user_view_type": "public"
},
"private": true,
"pulls_url": "https://api.github.com/repos/docker/github-builder-test/pulls{/number}",
"pushed_at": "2025-10-30T10:04:10Z",
"releases_url": "https://api.github.com/repos/docker/github-builder-test/releases{/id}",
"size": 25,
"ssh_url": "git@github.com:docker/github-builder-test.git",
"stargazers_count": 0,
"stargazers_url": "https://api.github.com/repos/docker/github-builder-test/stargazers",
"statuses_url": "https://api.github.com/repos/docker/github-builder-test/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/docker/github-builder-test/subscribers",
"subscription_url": "https://api.github.com/repos/docker/github-builder-test/subscription",
"svn_url": "https://github.com/docker/github-builder-test",
"tags_url": "https://api.github.com/repos/docker/github-builder-test/tags",
"teams_url": "https://api.github.com/repos/docker/github-builder-test/teams",
"topics": [],
"trees_url": "https://api.github.com/repos/docker/github-builder-test/git/trees{/sha}",
"updated_at": "2025-10-30T10:04:14Z",
"url": "https://api.github.com/repos/docker/github-builder-test",
"visibility": "internal",
"watchers": 0,
"watchers_count": 0,
"web_commit_signoff_required": false
},
"sender": {
"avatar_url": "https://avatars.githubusercontent.com/u/1951866?v=4",
"events_url": "https://api.github.com/users/crazy-max/events{/privacy}",
"followers_url": "https://api.github.com/users/crazy-max/followers",
"following_url": "https://api.github.com/users/crazy-max/following{/other_user}",
"gists_url": "https://api.github.com/users/crazy-max/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/crazy-max",
"id": 1951866,
"login": "crazy-max",
"node_id": "MDQ6VXNlcjE5NTE4NjY=",
"organizations_url": "https://api.github.com/users/crazy-max/orgs",
"received_events_url": "https://api.github.com/users/crazy-max/received_events",
"repos_url": "https://api.github.com/users/crazy-max/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/crazy-max/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/crazy-max/subscriptions",
"type": "User",
"url": "https://api.github.com/users/crazy-max",
"user_view_type": "public"
},
"workflow": ".github/workflows/ci.yml"
},
"github_job": "build",
"github_ref": "refs/heads/main",
"github_ref_name": "main",
"github_ref_protected": "false",
"github_ref_type": "branch",
"github_repository": "docker/github-builder-test",
"github_repository_id": "1040594287",
"github_repository_owner": "docker",
"github_repository_owner_id": "5429470",
"github_run_attempt": "1",
"github_run_id": "18937328894",
"github_run_number": "183",
"github_runner_arch": "X64",
"github_runner_environment": "github-hosted",
"github_runner_image_os": "ubuntu24",
"github_runner_image_version": "20250929.60.1",
"github_runner_name": "GitHub Actions 1002376925",
"github_runner_os": "Linux",
"github_runner_tracking_id": "github_7c0a7521-2999-41e5-af30-b7f0681f204f",
"github_server_url": "https://github.com",
"github_triggering_actor": "crazy-max",
"github_workflow": "ci",
"github_workflow_ref": "docker/github-builder-test/.github/workflows/ci.yml@refs/heads/main",
"github_workflow_sha": "bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe"
}
},
"runDetails": {
"builder": {
"id": "https://github.com/docker/github-builder-test/actions/runs/18937328894/attempts/1"
},
"metadata": {
"invocationID": "7qg2yuux3iklv02ktbmbtwgeb",
"startedOn": "2025-10-30T10:19:52.868710505Z",
"finishedOn": "2025-10-30T10:19:57.635810119Z",
"buildkit_metadata": {
"source": {
"locations": {
"step0": {
"locations": [
{
"ranges": [
{
"start": {
"line": 1
},
"end": {
"line": 1
}
}
]
}
]
},
"step1": {
"locations": [
{
"ranges": [
{
"start": {
"line": 3
},
"end": {
"line": 3
}
}
]
}
]
},
"step2": {
"locations": [
{
"ranges": [
{
"start": {
"line": 7
},
"end": {
"line": 7
}
}
]
}
]
}
},
"infos": [
{
"filename": "hello.Dockerfile",
"language": "Dockerfile",
"data": "RlJPTSBhbHBpbmUgQVMgYmFzZQpBUkcgVEFSR0VUUExBVEZPUk0KUlVOIGVjaG8gIkhlbGxvLCBXb3JsZCEgVGhpcyBpcyAke1RBUkdFVFBMQVRGT1JNfSIgPiAvaGVsbG8udHh0CkFSRyBCVUlMREtJVF9TQk9NX1NDQU5fU1RBR0U9dHJ1ZQoKRlJPTSBzY3JhdGNoCkNPUFkgLS1mcm9tPWJhc2UgL2hlbGxvLnR4dCAvCg==",
"llbDefinition": [
{
"id": "step0",
"op": {
"Op": {
"source": {
"identifier": "git://github.com/docker/github-builder-test.git#bdb96fcfe8cc9e3a54800bc2537a4d4a14f0c5fe",
"attrs": {
"git.authheadersecret": "GIT_AUTH_HEADER",
"git.authtokensecret": "GIT_AUTH_TOKEN",
"git.fullurl": "https://github.com/docker/github-builder-test.git"
}
}
},
"constraints": {}
}
},
{
"id": "step1",
"op": {
"Op": {}
},
"inputs": [
"step0:0"
]
}
],
"digestMapping": {
"sha256:47540f0959d81a7ff2fc9742b9ef0bb37d7eca99c13aa6df83b883d06e808ef2": "step0",
"sha256:96933c546ff00debd500304305864192fcb51d348e8c41b6a6e1569a051e66ed": "step1"
}
}
]
},
"layers": {
"step0:0": [
[
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:2d35ebdb57d9971fea0cac1582aa78935adf8058b2cc32db163c98822e5dfa1b",
"size": 3802452
}
]
]
}
},
"buildkit_completeness": {
"request": true,
"resolvedDependencies": true
}
}
}
}
}

View File

@@ -466,6 +466,89 @@ baz = qux
]
}
],
[
'inspect12.txt',
{
"name": "nvidia",
"driver": "docker-container",
"lastActivity": new Date("2025-02-14T15:57:45.000Z"),
"nodes": [
{
"buildkit": "v0.20.0-rc2-4-gd30d8e22c.m",
"buildkitd-flags": "--allow-insecure-entitlement=network.host",
"driver-opts": [
"image=moby/buildkit:local",
],
"endpoint": "unix:///var/run/docker.sock",
"name": "nvidia0",
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6",
"status": "running",
"features": {
"Cache export": true,
"Docker exporter": true,
"Multi-platform build": true,
"OCI exporter": true,
},
"labels": {
"org.mobyproject.buildkit.worker.executor": "oci",
"org.mobyproject.buildkit.worker.hostname": "76ac9a510d96",
"org.mobyproject.buildkit.worker.network": "host",
"org.mobyproject.buildkit.worker.oci.process-mode": "sandbox",
"org.mobyproject.buildkit.worker.selinux.enabled": "false",
"org.mobyproject.buildkit.worker.snapshotter": "overlayfs",
},
"devices": [
{
"annotations": {
"foo": "bar",
"org.mobyproject.buildkit.device.autoallow": "true"
},
"autoAllow": true,
"name": "nvidia.com/gpu=all"
},
{
"annotations": {
"bar": "baz"
},
"autoAllow": false,
"name": "docker.com/gpu=venus"
}
],
"gcPolicy": [
{
"all": false,
"filter": [
"type==source.local",
"type==exec.cachemount",
"type==source.git.checkout"
],
"keepDuration": "48h0m0s",
"maxUsedSpace": "488.3MiB",
},
{
"all": false,
"keepDuration": "1440h0m0s",
"maxUsedSpace": "93.13GiB",
"minFreeSpace": "188.1GiB",
"reservedSpace": "9.313GiB",
},
{
"all": false,
"maxUsedSpace": "93.13GiB",
"minFreeSpace": "188.1GiB",
"reservedSpace": "9.313GiB",
},
{
"all": true,
"maxUsedSpace": "93.13GiB",
"minFreeSpace": "188.1GiB",
"reservedSpace": "9.313GiB",
}
]
}
]
}
],
])('given %p', async (inspectFile, expected) => {
expect(await Builder.parseInspect(fs.readFileSync(path.join(fixturesDir, inspectFile)).toString())).toEqual(expected);
});

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
import {afterEach, beforeEach, describe, expect, it, jest, test} from '@jest/globals';
import {describe, expect, it, test} from '@jest/globals';
import fs from 'fs';
import os from 'os';
import path from 'path';
@@ -30,7 +30,49 @@ const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'buildx
const maybe = !process.env.GITHUB_ACTIONS || (process.env.GITHUB_ACTIONS === 'true' && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) ? describe : describe.skip;
maybe('exportBuild', () => {
maybe('inspect', () => {
it('build', async () => {
const buildx = new Buildx();
const build = new Build({buildx: buildx});
fs.mkdirSync(tmpDir, {recursive: true});
await expect(
(async () => {
// prettier-ignore
const buildCmd = await buildx.getCommand([
'--builder', process.env.CTN_BUILDER_NAME ?? 'default',
'build', '-f', path.join(fixturesDir, 'hello.Dockerfile'),
'--metadata-file', build.getMetadataFilePath(),
fixturesDir
]);
await Exec.exec(buildCmd.command, buildCmd.args);
})()
).resolves.not.toThrow();
const metadata = build.resolveMetadata();
expect(metadata).toBeDefined();
const buildRef = build.resolveRef(metadata);
if (!buildRef) {
throw new Error('buildRef is undefined');
}
const [builderName, nodeName, ref] = buildRef.split('/');
expect(builderName).toBeDefined();
expect(nodeName).toBeDefined();
expect(ref).toBeDefined();
const history = new History({buildx: buildx});
const res = await history.inspect({
ref: ref,
builder: builderName
});
expect(res).toBeDefined();
expect(res?.Name).toBeDefined();
expect(res?.Ref).toBeDefined();
});
});
maybe('export', () => {
// prettier-ignore
test.each([
[
@@ -50,7 +92,7 @@ maybe('exportBuild', () => {
fixturesDir
],
]
])('export build %p', async (_, bargs) => {
])('export with build %p', async (_, bargs) => {
const buildx = new Buildx();
const build = new Build({buildx: buildx});
@@ -110,7 +152,7 @@ maybe('exportBuild', () => {
'hello-matrix'
],
]
])('export bake build %p', async (_, bargs) => {
])('export with bake %p', async (_, bargs) => {
const buildx = new Buildx();
const bake = new Bake({buildx: buildx});
@@ -145,22 +187,8 @@ maybe('exportBuild', () => {
expect(fs.existsSync(exportRes?.dockerbuildFilename)).toBe(true);
expect(exportRes?.summaries).toBeDefined();
});
});
maybe('exportBuild custom image', () => {
const originalEnv = process.env;
beforeEach(() => {
jest.resetModules();
process.env = {
...originalEnv,
DOCKER_BUILD_EXPORT_BUILD_IMAGE: 'docker.io/dockereng/export-build:0.2.2'
};
});
afterEach(() => {
process.env = originalEnv;
});
it('with custom image', async () => {
it('export using container', async () => {
const buildx = new Buildx();
const build = new Build({buildx: buildx});
@@ -185,7 +213,8 @@ maybe('exportBuild custom image', () => {
const history = new History({buildx: buildx});
const exportRes = await history.export({
refs: [buildRef ?? '']
refs: [buildRef ?? ''],
useContainer: true
});
expect(exportRes).toBeDefined();

View File

@@ -19,7 +19,10 @@ import * as fs from 'fs';
import * as path from 'path';
import {ImageTools} from '../../src/buildx/imagetools';
import {Manifest as ImageToolsManifest} from '../../src/types/buildx/imagetools';
import {Image} from '../../src/types/oci/config';
import {Descriptor} from '../../src/types/oci/descriptor';
const fixturesDir = path.join(__dirname, '..', '.fixtures');
@@ -37,3 +40,39 @@ maybe('inspectImage', () => {
expect(image).toEqual(expectedImage);
});
});
maybe('inspectManifest', () => {
it('inspect descriptor', async () => {
const manifest = await new ImageTools().inspectManifest('moby/buildkit:latest@sha256:dccc69dd895968c4f21aa9e43e715f25f0cedfce4b17f1014c88c307928e22fc');
const expectedManifest = <Descriptor>JSON.parse(fs.readFileSync(path.join(fixturesDir, 'imagetools-03.json'), {encoding: 'utf-8'}).trim());
expect(manifest).toEqual(expectedManifest);
});
it('inspect index', async () => {
const manifest = await new ImageTools().inspectManifest('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6');
const expectedManifest = <ImageToolsManifest>JSON.parse(fs.readFileSync(path.join(fixturesDir, 'imagetools-04.json'), {encoding: 'utf-8'}).trim());
expect(manifest).toEqual(expectedManifest);
});
});
maybe('attestationDescriptors', () => {
it('returns buildkit attestations descriptors', async () => {
const attestations = await new ImageTools().attestationDescriptors('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6');
const expectedAttestations = <Array<Descriptor>>JSON.parse(fs.readFileSync(path.join(fixturesDir, 'imagetools-05.json'), {encoding: 'utf-8'}).trim());
expect(attestations).toEqual(expectedAttestations);
});
});
maybe('attestationDigests', () => {
it('returns buildkit attestations digests', async () => {
const digests = await new ImageTools().attestationDigests('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6');
// prettier-ignore
expect(digests).toEqual([
'sha256:2ba4ad6eae1efcafee73a971953093c7c32b6938f2f9fd4998c8bf4d0fbe76f2',
'sha256:0709528fae1747ce17638ad2978ee7936b38a294136eaadaf692e415f64b1e03',
'sha256:241b7159129d53923c89708bcc052b3398086a826519896be2f025545916e43e',
'sha256:97f4a222a7992dba6dc1a43991d0cca1fcffdc25593033c6a3a7ff14c8651cbf',
'sha256:aa933713d8094b2708120e889acb6f7153dee4e0f3298ccd3e37a584cd0c260d',
'sha256:d95ca72d4f2a6bc416d4b2f3003b2af9d5f4dea99acec6ad3ab0c2082000a98c'
]);
});
});

View File

@@ -37,19 +37,17 @@ describe('download', () => {
['latest', true]
])(
'acquires %p of buildx (standalone: %p)', async (version, standalone) => {
const install = new Install({standalone: standalone});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
let buildxBin: string;
if (standalone) {
buildxBin = await install.installStandalone(toolPath, tmpDir);
} else {
buildxBin = await install.installPlugin(toolPath, tmpDir);
}
expect(fs.existsSync(buildxBin)).toBe(true);
},
100000
);
const install = new Install({standalone: standalone});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
let buildxBin: string;
if (standalone) {
buildxBin = await install.installStandalone(toolPath, tmpDir);
} else {
buildxBin = await install.installPlugin(toolPath, tmpDir);
}
expect(fs.existsSync(buildxBin)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
@@ -57,26 +55,22 @@ describe('download', () => {
['v0.9.0'],
['v0.10.5'],
])(
'acquires %p of buildx with cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
},
100000
);
'acquires %p of buildx with cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
['v0.11.2'],
['v0.12.0'],
])(
'acquires %p of buildx without cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);
},
100000
);
'acquires %p of buildx without cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);
}, 100000);
// TODO: add tests for arm
// prettier-ignore
@@ -90,15 +84,13 @@ describe('download', () => {
['linux', 'ppc64'],
['linux', 's390x'],
])(
'acquires buildx for %s/%s', async (os, arch) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const install = new Install();
const buildxBin = await install.download('latest');
expect(fs.existsSync(buildxBin)).toBe(true);
},
100000
);
'acquires buildx for %s/%s', async (os, arch) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const install = new Install();
const buildxBin = await install.download('latest');
expect(fs.existsSync(buildxBin)).toBe(true);
}, 100000);
});
describe('build', () => {
@@ -127,7 +119,12 @@ describe('getDownloadVersion', () => {
expect(version.key).toEqual('official');
expect(version.version).toEqual('latest');
expect(version.downloadURL).toEqual('https://github.com/docker/buildx/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/buildx-releases.json'
});
});
it('returns official v0.10.1 download version', async () => {
@@ -135,7 +132,12 @@ describe('getDownloadVersion', () => {
expect(version.key).toEqual('official');
expect(version.version).toEqual('v0.10.1');
expect(version.downloadURL).toEqual('https://github.com/docker/buildx/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/buildx-releases.json'
});
});
it('returns cloud latest download version', async () => {
@@ -143,7 +145,12 @@ describe('getDownloadVersion', () => {
expect(version.key).toEqual('cloud');
expect(version.version).toEqual('latest');
expect(version.downloadURL).toEqual('https://github.com/docker/buildx-desktop/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/buildx-lab-releases.json'
});
});
it('returns cloud v0.11.2-desktop.2 download version', async () => {
@@ -151,7 +158,12 @@ describe('getDownloadVersion', () => {
expect(version.key).toEqual('cloud');
expect(version.version).toEqual('v0.11.2-desktop.2');
expect(version.downloadURL).toEqual('https://github.com/docker/buildx-desktop/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/buildx-lab-releases.json'
});
});
it('returns cloud for lab version', async () => {
@@ -159,7 +171,12 @@ describe('getDownloadVersion', () => {
expect(version.key).toEqual('cloud');
expect(version.version).toEqual('latest');
expect(version.downloadURL).toEqual('https://github.com/docker/buildx-desktop/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/buildx-lab-releases.json'
});
});
it('unknown repo', async () => {
@@ -195,6 +212,6 @@ describe('getRelease', () => {
it('unknown release', async () => {
const version = await Install.getDownloadVersion('foo');
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Buildx release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json'));
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Buildx release foo in releases JSON'));
});
});

View File

@@ -36,20 +36,18 @@ describe('download', () => {
['v2.32.4', true],
['latest', true]
])(
'acquires %p of compose (standalone: %p)', async (version, standalone) => {
const install = new Install({standalone: standalone});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
let composeBin: string;
if (standalone) {
composeBin = await install.installStandalone(toolPath, tmpDir);
} else {
composeBin = await install.installPlugin(toolPath, tmpDir);
}
expect(fs.existsSync(composeBin)).toBe(true);
},
100000
);
'acquires %p of compose (standalone: %p)', async (version, standalone) => {
const install = new Install({standalone: standalone});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
let composeBin: string;
if (standalone) {
composeBin = await install.installStandalone(toolPath, tmpDir);
} else {
composeBin = await install.installPlugin(toolPath, tmpDir);
}
expect(fs.existsSync(composeBin)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
@@ -57,26 +55,22 @@ describe('download', () => {
['v2.31.0'],
['v2.32.4'],
])(
'acquires %p of compose with cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
},
100000
);
'acquires %p of compose with cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
['v2.27.1'],
['v2.28.0'],
])(
'acquires %p of compose without cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);
},
100000
);
'acquires %p of compose without cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);
}, 100000);
// TODO: add tests for arm
// prettier-ignore
@@ -90,15 +84,13 @@ describe('download', () => {
['linux', 'ppc64'],
['linux', 's390x'],
])(
'acquires compose for %s/%s', async (os, arch) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const install = new Install();
const composeBin = await install.download('latest');
expect(fs.existsSync(composeBin)).toBe(true);
},
100000
);
'acquires compose for %s/%s', async (os, arch) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const install = new Install();
const composeBin = await install.download('latest');
expect(fs.existsSync(composeBin)).toBe(true);
}, 100000);
});
describe('getDownloadVersion', () => {
@@ -107,28 +99,48 @@ describe('getDownloadVersion', () => {
expect(version.key).toEqual('official');
expect(version.version).toEqual('latest');
expect(version.downloadURL).toEqual('https://github.com/docker/compose/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/compose-releases.json'
});
});
it('returns official v2.24.3 download version', async () => {
const version = await Install.getDownloadVersion('v2.24.3');
expect(version.key).toEqual('official');
expect(version.version).toEqual('v2.24.3');
expect(version.downloadURL).toEqual('https://github.com/docker/compose/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/compose-releases.json'
});
});
it('returns cloud latest download version', async () => {
const version = await Install.getDownloadVersion('cloud:latest');
expect(version.key).toEqual('cloud');
expect(version.version).toEqual('latest');
expect(version.downloadURL).toEqual('https://github.com/docker/compose-desktop/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-lab-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/compose-lab-releases.json'
});
});
it('returns cloud v2.27.1-desktop.1 download version', async () => {
const version = await Install.getDownloadVersion('cloud:v2.27.1-desktop.1');
expect(version.key).toEqual('cloud');
expect(version.version).toEqual('v2.27.1-desktop.1');
expect(version.downloadURL).toEqual('https://github.com/docker/compose-desktop/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-lab-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/compose-lab-releases.json'
});
});
it('unknown repo', async () => {
await expect(Install.getDownloadVersion('foo:bar')).rejects.toThrow(new Error('Cannot find compose version for foo:bar'));
@@ -160,6 +172,6 @@ describe('getRelease', () => {
});
it('unknown release', async () => {
const version = await Install.getDownloadVersion('foo');
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Compose release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json'));
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Compose release foo in releases JSON'));
});
});

View File

@@ -0,0 +1,90 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, it, jest, test} from '@jest/globals';
import fs from 'fs';
import path from 'path';
import * as semver from 'semver';
import {Exec} from '../../src/exec';
import {Cosign} from '../../src/cosign/cosign';
const fixturesDir = path.join(__dirname, '..', '.fixtures');
describe('isAvailable', () => {
it('checks Cosign is available', async () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
const cosign = new Cosign();
await cosign.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`cosign`, [], {
silent: true,
ignoreReturnCode: true
});
});
});
describe('printVersion', () => {
it('prints Cosign version', async () => {
const execSpy = jest.spyOn(Exec, 'exec');
const cosign = new Cosign();
await cosign.printVersion();
expect(execSpy).toHaveBeenCalledWith(`cosign`, ['version', '--json'], {
failOnStdErr: false
});
});
});
describe('version', () => {
it('valid', async () => {
const cosign = new Cosign();
expect(semver.valid(await cosign.version())).not.toBeUndefined();
});
});
describe('versionSatisfies', () => {
test.each([
['v0.4.1', '>=0.3.2', true],
['v0.8.0', '>0.6.0', true],
['v0.8.0', '<0.3.0', false]
])('given %p', async (version, range, expected) => {
const cosign = new Cosign();
expect(await cosign.versionSatisfies(range, version)).toBe(expected);
});
});
describe('parseCommandOutput', () => {
// prettier-ignore
test.each([
[path.join(fixturesDir, 'cosign', 'sign-output1.txt')],
[path.join(fixturesDir, 'cosign', 'sign-output2.txt')],
[path.join(fixturesDir, 'cosign', 'sign-output3.txt')],
])('parsing %p', async (fixturePath: string) => {
const signResult = Cosign.parseCommandOutput(fs.readFileSync(fixturePath, 'utf-8'));
expect(signResult).toBeDefined();
expect(signResult.bundle).toBeDefined();
});
// prettier-ignore
test.each([
[path.join(fixturesDir, 'cosign', 'verify-output-err1.txt')],
])('parsing %p', async (fixturePath: string) => {
const signResult = Cosign.parseCommandOutput(fs.readFileSync(fixturePath, 'utf-8'));
expect(signResult).toBeDefined();
expect(signResult.bundle).toBeUndefined();
expect(signResult.errors).toBeDefined();
});
});

View File

@@ -0,0 +1,50 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, it, test} from '@jest/globals';
import * as fs from 'fs';
import {Install} from '../../src/cosign/install';
const maybe = !process.env.GITHUB_ACTIONS || (process.env.GITHUB_ACTIONS === 'true' && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) ? describe : describe.skip;
describe('download', () => {
// prettier-ignore
test.each(['latest'])(
'install cosign %s', async (version) => {
await expect((async () => {
const install = new Install();
const toolPath = await install.download(version);
if (!fs.existsSync(toolPath)) {
throw new Error('toolPath does not exist');
}
const binPath = await install.install(toolPath);
if (!fs.existsSync(binPath)) {
throw new Error('binPath does not exist');
}
})()).resolves.not.toThrow();
}, 60000);
});
maybe('build', () => {
it.skip('builds refs/pull/4492/head', async () => {
const install = new Install();
const toolPath = await install.build('https://github.com/sigstore/cosign.git#refs/pull/4492/head');
expect(fs.existsSync(toolPath)).toBe(true);
const buildxBin = await install.install(toolPath);
expect(fs.existsSync(buildxBin)).toBe(true);
}, 500000);
});

View File

@@ -0,0 +1,132 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, it, jest, test, afterEach} from '@jest/globals';
import fs from 'fs';
import os from 'os';
import path from 'path';
import * as rimraf from 'rimraf';
import osm = require('os');
import {Install} from '../../src/cosign/install';
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'cosign-install-'));
afterEach(function () {
rimraf.sync(tmpDir);
});
describe('download', () => {
// prettier-ignore
test.each([
['v2.6.1'],
['v3.0.1'],
['latest']
])(
'acquires %p of cosign', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
const cosignBin = await install.install(toolPath, tmpDir);
expect(fs.existsSync(cosignBin)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
// following versions are already cached to htc from previous test cases
['v2.6.1'],
['v3.0.1'],
])(
'acquires %p of cosign with cache', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
['v2.5.3'],
['v2.6.0'],
])(
'acquires %p of cosign without cache', async (version) => {
const install = new Install();
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);
}, 100000);
// TODO: add tests for arm
// prettier-ignore
test.each([
['win32', 'x64'],
['darwin', 'x64'],
['darwin', 'arm64'],
['linux', 'x64'],
['linux', 'arm64']
])(
'acquires undock for %s/%s', async (os, arch) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const install = new Install();
const cosignBin = await install.download('latest');
expect(fs.existsSync(cosignBin)).toBe(true);
}, 100000);
});
describe('getDownloadVersion', () => {
it('returns latest download version', async () => {
const version = await Install.getDownloadVersion('latest');
expect(version.version).toEqual('latest');
expect(version.downloadURL).toEqual('https://github.com/sigstore/cosign/releases/download/v%s/%s');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/cosign-releases.json'
});
});
it('returns v3.0.2 download version', async () => {
const version = await Install.getDownloadVersion('v3.0.2');
expect(version.version).toEqual('v3.0.2');
expect(version.downloadURL).toEqual('https://github.com/sigstore/cosign/releases/download/v%s/%s');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/cosign-releases.json'
});
});
});
describe('getRelease', () => {
it('returns latest GitHub release', async () => {
const version = await Install.getDownloadVersion('latest');
const release = await Install.getRelease(version);
expect(release).not.toBeNull();
expect(release?.tag_name).not.toEqual('');
});
it('returns v3.0.2 GitHub release', async () => {
const version = await Install.getDownloadVersion('v3.0.2');
const release = await Install.getRelease(version);
expect(release).not.toBeNull();
expect(release?.id).toEqual(253720294);
expect(release?.tag_name).toEqual('v3.0.2');
expect(release?.html_url).toEqual('https://github.com/sigstore/cosign/releases/tag/v3.0.2');
});
it('unknown release', async () => {
const version = await Install.getDownloadVersion('foo');
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Cosign release foo in releases JSON'));
});
});

View File

@@ -14,17 +14,29 @@
* limitations under the License.
*/
import {describe, test, expect} from '@jest/globals';
import {beforeAll, describe, test, expect} from '@jest/globals';
import fs from 'fs';
import os from 'os';
import path from 'path';
import {Install, InstallSource, InstallSourceArchive, InstallSourceImage} from '../../src/docker/install';
import {Docker} from '../../src/docker/docker';
import {Install as RegclientInstall} from '../../src/regclient/install';
import {Install as UndockInstall} from '../../src/undock/install';
import {Exec} from '../../src/exec';
const tmpDir = () => fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'docker-install-itg-'));
beforeAll(async () => {
const undockInstall = new UndockInstall();
const undockBinPath = await undockInstall.download('v0.10.0', true);
await undockInstall.install(undockBinPath);
const regclientInstall = new RegclientInstall();
const regclientBinPath = await regclientInstall.download('v0.8.2', true);
await regclientInstall.install(regclientBinPath);
}, 100000);
describe('root', () => {
// prettier-ignore
test.each(getSources(true))(
@@ -133,11 +145,12 @@ async function ensureNoSystemContainerd() {
function getSources(root: boolean): Array<InstallSource> {
const dockerInstallType = process.env.DOCKER_INSTALL_TYPE;
const dockerInstallVersion = process.env.DOCKER_INSTALL_VERSION;
const dockerInstallChannel = process.env.DOCKER_INSTALL_CHANNEL || 'stable';
if (dockerInstallType && dockerInstallVersion) {
if (dockerInstallType === 'archive') {
// prettier-ignore
return [
{ type: dockerInstallType, version: dockerInstallVersion, channel: 'stable'} as InstallSourceArchive
{ type: dockerInstallType, version: dockerInstallVersion, channel: dockerInstallChannel} as InstallSourceArchive
];
} else {
// prettier-ignore
@@ -153,7 +166,8 @@ function getSources(root: boolean): Array<InstallSource> {
{type: 'image', tag: 'master'} as InstallSourceImage,
{type: 'image', tag: 'latest'} as InstallSourceImage,
{type: 'archive', version: 'v26.1.4', channel: 'stable'} as InstallSourceArchive,
{type: 'archive', version: 'latest', channel: 'stable'} as InstallSourceArchive
{type: 'archive', version: 'latest', channel: 'stable'} as InstallSourceArchive,
{type: 'archive', version: 'v29.0.0-rc.1', channel: 'test'} as InstallSourceArchive
];
} else {
// prettier-ignore

View File

@@ -51,6 +51,7 @@ describe('download', () => {
[archive('v20.10.22', 'stable'), 'linux'],
[archive('v20.10.22', 'stable'), 'darwin'],
[archive('v20.10.22', 'stable'), 'win32'],
[archive('v29.0.0-rc.1', 'test'), 'linux'],
[image('master'), 'linux'],
[image('master'), 'win32'],
@@ -63,7 +64,7 @@ describe('download', () => {
jest.spyOn(osm, 'arch').mockImplementation(() => 'x64');
const install = new Install({
source: source,
runDir: tmpDir,
runDir: tmpDir
});
const toolPath = await install.download();
expect(fs.existsSync(toolPath)).toBe(true);
@@ -77,7 +78,7 @@ describe('getRelease', () => {
expect(release?.tag_name).not.toEqual('');
});
it('returns v23.0.0 buildx GitHub release', async () => {
it('returns v23.0.0 docker GitHub release', async () => {
const release = await Install.getRelease('v23.0.0');
expect(release).not.toBeNull();
expect(release?.id).toEqual(91109643);
@@ -85,8 +86,16 @@ describe('getRelease', () => {
expect(release?.html_url).toEqual('https://github.com/moby/moby/releases/tag/v23.0.0');
});
it('returns v29.0.0-rc.1 docker GitHub release', async () => {
const release = await Install.getRelease('v29.0.0-rc.1');
expect(release).not.toBeNull();
expect(release?.id).toEqual(252020476);
expect(release?.tag_name).toEqual('docker-v29.0.0-rc.1');
expect(release?.html_url).toEqual('https://github.com/moby/moby/releases/tag/docker-v29.0.0-rc.1');
});
it('unknown release', async () => {
await expect(Install.getRelease('foo')).rejects.toThrow(new Error('Cannot find Docker release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/docker-releases.json'));
await expect(Install.getRelease('foo')).rejects.toThrow(new Error('Cannot find Docker release foo in releases JSON'));
});
});

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
import {describe, expect, jest, it, beforeEach, afterEach} from '@jest/globals';
import {describe, expect, jest, it, beforeEach, afterEach, test} from '@jest/globals';
import * as fs from 'fs';
import * as path from 'path';
import * as core from '@actions/core';
@@ -43,6 +43,29 @@ describe('context', () => {
});
});
describe('releases', () => {
// prettier-ignore
test.each([
['.github/buildx-lab-releases.json'],
['.github/buildx-releases.json'],
['.github/compose-lab-releases.json'],
['.github/compose-releases.json'],
['.github/docker-releases.json'],
['.github/regclient-releases.json'],
['.github/undock-releases.json'],
])('returns %p', async (path: string) => {
const github = new GitHub();
const releases = await github.releases('App', {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: path
});
expect(releases).toBeDefined();
expect(Object.keys(releases).length).toBeGreaterThan(0);
});
});
describe('serverURL', () => {
const originalEnv = process.env;
beforeEach(() => {

View File

@@ -0,0 +1,38 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, test} from '@jest/globals';
import * as fs from 'fs';
import {Install} from '../../src/regclient/install';
describe('download', () => {
// prettier-ignore
test.each(['latest'])(
'install regclient %s', async (version) => {
await expect((async () => {
const install = new Install();
const toolPath = await install.download(version);
if (!fs.existsSync(toolPath)) {
throw new Error('toolPath does not exist');
}
const binPath = await install.install(toolPath);
if (!fs.existsSync(binPath)) {
throw new Error('binPath does not exist');
}
})()).resolves.not.toThrow();
}, 60000);
});

View File

@@ -0,0 +1,130 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, it, jest, test, afterEach} from '@jest/globals';
import fs from 'fs';
import os from 'os';
import path from 'path';
import * as rimraf from 'rimraf';
import osm = require('os');
import {Install} from '../../src/regclient/install';
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'regclient-install-'));
afterEach(function () {
rimraf.sync(tmpDir);
});
describe('download', () => {
// prettier-ignore
test.each([
['v0.8.2'],
['latest']
])(
'acquires %p of regclient', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
const regclientBin = await install.install(toolPath, tmpDir);
expect(fs.existsSync(regclientBin)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
// following versions are already cached to htc from previous test cases
['v0.8.2'],
])(
'acquires %p of regclient with cache', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
['v0.8.1'],
])(
'acquires %p of regclient without cache', async (version) => {
const install = new Install();
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
['win32', 'x64'],
['darwin', 'x64'],
['darwin', 'arm64'],
['linux', 'x64'],
['linux', 'arm64'],
['linux', 'ppc64'],
['linux', 's390x'],
])(
'acquires regclient for %s/%s', async (os, arch) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const install = new Install();
const regclientBin = await install.download('latest');
expect(fs.existsSync(regclientBin)).toBe(true);
}, 100000);
});
describe('getDownloadVersion', () => {
it('returns latest download version', async () => {
const version = await Install.getDownloadVersion('latest');
expect(version.version).toEqual('latest');
expect(version.downloadURL).toEqual('https://github.com/regclient/regclient/releases/download/v%s/%s');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/regclient-releases.json'
});
});
it('returns v0.8.1 download version', async () => {
const version = await Install.getDownloadVersion('v0.8.1');
expect(version.version).toEqual('v0.8.1');
expect(version.downloadURL).toEqual('https://github.com/regclient/regclient/releases/download/v%s/%s');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/regclient-releases.json'
});
});
});
describe('getRelease', () => {
it('returns latest GitHub release', async () => {
const version = await Install.getDownloadVersion('latest');
const release = await Install.getRelease(version);
expect(release).not.toBeNull();
expect(release?.tag_name).not.toEqual('');
});
it('returns v0.8.1 GitHub release', async () => {
const version = await Install.getDownloadVersion('v0.8.1');
const release = await Install.getRelease(version);
expect(release).not.toBeNull();
expect(release?.id).toEqual(199719231);
expect(release?.tag_name).toEqual('v0.8.1');
expect(release?.html_url).toEqual('https://github.com/regclient/regclient/releases/tag/v0.8.1');
});
it('unknown release', async () => {
const version = await Install.getDownloadVersion('foo');
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find regclient release foo in releases JSON'));
});
});

View File

@@ -0,0 +1,123 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, it, jest, test} from '@jest/globals';
import * as semver from 'semver';
import {Exec} from '../../src/exec';
import {Regctl} from '../../src/regclient/regctl';
import {Image} from '../../src/types/oci/config';
describe('manifestGet', () => {
// prettier-ignore
test.each([
['moby/moby-bin:28.1.0-rc.2'],
['crazymax/diun:4.17.0'],
])('given %p', async image => {
const regctl = new Regctl();
const manifest = await regctl.manifestGet({
image: image,
});
expect(manifest).not.toBeNull();
expect(manifest?.config).toBeDefined();
expect(manifest?.config.digest).not.toEqual('');
expect(manifest?.layers).toBeDefined();
expect(manifest?.layers.length).toBeGreaterThan(0);
}, 100000);
});
describe('blobGet', () => {
// prettier-ignore
test.each([
['moby/moby-bin', 'sha256:234fccbd13fde0ba978a19f728cbdc67e29bc76247ac560822bb6ae5236c0bf0'],
['crazymax/diun', 'sha256:1e4881f66e0ec0f1710b837002107050bbbc0a231d8a42d7f422b56a139900bb'],
])('given %p', async (repo, digest) => {
const regctl = new Regctl();
const blob = await regctl.blobGet({
repository: repo,
digest: digest
});
expect(blob).toBeDefined();
}, 100000);
});
describe('image config', () => {
// prettier-ignore
test.each([
['moby/moby-bin:28.1.0-rc.2'],
['crazymax/diun:4.17.0'],
])('given %p', async image => {
const regctl = new Regctl();
const manifest = await regctl.manifestGet({
image: image,
});
expect(manifest).not.toBeNull();
expect(manifest?.config).toBeDefined();
expect(manifest?.config.digest).not.toEqual('');
const blob = await regctl.blobGet({
repository: image, // image works as well
digest: manifest?.config.digest
});
const imageConfig = <Image>JSON.parse(blob);
expect(imageConfig).not.toBeNull();
expect(imageConfig.config).toBeDefined();
expect(imageConfig?.config?.Labels).toBeDefined();
expect(Object.keys(imageConfig?.config?.Labels || {}).length).toBeGreaterThan(0);
}, 100000);
});
describe('isAvailable', () => {
it('checks regctl is available', async () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
const regctl = new Regctl();
await regctl.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`regctl`, [], {
silent: true,
ignoreReturnCode: true
});
});
});
describe('printVersion', () => {
it('prints regctl version', async () => {
const execSpy = jest.spyOn(Exec, 'exec');
const regctl = new Regctl();
await regctl.printVersion();
expect(execSpy).toHaveBeenCalledWith(`regctl`, ['version'], {
failOnStdErr: false
});
});
});
describe('version', () => {
it('valid', async () => {
const regctl = new Regctl();
expect(semver.valid(await regctl.version())).not.toBeUndefined();
});
});
describe('versionSatisfies', () => {
test.each([
['v0.8.2', '>=0.6.0', true],
['v0.8.0', '>0.6.0', true],
['v0.8.0', '<0.3.0', false]
])('given %p', async (version, range, expected) => {
const regctl = new Regctl();
expect(await regctl.versionSatisfies(range, version)).toBe(expected);
});
});

View File

@@ -0,0 +1,92 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, jest, it, beforeAll} from '@jest/globals';
import fs from 'fs';
import * as path from 'path';
import {Install as CosignInstall} from '../../src/cosign/install';
import {Sigstore} from '../../src/sigstore/sigstore';
const fixturesDir = path.join(__dirname, '..', '.fixtures');
const maybe = process.env.GITHUB_ACTIONS && process.env.GITHUB_ACTIONS === 'true' && process.env.ACTIONS_ID_TOKEN_REQUEST_URL && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu') ? describe : describe.skip;
// needs current GitHub repo info
jest.unmock('@actions/github');
beforeAll(async () => {
const cosignInstall = new CosignInstall();
const cosignBinPath = await cosignInstall.download('v3.0.2', true);
await cosignInstall.install(cosignBinPath);
}, 100000);
maybe('signProvenanceBlobs', () => {
it('single platform', async () => {
const sigstore = new Sigstore();
const results = await sigstore.signProvenanceBlobs({
localExportDir: path.join(fixturesDir, 'sigstore', 'single')
});
expect(Object.keys(results).length).toEqual(1);
const provenancePath = Object.keys(results)[0];
expect(provenancePath).toEqual(path.join(fixturesDir, 'sigstore', 'single', 'provenance.json'));
expect(fs.existsSync(results[provenancePath].bundlePath)).toBe(true);
expect(results[provenancePath].bundle).toBeDefined();
expect(results[provenancePath].certificate).toBeDefined();
expect(results[provenancePath].tlogID).toBeDefined();
expect(results[provenancePath].attestationID).not.toBeDefined();
console.log(provenancePath, JSON.stringify(results[provenancePath].bundle, null, 2));
});
it('multi-platform', async () => {
const sigstore = new Sigstore();
const results = await sigstore.signProvenanceBlobs({
localExportDir: path.join(fixturesDir, 'sigstore', 'multi')
});
expect(Object.keys(results).length).toEqual(2);
for (const [provenancePath, res] of Object.entries(results)) {
expect(provenancePath).toMatch(/linux_(amd64|arm64)\/provenance.json/);
expect(fs.existsSync(res.bundlePath)).toBe(true);
expect(res.bundle).toBeDefined();
expect(res.certificate).toBeDefined();
expect(res.tlogID).toBeDefined();
expect(res.attestationID).not.toBeDefined();
console.log(provenancePath, JSON.stringify(res.bundle, null, 2));
}
});
});
maybe('verifySignedArtifacts', () => {
it('sign and verify', async () => {
const sigstore = new Sigstore();
const signResults = await sigstore.signProvenanceBlobs({
localExportDir: path.join(fixturesDir, 'sigstore', 'multi')
});
expect(Object.keys(signResults).length).toEqual(2);
const verifyResults = await sigstore.verifySignedArtifacts(
{
certificateIdentityRegexp: `^https://github.com/docker/actions-toolkit/.github/workflows/test.yml.*$`
},
signResults
);
expect(Object.keys(verifyResults).length).toEqual(2);
for (const [artifactPath, res] of Object.entries(verifyResults)) {
expect(fs.existsSync(artifactPath)).toBe(true);
expect(res.bundlePath).toBeDefined();
expect(res.cosignArgs).toBeDefined();
}
});
});

View File

@@ -36,15 +36,13 @@ describe('download', () => {
['v0.7.0'],
['latest']
])(
'acquires %p of undock (standalone: %p)', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
const undockBin = await install.install(toolPath, tmpDir);
expect(fs.existsSync(undockBin)).toBe(true);
},
100000
);
'acquires %p of undock', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
const undockBin = await install.install(toolPath, tmpDir);
expect(fs.existsSync(undockBin)).toBe(true);
}, 100000);
// prettier-ignore
test.each([
@@ -56,7 +54,7 @@ describe('download', () => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
});
}, 100000);
// prettier-ignore
test.each([
@@ -67,7 +65,7 @@ describe('download', () => {
const install = new Install();
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);
});
}, 100000);
// TODO: add tests for arm
// prettier-ignore
@@ -82,14 +80,12 @@ describe('download', () => {
['linux', 's390x'],
])(
'acquires undock for %s/%s', async (os, arch) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const install = new Install();
const undockBin = await install.download('latest');
expect(fs.existsSync(undockBin)).toBe(true);
},
100000
);
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const install = new Install();
const undockBin = await install.download('latest');
expect(fs.existsSync(undockBin)).toBe(true);
}, 100000);
});
describe('getDownloadVersion', () => {
@@ -97,13 +93,23 @@ describe('getDownloadVersion', () => {
const version = await Install.getDownloadVersion('latest');
expect(version.version).toEqual('latest');
expect(version.downloadURL).toEqual('https://github.com/crazy-max/undock/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/undock-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/undock-releases.json'
});
});
it('returns v0.6.0 download version', async () => {
const version = await Install.getDownloadVersion('v0.6.0');
expect(version.version).toEqual('v0.6.0');
expect(version.downloadURL).toEqual('https://github.com/crazy-max/undock/releases/download/v%s/%s');
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/undock-releases.json');
expect(version.contentOpts).toEqual({
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/undock-releases.json'
});
});
});
@@ -124,6 +130,6 @@ describe('getRelease', () => {
});
it('unknown release', async () => {
const version = await Install.getDownloadVersion('foo');
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Undock release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/undock-releases.json'));
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Undock release foo in releases JSON'));
});
});

View File

@@ -0,0 +1,47 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {describe, expect, it} from '@jest/globals';
import fs from 'fs';
import os from 'os';
import {Undock} from '../../src/undock/undock';
import {Install as UndockInstall} from '../../src/undock/install';
describe('run', () => {
it('extracts moby/moby-bin:26.1.5', async () => {
const install = new UndockInstall();
const toolPath = await install.download('latest');
if (!fs.existsSync(toolPath)) {
throw new Error('toolPath does not exist');
}
const binPath = await install.install(toolPath);
if (!fs.existsSync(binPath)) {
throw new Error('binPath does not exist');
}
const undock = new Undock();
await expect(
(async () => {
// prettier-ignore
await undock.run({
source: 'docker/buildx-bin:0.23.0',
dist: os.tmpdir()
});
})()
).resolves.not.toThrow();
}, 500000);
});

View File

@@ -38,7 +38,7 @@ describe('run', () => {
});
})()
).resolves.not.toThrow();
}, 100000);
}, 500000);
});
describe('isAvailable', () => {

View File

@@ -469,6 +469,36 @@ describe('isPathRelativeTo', () => {
});
});
describe('formatDuration', () => {
it('formats 0 nanoseconds as "0s"', () => {
expect(Util.formatDuration(0)).toBe('0s');
});
it('formats only seconds', () => {
expect(Util.formatDuration(5e9)).toBe('5s');
expect(Util.formatDuration(59e9)).toBe('59s');
});
it('formats minutes and seconds', () => {
expect(Util.formatDuration(65e9)).toBe('1m5s');
expect(Util.formatDuration(600e9)).toBe('10m');
});
it('formats hours, minutes, and seconds', () => {
expect(Util.formatDuration(3661e9)).toBe('1h1m1s');
expect(Util.formatDuration(7322e9)).toBe('2h2m2s');
});
it('formats hours only', () => {
expect(Util.formatDuration(3 * 3600e9)).toBe('3h');
});
it('formats hours and minutes', () => {
expect(Util.formatDuration(3900e9)).toBe('1h5m');
});
it('formats minutes only', () => {
expect(Util.formatDuration(120e9)).toBe('2m');
});
it('rounds down partial seconds', () => {
expect(Util.formatDuration(1799999999)).toBe('1s');
});
});
// See: https://github.com/actions/toolkit/blob/a1b068ec31a042ff1e10a522d8fdf0b8869d53ca/packages/core/src/core.ts#L89
function getInputName(name: string): string {
return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;

View File

@@ -15,10 +15,12 @@
# limitations under the License.
ARG NODE_VERSION=20
ARG DOCKER_VERSION=27.2.1
ARG BUILDX_VERSION=0.21.1
ARG COMPOSE_VERSION=2.32.4
ARG UNDOCK_VERSION=0.8.0
ARG DOCKER_VERSION=28.3
ARG BUILDX_VERSION=0.29.1
ARG COMPOSE_VERSION=2.39.1
ARG UNDOCK_VERSION=0.10.0
ARG REGCTL_VERSION=v0.8.2
ARG COSIGN_VERSION=v3.0.2
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git
@@ -75,21 +77,25 @@ RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run lint
FROM docker:${DOCKER_VERSION} AS docker
FROM dockereng/cli-bin:${DOCKER_VERSION} AS docker
FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx
FROM docker/compose-bin:v${COMPOSE_VERSION} AS compose
FROM crazymax/undock:${UNDOCK_VERSION} AS undock
FROM ghcr.io/regclient/regctl:${REGCTL_VERSION} AS regctl
FROM ghcr.io/sigstore/cosign/cosign:${COSIGN_VERSION} AS cosign
FROM deps AS test
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
--mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
--mount=type=bind,from=docker,source=/docker,target=/usr/bin/docker \
--mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \
--mount=type=bind,from=buildx,source=/buildx,target=/usr/bin/buildx \
--mount=type=bind,from=compose,source=/docker-compose,target=/usr/libexec/docker/cli-plugins/docker-compose \
--mount=type=bind,from=compose,source=/docker-compose,target=/usr/bin/compose \
--mount=type=bind,from=undock,source=/usr/local/bin/undock,target=/usr/bin/undock \
--mount=type=bind,from=regctl,source=/regctl,target=/usr/bin/regctl \
--mount=type=bind,from=cosign,source=/ko-app/cosign,target=/usr/bin/cosign \
--mount=type=secret,id=GITHUB_TOKEN \
GITHUB_TOKEN=$(cat /run/secrets/GITHUB_TOKEN) yarn run test:coverage --coverageDirectory=/tmp/coverage
@@ -101,7 +107,7 @@ ARG GITHUB_REF
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
--mount=type=secret,id=NODE_AUTH_TOKEN <<EOT
--mount=type=secret,id=NODE_AUTH_TOKEN,env=NODE_AUTH_TOKEN <<EOT
set -e
if ! [[ $GITHUB_REF =~ ^refs/tags/v ]]; then
echo "GITHUB_REF is not a tag"
@@ -109,10 +115,10 @@ RUN --mount=type=bind,target=.,rw \
fi
yarn install
yarn run build
npm config set //registry.npmjs.org/:_authToken $(cat /run/secrets/NODE_AUTH_TOKEN)
npm config set //registry.npmjs.org/:_authToken $NODE_AUTH_TOKEN
npm version --no-git-tag-version ${GITHUB_REF#refs/tags/v}
npm publish --access public
# FIXME: Can't publish with yarn berry atm: https://github.com/changesets/changesets/pull/674
#NODE_AUTH_TOKEN=$(cat /run/secrets/NODE_AUTH_TOKEN) yarn publish --no-git-tag-version --new-version ${GITHUB_REF#refs/tags/v}
#yarn publish --no-git-tag-version --new-version ${GITHUB_REF#refs/tags/v}
EOT

View File

@@ -14,20 +14,6 @@
* limitations under the License.
*/
import fs from 'fs';
import os from 'os';
import path from 'path';
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-'));
process.env = Object.assign({}, process.env, {
TEMP: tmpDir,
RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
}) as {
[key: string]: string;
};
module.exports = {
testEnvironment: 'node',
moduleFileExtensions: ['js', 'ts'],

View File

@@ -30,7 +30,7 @@
],
"author": "Docker Inc.",
"license": "Apache-2.0",
"packageManager": "yarn@3.6.3",
"packageManager": "yarn@4.9.2",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"directories": {
@@ -45,50 +45,54 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"@actions/artifact": "^2.2.2",
"@actions/cache": "^4.0.2",
"@actions/artifact": "^4.0.0",
"@actions/attest": "^2.0.0",
"@actions/cache": "^4.1.0",
"@actions/core": "^1.11.1",
"@actions/exec": "^1.1.1",
"@actions/github": "^6.0.0",
"@actions/github": "^6.0.1",
"@actions/http-client": "^2.2.3",
"@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.2",
"@azure/storage-blob": "^12.15.0",
"@octokit/core": "^5.1.0",
"@octokit/plugin-rest-endpoint-methods": "^10.4.0",
"@octokit/core": "^5.2.2",
"@octokit/plugin-rest-endpoint-methods": "^10.4.1",
"@sigstore/bundle": "^3.1.0",
"@sigstore/sign": "^3.1.0",
"async-retry": "^1.3.3",
"csv-parse": "^5.6.0",
"csv-parse": "^6.1.0",
"gunzip-maybe": "^1.4.2",
"handlebars": "^4.7.8",
"he": "^1.2.0",
"js-yaml": "^4.1.0",
"jwt-decode": "^4.0.0",
"semver": "^7.7.1",
"semver": "^7.7.3",
"tar-stream": "^3.1.7",
"tmp": "^0.2.3"
"tmp": "^0.2.5"
},
"devDependencies": {
"@types/csv-parse": "^1.2.2",
"@sigstore/mock": "^0.10.0",
"@sigstore/rekor-types": "^3.0.0",
"@types/gunzip-maybe": "^1.4.2",
"@types/he": "^1.2.3",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.12.10",
"@types/semver": "^7.5.8",
"@types/tar-stream": "^3.1.3",
"@types/node": "^20.19.9",
"@types/semver": "^7.7.1",
"@types/tar-stream": "^3.1.4",
"@types/tmp": "^0.2.6",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"dotenv": "^16.4.5",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jest": "^28.5.0",
"eslint-plugin-prettier": "^5.1.3",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"dotenv": "^17.2.1",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.2",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^28.14.0",
"eslint-plugin-prettier": "^5.5.3",
"jest": "^29.7.0",
"prettier": "^3.2.5",
"rimraf": "^5.0.5",
"ts-jest": "^29.1.2",
"prettier": "^3.6.2",
"rimraf": "^6.0.1",
"ts-jest": "^29.4.1",
"ts-node": "^10.9.2",
"typescript": "^5.4.5"
"typescript": "^5.9.2"
}
}

View File

@@ -32,6 +32,11 @@ export interface BuildOpts {
buildx?: Buildx;
}
export interface ResolveSecretsOpts {
asFile?: boolean;
redact?: boolean;
}
export class Build {
private readonly buildx: Buildx;
private readonly iidFilename: string;
@@ -124,12 +129,16 @@ export class Build {
}
public static resolveSecretString(kvp: string): string {
const [key, file] = Build.resolveSecret(kvp, false);
const [key, file] = Build.resolveSecret(kvp, {
redact: true
});
return `id=${key},src=${file}`;
}
public static resolveSecretFile(kvp: string): string {
const [key, file] = Build.resolveSecret(kvp, true);
const [key, file] = Build.resolveSecret(kvp, {
asFile: true
});
return `id=${key},src=${file}`;
}
@@ -138,10 +147,10 @@ export class Build {
return `id=${key},env=${value}`;
}
public static resolveSecret(kvp: string, file: boolean): [string, string] {
const [key, value] = Build.parseSecretKvp(kvp);
public static resolveSecret(kvp: string, opts?: ResolveSecretsOpts): [string, string] {
const [key, value] = Build.parseSecretKvp(kvp, opts?.redact);
const secretFile = Context.tmpName({tmpdir: Context.tmpDir()});
if (file) {
if (opts?.asFile) {
if (!fs.existsSync(value)) {
throw new Error(`secret file ${value} not found`);
}
@@ -310,13 +319,16 @@ export class Build {
return false;
}
private static parseSecretKvp(kvp: string): [string, string] {
public static parseSecretKvp(kvp: string, redact?: boolean): [string, string] {
const delimiterIndex = kvp.indexOf('=');
const key = kvp.substring(0, delimiterIndex);
const value = kvp.substring(delimiterIndex + 1);
if (key.length == 0 || value.length == 0) {
throw new Error(`${kvp} is not a valid secret`);
}
if (redact) {
core.setSecret(value);
}
return [key, value];
}
}

View File

@@ -19,7 +19,7 @@ import * as core from '@actions/core';
import {Buildx} from './buildx';
import {Exec} from '../exec';
import {BuilderInfo, GCPolicy, NodeInfo} from '../types/buildx/builder';
import {BuilderInfo, Device, GCPolicy, NodeInfo} from '../types/buildx/builder';
export interface BuilderOpts {
buildx?: Buildx;
@@ -89,6 +89,7 @@ export class Builder {
let parsingType: string | undefined;
let currentNode: NodeInfo = {};
let currentGCPolicy: GCPolicy | undefined;
let currentDevice: Device | undefined;
let currentFile: string | undefined;
for (const line of data.trim().split(`\n`)) {
const [key, ...rest] = line.split(':');
@@ -172,6 +173,10 @@ export class Builder {
parsingType = 'label';
currentNode.labels = {};
break;
case lkey == 'devices':
parsingType = 'devices';
currentNode.devices = currentNode.devices || [];
break;
case lkey.startsWith('gc policy rule#'):
parsingType = 'gcpolicy';
if (currentNode.gcPolicy && currentGCPolicy) {
@@ -186,6 +191,10 @@ export class Builder {
currentNode.files[currentFile] = '';
break;
default: {
if (parsingType && parsingType !== 'devices' && currentNode.devices && currentDevice) {
currentNode.devices.push(currentDevice);
currentDevice = undefined;
}
switch (parsingType || '') {
case 'features': {
currentNode.features = currentNode.features || {};
@@ -197,6 +206,42 @@ export class Builder {
currentNode.labels[key.trim()] = value;
break;
}
case 'devices': {
switch (lkey.trim()) {
case 'name': {
if (currentNode.devices && currentDevice) {
currentNode.devices.push(currentDevice);
}
currentDevice = {};
currentDevice.name = value;
break;
}
case 'on-demand': {
if (currentDevice && value) {
currentDevice.onDemand = value == 'true';
}
break;
}
case 'automatically allowed': {
if (currentDevice && value) {
currentDevice.autoAllow = value == 'true';
}
break;
}
case 'annotations': {
if (currentDevice) {
currentDevice.annotations = currentDevice.annotations || {};
}
break;
}
default: {
if (currentDevice && currentDevice.annotations) {
currentDevice.annotations[key.trim()] = value;
}
}
}
break;
}
case 'gcpolicy': {
currentNode.gcPolicy = currentNode.gcPolicy || [];
currentGCPolicy = currentGCPolicy || {};
@@ -219,6 +264,18 @@ export class Builder {
currentGCPolicy.keepBytes = value;
break;
}
case 'reserved space': {
currentGCPolicy.reservedSpace = value;
break;
}
case 'max used space': {
currentGCPolicy.maxUsedSpace = value;
break;
}
case 'min free space': {
currentGCPolicy.minFreeSpace = value;
break;
}
}
break;
}
@@ -235,6 +292,9 @@ export class Builder {
}
}
}
if (currentDevice && currentNode.devices) {
currentNode.devices.push(currentDevice);
}
if (currentGCPolicy && currentNode.gcPolicy) {
currentNode.gcPolicy.push(currentGCPolicy);
}

View File

@@ -28,7 +28,7 @@ import {Exec} from '../exec';
import {GitHub} from '../github';
import {Util} from '../util';
import {ExportRecordOpts, ExportRecordResponse, Summaries} from '../types/buildx/history';
import {ExportOpts, ExportResponse, InspectOpts, InspectResponse, Summaries} from '../types/buildx/history';
export interface HistoryOpts {
buildx?: Buildx;
@@ -37,27 +37,43 @@ export interface HistoryOpts {
export class History {
private readonly buildx: Buildx;
private static readonly EXPORT_BUILD_IMAGE_DEFAULT: string = 'docker.io/dockereng/export-build:latest';
private static readonly EXPORT_BUILD_IMAGE_ENV: string = 'DOCKER_BUILD_EXPORT_BUILD_IMAGE';
constructor(opts?: HistoryOpts) {
this.buildx = opts?.buildx || new Buildx();
}
public async export(opts: ExportRecordOpts): Promise<ExportRecordResponse> {
if (os.platform() === 'win32') {
throw new Error('Exporting a build record is currently not supported on Windows');
}
if (!(await Docker.isAvailable())) {
throw new Error('Docker is required to export a build record');
}
if (!(await Docker.isDaemonRunning())) {
throw new Error('Docker daemon needs to be running to export a build record');
}
if (!(await this.buildx.versionSatisfies('>=0.13.0'))) {
throw new Error('Buildx >= 0.13.0 is required to export a build record');
}
public async getCommand(args: Array<string>) {
return await this.buildx.getCommand(['history', ...args]);
}
public async getInspectCommand(args: Array<string>) {
return await this.getCommand(['inspect', ...args]);
}
public async getExportCommand(args: Array<string>) {
return await this.getCommand(['export', ...args]);
}
public async inspect(opts: InspectOpts): Promise<InspectResponse> {
const args: Array<string> = ['--format', 'json'];
if (opts.builder) {
args.push('--builder', opts.builder);
}
if (opts.ref) {
args.push(opts.ref);
}
const cmd = await this.getInspectCommand(args);
return await Exec.getExecOutput(cmd.command, cmd.args, {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
return <InspectResponse>JSON.parse(res.stdout);
});
}
public async export(opts: ExportOpts): Promise<ExportResponse> {
let builderName: string = '';
let nodeName: string = '';
const refs: Array<string> = [];
@@ -85,6 +101,81 @@ export class History {
core.info(`exporting build record to ${outDir}`);
fs.mkdirSync(outDir, {recursive: true});
if (opts.useContainer || (await this.buildx.versionSatisfies('<0.23.0'))) {
return await this.exportLegacy(builderName, nodeName, refs, outDir, opts.image);
}
if (await this.buildx.versionSatisfies('<0.24.0')) {
// wait 3 seconds to ensure build records are finalized: https://github.com/moby/buildkit/pull/5109
// not necessary since buildx 0.24.0: https://github.com/docker/buildx/pull/3152
await Util.sleep(3);
}
const summaries: Summaries = {};
if (!opts.noSummaries) {
for (const ref of refs) {
await this.inspect({
ref: ref,
builder: builderName
}).then(res => {
let errorLogs = '';
if (res.Error && res.Status !== 'canceled') {
if (res.Error.Message) {
errorLogs = res.Error.Message;
} else if (res.Error.Name && res.Error.Logs) {
errorLogs = `=> ${res.Error.Name}\n${res.Error.Logs}`;
}
}
summaries[ref] = {
name: res.Name,
status: res.Status,
duration: Util.formatDuration(res.Duration),
numCachedSteps: res.NumCachedSteps,
numTotalSteps: res.NumTotalSteps,
numCompletedSteps: res.NumCompletedSteps,
defaultPlatform: res.Platform?.[0],
error: errorLogs
};
});
}
}
const dockerbuildPath = path.join(outDir, `${History.exportFilename(refs)}.dockerbuild`);
const exportArgs = ['--builder', builderName, '--output', dockerbuildPath, ...refs];
if (await this.buildx.versionSatisfies('>=0.24.0')) {
exportArgs.push('--finalize');
}
const cmd = await this.getExportCommand(exportArgs);
await Exec.getExecOutput(cmd.command, cmd.args);
const dockerbuildStats = fs.statSync(dockerbuildPath);
return {
dockerbuildFilename: dockerbuildPath,
dockerbuildSize: dockerbuildStats.size,
builderName: builderName,
nodeName: nodeName,
refs: refs,
summaries: summaries
};
}
private async exportLegacy(builderName: string, nodeName: string, refs: Array<string>, outDir: string, image?: string): Promise<ExportResponse> {
if (os.platform() === 'win32') {
throw new Error('Exporting a build record is currently not supported on Windows');
}
if (!(await Docker.isAvailable())) {
throw new Error('Docker is required to export a build record');
}
if (!(await Docker.isDaemonRunning())) {
throw new Error('Docker daemon needs to be running to export a build record');
}
if (!(await this.buildx.versionSatisfies('>=0.13.0'))) {
throw new Error('Buildx >= 0.13.0 is required to export a build record');
}
// wait 3 seconds to ensure build records are finalized: https://github.com/moby/buildkit/pull/5109
await Util.sleep(3);
@@ -139,7 +230,7 @@ export class History {
'run', '--rm', '-i',
'-v', `${Buildx.refsDir}:/buildx-refs`,
'-v', `${outDir}:/out`,
opts.image || process.env[History.EXPORT_BUILD_IMAGE_ENV] || History.EXPORT_BUILD_IMAGE_DEFAULT,
image || process.env['DOCKER_BUILD_EXPORT_BUILD_IMAGE'] || 'docker.io/dockereng/export-build:latest',
...ebargs
]
core.info(`[command]docker ${dockerRunArgs.join(' ')}`);
@@ -190,12 +281,7 @@ export class History {
}
});
let dockerbuildFilename = `${GitHub.context.repo.owner}~${GitHub.context.repo.repo}~${refs[0].substring(0, 6).toUpperCase()}`;
if (refs.length > 1) {
dockerbuildFilename += `+${refs.length - 1}`;
}
const dockerbuildPath = path.join(outDir, `${dockerbuildFilename}.dockerbuild`);
const dockerbuildPath = path.join(outDir, `${History.exportFilename(refs)}.dockerbuild`);
fs.renameSync(tmpDockerbuildFilename, dockerbuildPath);
const dockerbuildStats = fs.statSync(dockerbuildPath);
@@ -206,10 +292,18 @@ export class History {
return {
dockerbuildFilename: dockerbuildPath,
dockerbuildSize: dockerbuildStats.size,
summaries: summaries,
builderName: builderName,
nodeName: nodeName,
refs: refs
refs: refs,
summaries: summaries
};
}
private static exportFilename(refs: Array<string>): string {
let name = `${GitHub.context.repo.owner}~${GitHub.context.repo.repo}~${refs[0].substring(0, 6).toUpperCase()}`;
if (refs.length > 1) {
name += `+${refs.length - 1}`;
}
return name;
}
}

View File

@@ -17,7 +17,10 @@
import {Buildx} from './buildx';
import {Exec} from '../exec';
import {Manifest as ImageToolsManifest} from '../types/buildx/imagetools';
import {Image} from '../types/oci/config';
import {Descriptor} from '../types/oci/descriptor';
import {Digest} from '../types/oci/digest';
export interface ImageToolsOpts {
buildx?: Buildx;
@@ -58,4 +61,37 @@ export class ImageTools {
throw new Error('Unexpected output format');
});
}
public async inspectManifest(name: string): Promise<ImageToolsManifest | Descriptor> {
const cmd = await this.getInspectCommand([name, '--format', '{{json .Manifest}}']);
return await Exec.getExecOutput(cmd.command, cmd.args, {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
const parsedOutput = JSON.parse(res.stdout);
if (typeof parsedOutput === 'object' && !Array.isArray(parsedOutput) && parsedOutput !== null) {
if (Object.prototype.hasOwnProperty.call(parsedOutput, 'manifests')) {
return <ImageToolsManifest>parsedOutput;
} else {
return <Descriptor>parsedOutput;
}
}
throw new Error('Unexpected output format');
});
}
public async attestationDescriptors(name: string): Promise<Array<Descriptor>> {
const manifest = await this.inspectManifest(name);
if (typeof manifest === 'object' && manifest !== null && 'manifests' in manifest && Array.isArray(manifest.manifests)) {
return manifest.manifests.filter(m => m.annotations && m.annotations['vnd.docker.reference.type'] === 'attestation-manifest');
}
throw new Error(`No attestation descriptors found for ${name}`);
}
public async attestationDigests(name: string): Promise<Array<Digest>> {
return (await this.attestationDescriptors(name)).map(attestation => attestation.digest);
}
}

View File

@@ -18,7 +18,6 @@ import fs from 'fs';
import os from 'os';
import path from 'path';
import * as core from '@actions/core';
import * as httpm from '@actions/http-client';
import * as tc from '@actions/tool-cache';
import * as semver from 'semver';
import * as util from 'util';
@@ -29,6 +28,7 @@ import {Context} from '../context';
import {Exec} from '../exec';
import {Docker} from '../docker/docker';
import {Git} from '../git';
import {GitHub} from '../github';
import {Util} from '../util';
import {DownloadVersion} from '../types/buildx/buildx';
@@ -36,13 +36,16 @@ import {GitHubRelease} from '../types/github';
export interface InstallOpts {
standalone?: boolean;
githubToken?: string;
}
export class Install {
private readonly _standalone: boolean | undefined;
private readonly standalone: boolean | undefined;
private readonly githubToken: string | undefined;
constructor(opts?: InstallOpts) {
this._standalone = opts?.standalone;
this.standalone = opts?.standalone;
this.githubToken = opts?.githubToken || process.env.GITHUB_TOKEN;
}
/*
@@ -55,7 +58,7 @@ export class Install {
const version: DownloadVersion = await Install.getDownloadVersion(v);
core.debug(`Install.download version: ${version.version}`);
const release: GitHubRelease = await Install.getRelease(version);
const release: GitHubRelease = await Install.getRelease(version, this.githubToken);
core.debug(`Install.download release tag name: ${release.tag_name}`);
const vspec = await this.vspec(release.tag_name);
@@ -83,7 +86,7 @@ export class Install {
const downloadURL = util.format(version.downloadURL, vspec, this.filename(vspec));
core.info(`Downloading ${downloadURL}`);
const htcDownloadPath = await tc.downloadTool(downloadURL);
const htcDownloadPath = await tc.downloadTool(downloadURL, undefined, this.githubToken);
core.debug(`Install.download htcDownloadPath: ${htcDownloadPath}`);
const cacheSavePath = await installCache.save(htcDownloadPath);
@@ -205,7 +208,7 @@ export class Install {
}
private async isStandalone(): Promise<boolean> {
const standalone = this._standalone ?? !(await Docker.isAvailable());
const standalone = this.standalone ?? !(await Docker.isAvailable());
core.debug(`Install.isStandalone: ${standalone}`);
return standalone;
}
@@ -285,7 +288,12 @@ export class Install {
key: repoKey,
version: version,
downloadURL: 'https://github.com/docker/buildx/releases/download/v%s/%s',
releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json'
contentOpts: {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/buildx-releases.json'
}
};
}
case 'cloud': {
@@ -293,7 +301,12 @@ export class Install {
key: repoKey,
version: version,
downloadURL: 'https://github.com/docker/buildx-desktop/releases/download/v%s/%s',
releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json'
contentOpts: {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/buildx-lab-releases.json'
}
};
}
default: {
@@ -302,17 +315,11 @@ export class Install {
}
}
public static async getRelease(version: DownloadVersion): Promise<GitHubRelease> {
const http: httpm.HttpClient = new httpm.HttpClient('docker-actions-toolkit');
const resp: httpm.HttpClientResponse = await http.get(version.releasesURL);
const body = await resp.readBody();
const statusCode = resp.message.statusCode || 500;
if (statusCode >= 400) {
throw new Error(`Failed to get Buildx releases from ${version.releasesURL} with status code ${statusCode}: ${body}`);
}
const releases = <Record<string, GitHubRelease>>JSON.parse(body);
public static async getRelease(version: DownloadVersion, githubToken?: string): Promise<GitHubRelease> {
const github = new GitHub({token: githubToken});
const releases = await github.releases('Buildx', version.contentOpts);
if (!releases[version.version]) {
throw new Error(`Cannot find Buildx release ${version.version} in ${version.releasesURL}`);
throw new Error(`Cannot find Buildx release ${version.version} in releases JSON`);
}
return releases[version.version];
}

View File

@@ -18,27 +18,30 @@ import fs from 'fs';
import os from 'os';
import path from 'path';
import * as core from '@actions/core';
import * as httpm from '@actions/http-client';
import * as tc from '@actions/tool-cache';
import * as semver from 'semver';
import * as util from 'util';
import {Cache} from '../cache';
import {Context} from '../context';
import {Docker} from '../docker/docker';
import {GitHub} from '../github';
import {DownloadVersion} from '../types/compose/compose';
import {GitHubRelease} from '../types/github';
import {Docker} from '../docker/docker';
export interface InstallOpts {
standalone?: boolean;
githubToken?: string;
}
export class Install {
private readonly _standalone: boolean | undefined;
private readonly standalone: boolean | undefined;
private readonly githubToken: string | undefined;
constructor(opts?: InstallOpts) {
this._standalone = opts?.standalone;
this.standalone = opts?.standalone;
this.githubToken = opts?.githubToken || process.env.GITHUB_TOKEN;
}
/*
@@ -51,7 +54,7 @@ export class Install {
const version: DownloadVersion = await Install.getDownloadVersion(v);
core.debug(`Install.download version: ${version.version}`);
const release: GitHubRelease = await Install.getRelease(version);
const release: GitHubRelease = await Install.getRelease(version, this.githubToken);
core.debug(`Install.download release tag name: ${release.tag_name}`);
const vspec = await this.vspec(release.tag_name);
@@ -79,7 +82,7 @@ export class Install {
const downloadURL = util.format(version.downloadURL, vspec, this.filename());
core.info(`Downloading ${downloadURL}`);
const htcDownloadPath = await tc.downloadTool(downloadURL);
const htcDownloadPath = await tc.downloadTool(downloadURL, undefined, this.githubToken);
core.debug(`Install.download htcDownloadPath: ${htcDownloadPath}`);
const cacheSavePath = await installCache.save(htcDownloadPath);
@@ -129,7 +132,7 @@ export class Install {
}
private async isStandalone(): Promise<boolean> {
const standalone = this._standalone ?? !(await Docker.isAvailable());
const standalone = this.standalone ?? !(await Docker.isAvailable());
core.debug(`Install.isStandalone: ${standalone}`);
return standalone;
}
@@ -183,7 +186,12 @@ export class Install {
key: repoKey,
version: version,
downloadURL: 'https://github.com/docker/compose/releases/download/v%s/%s',
releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json'
contentOpts: {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/compose-releases.json'
}
};
}
case 'cloud': {
@@ -191,7 +199,12 @@ export class Install {
key: repoKey,
version: version,
downloadURL: 'https://github.com/docker/compose-desktop/releases/download/v%s/%s',
releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-lab-releases.json'
contentOpts: {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/compose-lab-releases.json'
}
};
}
default: {
@@ -200,17 +213,11 @@ export class Install {
}
}
public static async getRelease(version: DownloadVersion): Promise<GitHubRelease> {
const http: httpm.HttpClient = new httpm.HttpClient('docker-actions-toolkit');
const resp: httpm.HttpClientResponse = await http.get(version.releasesURL);
const body = await resp.readBody();
const statusCode = resp.message.statusCode || 500;
if (statusCode >= 400) {
throw new Error(`Failed to get Compose releases from ${version.releasesURL} with status code ${statusCode}: ${body}`);
}
const releases = <Record<string, GitHubRelease>>JSON.parse(body);
public static async getRelease(version: DownloadVersion, githubToken?: string): Promise<GitHubRelease> {
const github = new GitHub({token: githubToken});
const releases = await github.releases('Compose', version.contentOpts);
if (!releases[version.version]) {
throw new Error(`Cannot find Compose release ${version.version} in ${version.releasesURL}`);
throw new Error(`Cannot find Compose release ${version.version} in releases JSON`);
}
return releases[version.version];
}

160
src/cosign/cosign.ts Normal file
View File

@@ -0,0 +1,160 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as core from '@actions/core';
import {BUNDLE_V03_MEDIA_TYPE, SerializedBundle} from '@sigstore/bundle';
import {Exec} from '../exec';
import * as semver from 'semver';
import {MEDIATYPE_EMPTY_JSON_V1} from '../types/oci/mediatype';
export interface CosignOpts {
binPath?: string;
}
export interface CosignCommandResult {
bundle?: SerializedBundle;
signatureManifestDigest?: string;
errors?: Array<CosignCommandError>;
}
export interface CosignCommandError {
code: string;
message: string;
detail: string;
}
export class Cosign {
private readonly binPath: string;
private _version: string;
private _versionOnce: boolean;
constructor(opts?: CosignOpts) {
this.binPath = opts?.binPath || 'cosign';
this._version = '';
this._versionOnce = false;
}
public async isAvailable(): Promise<boolean> {
const ok: boolean = await Exec.getExecOutput(this.binPath, [], {
ignoreReturnCode: true,
silent: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
core.debug(`Cosign.isAvailable cmd err: ${res.stderr.trim()}`);
return false;
}
return res.exitCode == 0;
})
.catch(error => {
core.debug(`Cosign.isAvailable error: ${error}`);
return false;
});
core.debug(`Cosign.isAvailable: ${ok}`);
return ok;
}
public async version(): Promise<string> {
if (this._versionOnce) {
return this._version;
}
this._versionOnce = true;
this._version = await Exec.getExecOutput(this.binPath, ['version', '--json'], {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
return JSON.parse(res.stdout.trim()).gitVersion;
});
return this._version;
}
public async printVersion() {
await Exec.exec(this.binPath, ['version', '--json'], {
failOnStdErr: false
});
}
public async versionSatisfies(range: string, version?: string): Promise<boolean> {
const ver = version ?? (await this.version());
if (!ver) {
core.debug(`Cosign.versionSatisfies false: undefined version`);
return false;
}
const res = semver.satisfies(ver, range) || /^[0-9a-f]{7}$/.exec(ver) !== null;
core.debug(`Cosign.versionSatisfies ${ver} statisfies ${range}: ${res}`);
return res;
}
public static parseCommandOutput(logs: string): CosignCommandResult {
let signatureManifestDigest: string | undefined;
let signatureManifestFallbackDigest: string | undefined;
let bundlePayload: SerializedBundle | undefined;
let errors: Array<CosignCommandError> | undefined;
for (const rawLine of logs.split(/\r?\n/)) {
const line = rawLine.trim();
if (!line.startsWith('{') || !line.endsWith('}')) {
continue;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let obj: any;
try {
obj = JSON.parse(line);
} catch {
continue;
}
if (obj && Array.isArray(obj.errors) && obj.errors.length > 0) {
errors = obj.errors;
}
// signature manifest digest
if (!signatureManifestDigest && obj && Array.isArray(obj.manifests) && obj.manifests.length > 0) {
const m0 = obj.manifests[0];
if (m0?.artifactType === BUNDLE_V03_MEDIA_TYPE && typeof m0.digest === 'string') {
signatureManifestDigest = m0.digest;
} else if (m0?.artifactType === MEDIATYPE_EMPTY_JSON_V1 && typeof m0.digest === 'string') {
signatureManifestFallbackDigest = m0.digest;
}
}
// signature payload
if (!bundlePayload && obj && obj.mediaType === BUNDLE_V03_MEDIA_TYPE) {
bundlePayload = obj as SerializedBundle;
}
if (bundlePayload && signatureManifestDigest) {
break;
}
}
if (!errors && !bundlePayload) {
throw new Error(`Cannot find signature bundle from cosign command output: ${logs}`);
}
return {
bundle: bundlePayload,
signatureManifestDigest: signatureManifestDigest || signatureManifestFallbackDigest,
errors: errors
};
}
}

61
src/cosign/dockerfile.ts Normal file
View File

@@ -0,0 +1,61 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const dockerfileContent = `
# syntax=docker/dockerfile:1
ARG GO_VERSION="1.24"
ARG ALPINE_VERSION="3.22"
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.7.0 AS xx
FROM --platform=$BUILDPLATFORM golang:\${GO_VERSION}-alpine\${ALPINE_VERSION} AS builder-base
COPY --from=xx / /
RUN apk add --no-cache git
ENV GOTOOLCHAIN=auto
ENV CGO_ENABLED=0
WORKDIR /src
RUN --mount=type=cache,target=/go/pkg/mod \\
--mount=type=bind,source=go.mod,target=go.mod \\
--mount=type=bind,source=go.sum,target=go.sum \\
go mod download
FROM builder-base AS version
RUN --mount=type=bind,target=. <<'EOT'
git rev-parse HEAD 2>/dev/null || {
echo >&2 "Failed to get git revision, make sure --build-arg BUILDKIT_CONTEXT_KEEP_GIT_DIR=1 is set when building from Git directly"
exit 1
}
set -ex
export PKG=sigs.k8s.io BUILDDATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") TREESTATE=$(if ! git diff --no-ext-diff --quiet --exit-code; then echo dirty; else echo clean; fi) VERSION=$(git describe --match 'v[0-9]*' --dirty='.m' --always --tags) COMMIT=$(git rev-parse HEAD)$(if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi);
echo "-X \${PKG}/release-utils/version.gitVersion=\${VERSION} -X \${PKG}/release-utils/version.gitCommit=\${COMMIT} -X \${PKG}/release-utils/version.gitTreeState=\${TREESTATE} -X \${PKG}/release-utils/version.buildDate=\${BUILDDATE}" > /tmp/.ldflags;
echo -n "\${VERSION}" > /tmp/.version;
EOT
FROM builder-base AS builder
ARG TARGETPLATFORM
RUN --mount=type=bind,target=. \\
--mount=type=cache,target=/root/.cache,id=cosign-$TARGETPLATFORM \\
--mount=source=/tmp/.ldflags,target=/tmp/.ldflags,from=version \\
--mount=type=cache,target=/go/pkg/mod <<EOT
set -ex
xx-go build -trimpath -ldflags "-s -w $(cat /tmp/.ldflags)" -o /out/cosign ./cmd/cosign
xx-verify --static /out/cosign
EOT
FROM scratch
COPY --from=builder /out /
`;

248
src/cosign/install.ts Normal file
View File

@@ -0,0 +1,248 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fs from 'fs';
import os from 'os';
import path from 'path';
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import * as semver from 'semver';
import * as util from 'util';
import {Buildx} from '../buildx/buildx';
import {Cache} from '../cache';
import {Context} from '../context';
import {Exec} from '../exec';
import {Git} from '../git';
import {GitHub} from '../github';
import {Util} from '../util';
import {DownloadVersion} from '../types/cosign/cosign';
import {GitHubRelease} from '../types/github';
import {dockerfileContent} from './dockerfile';
export interface InstallOpts {
githubToken?: string;
buildx?: Buildx;
}
export class Install {
private readonly githubToken: string | undefined;
private readonly buildx: Buildx;
constructor(opts?: InstallOpts) {
this.githubToken = opts?.githubToken || process.env.GITHUB_TOKEN;
this.buildx = opts?.buildx || new Buildx();
}
public async download(v: string, ghaNoCache?: boolean, skipState?: boolean): Promise<string> {
const version: DownloadVersion = await Install.getDownloadVersion(v);
core.debug(`Install.download version: ${version.version}`);
const release: GitHubRelease = await Install.getRelease(version, this.githubToken);
core.debug(`Install.download release tag name: ${release.tag_name}`);
const vspec = await this.vspec(release.tag_name);
core.debug(`Install.download vspec: ${vspec}`);
const c = semver.clean(vspec) || '';
if (!semver.valid(c)) {
throw new Error(`Invalid Cosign version "${vspec}".`);
}
const installCache = new Cache({
htcName: 'cosign-dl-bin',
htcVersion: vspec,
baseCacheDir: path.join(os.homedir(), '.bin'),
cacheFile: os.platform() == 'win32' ? 'cosign.exe' : 'cosign',
ghaNoCache: ghaNoCache
});
const cacheFoundPath = await installCache.find();
if (cacheFoundPath) {
core.info(`Cosign binary found in ${cacheFoundPath}`);
return cacheFoundPath;
}
const downloadURL = util.format(version.downloadURL, vspec, this.filename());
core.info(`Downloading ${downloadURL}`);
const htcDownloadPath = await tc.downloadTool(downloadURL, undefined, this.githubToken);
core.debug(`Install.download htcDownloadPath: ${htcDownloadPath}`);
const cacheSavePath = await installCache.save(htcDownloadPath, skipState);
core.info(`Cached to ${cacheSavePath}`);
return cacheSavePath;
}
public async build(gitContext: string, ghaNoCache?: boolean, skipState?: boolean): Promise<string> {
const vspec = await this.vspec(gitContext);
core.debug(`Install.build vspec: ${vspec}`);
const installCache = new Cache({
htcName: 'cosign-build-bin',
htcVersion: vspec,
baseCacheDir: path.join(os.homedir(), '.bin'),
cacheFile: os.platform() == 'win32' ? 'cosign.exe' : 'cosign',
ghaNoCache: ghaNoCache
});
const cacheFoundPath = await installCache.find();
if (cacheFoundPath) {
core.info(`Cosign binary found in ${cacheFoundPath}`);
return cacheFoundPath;
}
const outputDir = path.join(Context.tmpDir(), 'cosign-build-cache');
const buildCmd = await this.buildCommand(gitContext, outputDir);
const buildBinPath = await Exec.getExecOutput(buildCmd.command, buildCmd.args, {
ignoreReturnCode: true,
input: Buffer.from(dockerfileContent)
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(`build failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
}
return `${outputDir}/cosign`;
});
const cacheSavePath = await installCache.save(buildBinPath, skipState);
core.info(`Cached to ${cacheSavePath}`);
return cacheSavePath;
}
public async install(binPath: string, dest?: string): Promise<string> {
dest = dest || Context.tmpDir();
const binDir = path.join(dest, 'cosign-bin');
if (!fs.existsSync(binDir)) {
fs.mkdirSync(binDir, {recursive: true});
}
const binName: string = os.platform() == 'win32' ? 'cosign.exe' : 'cosign';
const cosignPath: string = path.join(binDir, binName);
fs.copyFileSync(binPath, cosignPath);
core.info('Fixing perms');
fs.chmodSync(cosignPath, '0755');
core.addPath(binDir);
core.info('Added Cosign to PATH');
core.info(`Binary path: ${cosignPath}`);
return cosignPath;
}
private async buildCommand(gitContext: string, outputDir: string): Promise<{args: Array<string>; command: string}> {
const buildxStandaloneFound = await new Buildx({standalone: true}).isAvailable();
const buildxPluginFound = await new Buildx({standalone: false}).isAvailable();
let buildStandalone = false;
if ((await this.buildx.isStandalone()) && buildxStandaloneFound) {
core.debug(`Install.buildCommand: Buildx standalone found, build with it`);
buildStandalone = true;
} else if (!(await this.buildx.isStandalone()) && buildxPluginFound) {
core.debug(`Install.buildCommand: Buildx plugin found, build with it`);
buildStandalone = false;
} else if (buildxStandaloneFound) {
core.debug(`Install.buildCommand: Buildx plugin not found, but standalone found so trying to build with it`);
buildStandalone = true;
} else if (buildxPluginFound) {
core.debug(`Install.buildCommand: Buildx standalone not found, but plugin found so trying to build with it`);
buildStandalone = false;
} else {
throw new Error(`Neither buildx standalone or plugin have been found to build from ref ${gitContext}`);
}
const args = ['build', '--platform', 'local', '--build-arg', 'BUILDKIT_CONTEXT_KEEP_GIT_DIR=1', '--output', `type=local,dest=${outputDir}`];
if (process.env.GIT_AUTH_TOKEN) {
args.push('--secret', 'id=GIT_AUTH_TOKEN');
}
args.push('-f-', gitContext);
// prettier-ignore
return await new Buildx({standalone: buildStandalone}).getCommand(args);
}
private filename(): string {
let arch: string;
switch (os.arch()) {
case 'x64': {
arch = 'amd64';
break;
}
case 'ppc64': {
arch = 'ppc64le';
break;
}
default: {
arch = os.arch();
break;
}
}
const platform: string = os.platform() == 'win32' ? 'windows' : os.platform();
const ext: string = os.platform() == 'win32' ? '.exe' : '';
return util.format('cosign-%s-%s%s', platform, arch, ext);
}
private async vspec(versionOrRef: string): Promise<string> {
if (!Util.isValidRef(versionOrRef)) {
const v = versionOrRef.replace(/^v+|v+$/g, '');
core.info(`Use ${v} version spec cache key for ${versionOrRef}`);
return v;
}
// eslint-disable-next-line prefer-const
let [baseURL, ref] = versionOrRef.split('#');
if (ref.length == 0) {
ref = 'master';
}
let sha: string;
if (ref.match(/^[0-9a-fA-F]{40}$/)) {
sha = ref;
} else {
sha = await Git.remoteSha(baseURL, ref, process.env.GIT_AUTH_TOKEN);
}
const [owner, repo] = baseURL.substring('https://github.com/'.length).split('/');
const key = `${owner}/${Util.trimSuffix(repo, '.git')}/${sha}`;
const hash = Util.hash(key);
core.info(`Use ${hash} version spec cache key for ${key}`);
return hash;
}
public static async getDownloadVersion(v: string): Promise<DownloadVersion> {
return {
version: v,
downloadURL: 'https://github.com/sigstore/cosign/releases/download/v%s/%s',
contentOpts: {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/cosign-releases.json'
}
};
}
public static async getRelease(version: DownloadVersion, githubToken?: string): Promise<GitHubRelease> {
const github = new GitHub({token: githubToken});
const releases = await github.releases('Cosign', version.contentOpts);
if (!releases[version.version]) {
throw new Error(`Cannot find Cosign release ${version.version} in releases JSON`);
}
return releases[version.version];
}
}

View File

@@ -140,7 +140,10 @@ Get-WinEvent -ea SilentlyContinue \`
`;
export const limaYamlData = `
# Source: https://github.com/lima-vm/lima/blob/master/templates/docker-rootful.yaml
# Source:
# - https://github.com/lima-vm/lima/blob/master/templates/docker-rootful.yaml
# - https://github.com/lima-vm/lima/blob/master/templates/_images/ubuntu-lts.yaml
# - https://github.com/lima-vm/lima/blob/master/templates/_images/ubuntu-24.04.yaml
# VM type: "qemu" or "vz" (on macOS 13 and later).
# The vmType can be specified only on creating the instance.
@@ -162,17 +165,24 @@ images:
arch: "{{arch}}"
digest: "{{digest}}"
{{/each}}
- location: "https://cloud-images.ubuntu.com/releases/24.04/release-20241004/ubuntu-24.04-server-cloudimg-amd64.img"
- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250704/ubuntu-24.04-server-cloudimg-amd64.img"
arch: "x86_64"
digest: "sha256:fad101d50b06b26590cf30542349f9e9d3041ad7929e3bc3531c81ec27f2c788"
- location: "https://cloud-images.ubuntu.com/releases/24.04/release-20241004/ubuntu-24.04-server-cloudimg-arm64.img"
digest: "sha256:f1652d29d497fb7c623433705c9fca6525d1311b11294a0f495eed55c7639d1f"
kernel:
location: "https://cloud-images.ubuntu.com/releases/noble/release-20250704/unpacked/ubuntu-24.04-server-cloudimg-amd64-vmlinuz-generic"
digest: "sha256:67cd9af083515de2101de032b49a64fc4b65778e5383df6ef21cf788a3f4688e"
cmdline: "root=LABEL=cloudimg-rootfs ro console=tty1 console=ttyAMA0 no_timer_check"
initrd:
location: "https://cloud-images.ubuntu.com/releases/noble/release-20250704/unpacked/ubuntu-24.04-server-cloudimg-amd64-initrd-generic"
digest: "sha256:f257d581c44f66da2d80c7c5dc3fa598ce76ef313d6e27b368683e8030a9e8fd"
- location: "https://cloud-images.ubuntu.com/releases/noble/release-20250704/ubuntu-24.04-server-cloudimg-arm64.img"
arch: "aarch64"
digest: "sha256:e380b683b0c497d2a87af8a5dbe94c42eb54548fa976167f307ed8cf3944ec57"
digest: "sha256:bbecbb88100ee65497927ed0da247ba15af576a8855004182cf3c87265e25d35"
# Fallback to the latest release image.
# Hint: run \`limactl prune\` to invalidate the cache
- location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img"
- location: https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-amd64.img
arch: "x86_64"
- location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img"
- location: https://cloud-images.ubuntu.com/releases/noble/release/ubuntu-24.04-server-cloudimg-arm64.img
arch: "aarch64"
# CPUs
@@ -250,7 +260,7 @@ provision:
x86_64) arch=amd64;;
aarch64) arch=arm64;;
esac
url="https://github.com/crazy-max/undock/releases/download/v0.8.0/undock_0.8.0_linux_$arch.tar.gz"
url="https://github.com/crazy-max/undock/releases/download/v0.10.0/undock_0.10.0_linux_$arch.tar.gz"
wget "$url" -O /tmp/undock.tar.gz
tar -C /usr/local/bin -xvf /tmp/undock.tar.gz
@@ -283,18 +293,25 @@ probes:
#!/bin/bash
set -eux -o pipefail
# Don't check for docker CLI as it's not installed in the VM (only on the host)
if ! timeout 30s bash -c "until pgrep dockerd; do sleep 3; done"; then
if ! timeout 60s bash -c "until pgrep dockerd; do sleep 3; done"; then
echo >&2 "dockerd is not running"
exit 1
fi
hint: See "/var/log/cloud-init-output.log". in the guest
hostResolver:
# Don't use local system resolver
enabled: false
# hostResolver.hosts requires lima 0.8.3 or later. Names defined here will also
# resolve inside containers, and not just inside the VM itself.
hosts:
host.docker.internal: host.lima.internal
# Use custom DNS servers instead of the host's DNS settings
dns:
- 1.1.1.1
- 1.0.0.1
portForwards:
- guestSocket: "/var/run/docker.sock"
hostSocket: "{{dockerSock}}"

View File

@@ -22,17 +22,20 @@ import path from 'path';
import retry from 'async-retry';
import * as handlebars from 'handlebars';
import * as core from '@actions/core';
import * as httpm from '@actions/http-client';
import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import {Context} from '../context';
import {Docker} from './docker';
import {Exec} from '../exec';
import {GitHub} from '../github';
import {Regctl} from '../regclient/regctl';
import {Undock} from '../undock/undock';
import {Util} from '../util';
import {limaYamlData, dockerServiceLogsPs1, setupDockerWinPs1} from './assets';
import {GitHubRelease} from '../types/github';
import {HubRepository} from '../hubRepository';
import {Image} from '../types/oci/config';
export interface InstallSourceImage {
@@ -57,6 +60,11 @@ export interface InstallOpts {
daemonConfig?: string;
rootless?: boolean;
localTCPPort?: number;
regctl?: Regctl;
undock?: Undock;
githubToken?: string;
}
interface LimaImage {
@@ -72,6 +80,9 @@ export class Install {
private readonly daemonConfig?: string;
private readonly rootless: boolean;
private readonly localTCPPort?: number;
private readonly regctl: Regctl;
private readonly undock: Undock;
private readonly githubToken?: string;
private _version: string | undefined;
private _toolDir: string | undefined;
@@ -91,36 +102,15 @@ export class Install {
this.daemonConfig = opts.daemonConfig;
this.rootless = opts.rootless || false;
this.localTCPPort = opts.localTCPPort;
this.regctl = opts.regctl || new Regctl();
this.undock = opts.undock || new Undock();
this.githubToken = opts.githubToken || process.env.GITHUB_TOKEN;
}
get toolDir(): string {
return this._toolDir || Context.tmpDir();
}
async downloadStaticArchive(component: 'docker' | 'docker-rootless-extras', src: InstallSourceArchive): Promise<string> {
const release: GitHubRelease = await Install.getRelease(src.version);
this._version = release.tag_name.replace(/^v+|v+$/g, '');
core.debug(`docker.Install.download version: ${this._version}`);
const downloadURL = this.downloadURL(component, this._version, src.channel);
core.info(`Downloading ${downloadURL}`);
const downloadPath = await tc.downloadTool(downloadURL);
core.debug(`docker.Install.download downloadPath: ${downloadPath}`);
let extractFolder;
if (os.platform() == 'win32') {
extractFolder = await tc.extractZip(downloadPath, extractFolder);
} else {
extractFolder = await tc.extractTar(downloadPath, extractFolder);
}
if (Util.isDirectory(path.join(extractFolder, component))) {
extractFolder = path.join(extractFolder, component);
}
core.debug(`docker.Install.download extractFolder: ${extractFolder}`);
return extractFolder;
}
public async download(): Promise<string> {
let extractFolder: string;
let cacheKey: string;
@@ -128,39 +118,9 @@ export class Install {
switch (this.source.type) {
case 'image': {
const tag = this.source.tag;
this._version = tag;
this._version = this.source.tag;
cacheKey = `docker-image`;
core.info(`Downloading docker cli from dockereng/cli-bin:${tag}`);
const cli = await HubRepository.build('dockereng/cli-bin');
extractFolder = await cli.extractImage(tag);
const moby = await HubRepository.build('moby/moby-bin');
if (['win32', 'linux'].includes(platform)) {
core.info(`Downloading dockerd from moby/moby-bin:${tag}`);
await moby.extractImage(tag, extractFolder);
} else if (platform == 'darwin') {
// On macOS, the docker daemon binary will be downloaded inside the lima VM.
// However, we will get the exact git revision from the image config
// to get the matching systemd unit files.
core.info(`Getting git revision from moby/moby-bin:${tag}`);
// There's no macOS image for moby/moby-bin - a linux daemon is run inside lima.
const manifest = await moby.getPlatformManifest(tag, 'linux');
const config = await moby.getJSONBlob<Image>(manifest.config.digest);
core.debug(`Config ${JSON.stringify(config.config)}`);
this.gitCommit = config.config?.Labels?.['org.opencontainers.image.revision'];
if (!this.gitCommit) {
core.warning(`No git revision can be determined from the image. Will use master.`);
this.gitCommit = 'master';
}
core.info(`Git revision is ${this.gitCommit}`);
} else {
core.warning(`dockerd not supported on ${platform}, only the Docker cli will be available`);
}
extractFolder = await this.downloadSourceImage(platform);
break;
}
case 'archive': {
@@ -170,10 +130,10 @@ export class Install {
this._version = version;
core.info(`Downloading Docker ${version} from ${this.source.channel} at download.docker.com`);
extractFolder = await this.downloadStaticArchive('docker', this.source);
extractFolder = await this.downloadSourceArchive('docker', this.source);
if (this.rootless) {
core.info(`Downloading Docker rootless extras ${version} from ${this.source.channel} at download.docker.com`);
const extrasFolder = await this.downloadStaticArchive('docker-rootless-extras', this.source);
const extrasFolder = await this.downloadSourceArchive('docker-rootless-extras', this.source);
fs.readdirSync(extrasFolder).forEach(file => {
const src = path.join(extrasFolder, file);
const dest = path.join(extractFolder, file);
@@ -191,7 +151,9 @@ export class Install {
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
files.forEach(function (file, index) {
fs.chmodSync(path.join(extractFolder, file), '0755');
if (!Util.isDirectory(path.join(extractFolder, file))) {
fs.chmodSync(path.join(extractFolder, file), '0755');
}
});
});
@@ -203,6 +165,72 @@ export class Install {
return tooldir;
}
private async downloadSourceImage(platform: string): Promise<string> {
const dest = path.join(Context.tmpDir(), 'docker-install-image');
const cliImage = `dockereng/cli-bin:${this._version}`;
const engineImage = `moby/moby-bin:${this._version}`;
core.info(`Downloading Docker CLI from ${cliImage}`);
await this.undock.run({
source: cliImage,
dist: dest
});
if (['win32', 'linux'].includes(platform)) {
core.info(`Downloading Docker engine from ${engineImage}`);
await this.undock.run({
source: engineImage,
dist: dest
});
} else if (platform == 'darwin') {
// On macOS, the docker daemon binary will be downloaded inside the lima VM.
// However, we will get the exact git revision from the image config
// to get the matching systemd unit files. There's no macOS image for
// moby/moby-bin - a linux daemon is run inside lima.
try {
const engineImageConfig = await this.imageConfig(engineImage, 'linux/arm64');
core.debug(`docker.Install.downloadSourceImage engineImageConfig: ${JSON.stringify(engineImageConfig)}`);
this.gitCommit = engineImageConfig.config?.Labels?.['org.opencontainers.image.revision'];
if (!this.gitCommit) {
throw new Error(`No git revision can be determined from the image`);
}
} catch (e) {
core.warning(e);
this.gitCommit = 'master';
}
core.debug(`docker.Install.downloadSourceImage gitCommit: ${this.gitCommit}`);
} else {
core.warning(`Docker engine not supported on ${platform}, only the Docker cli will be available`);
}
return dest;
}
private async downloadSourceArchive(component: 'docker' | 'docker-rootless-extras', src: InstallSourceArchive): Promise<string> {
const release: GitHubRelease = await Install.getRelease(src.version, this.githubToken);
this._version = release.tag_name.replace(/^(docker-)?v+/, '');
core.debug(`docker.Install.downloadSourceArchive version: ${this._version}`);
const downloadURL = this.downloadURL(component, this._version, src.channel);
core.info(`Downloading ${downloadURL}`);
const downloadPath = await tc.downloadTool(downloadURL);
core.debug(`docker.Install.downloadSourceArchive downloadPath: ${downloadPath}`);
let extractFolder;
if (os.platform() == 'win32') {
extractFolder = await tc.extractZip(downloadPath, extractFolder);
} else {
extractFolder = await tc.extractTar(downloadPath, extractFolder);
}
if (Util.isDirectory(path.join(extractFolder, component))) {
extractFolder = path.join(extractFolder, component);
}
core.debug(`docker.Install.downloadSourceArchive extractFolder: ${extractFolder}`);
return extractFolder;
}
public async install(): Promise<string> {
if (!this.toolDir) {
throw new Error('toolDir must be set. Run download first.');
@@ -303,7 +331,7 @@ export class Install {
};
await core.group('Starting lima instance', async () => {
const limaStartArgs = ['start', `--name=${this.limaInstanceName}`];
const limaStartArgs = ['start', `--name=${this.limaInstanceName}`, `--timeout=${process.env.LIMA_START_TIMEOUT ?? '15m'}`];
if (process.env.LIMA_START_ARGS) {
limaStartArgs.push(process.env.LIMA_START_ARGS);
}
@@ -395,7 +423,7 @@ export class Install {
// avoid killing it when the action finishes running. Even if detached,
// we also need to run dockerd in a subshell and unref the process so
// GitHub Action doesn't wait for it to finish.
`${sudo} env "PATH=$PATH" ${bashPath} << EOF
`${sudo} env "PATH=$PATH" "XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" ${bashPath} << EOF
( ${cmd} 2>&1 | tee "${this.runDir}/dockerd.log" ) &
EOF`,
[],
@@ -670,19 +698,17 @@ EOF`,
});
}
public static async getRelease(version: string): Promise<GitHubRelease> {
const url = `https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/docker-releases.json`;
const http: httpm.HttpClient = new httpm.HttpClient('docker-actions-toolkit');
const resp: httpm.HttpClientResponse = await http.get(url);
const body = await resp.readBody();
const statusCode = resp.message.statusCode || 500;
if (statusCode >= 400) {
throw new Error(`Failed to get Docker release ${version} from ${url} with status code ${statusCode}: ${body}`);
}
const releases = <Record<string, GitHubRelease>>JSON.parse(body);
public static async getRelease(version: string, githubToken?: string): Promise<GitHubRelease> {
const github = new GitHub({token: githubToken});
const releases = await github.releases('Docker', {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/docker-releases.json'
});
if (!releases[version]) {
if (!releases['v' + version]) {
throw new Error(`Cannot find Docker release ${version} in ${url}`);
throw new Error(`Cannot find Docker release ${version} in releases JSON`);
}
return releases['v' + version];
}
@@ -709,4 +735,20 @@ EOF`,
}
return res;
}
private async imageConfig(image: string, platform?: string): Promise<Image> {
const manifest = await this.regctl.manifestGet({
image: image,
platform: platform
});
const configDigest = manifest?.config?.digest;
if (!configDigest) {
throw new Error(`No config digest found for image ${image}`);
}
const blob = await this.regctl.blobGet({
repository: image,
digest: configDigest
});
return <Image>JSON.parse(blob);
}
}

View File

@@ -17,7 +17,7 @@
import crypto from 'crypto';
import fs from 'fs';
import he from 'he';
import jsyaml from 'js-yaml';
import {dump as yamldump} from 'js-yaml';
import os from 'os';
import path from 'path';
import {CreateArtifactRequest, FinalizeArtifactRequest, StringValue} from '@actions/artifact/lib/generated';
@@ -31,29 +31,47 @@ import {SummaryTableCell} from '@actions/core/lib/summary';
import * as github from '@actions/github';
import {GitHub as Octokit} from '@actions/github/lib/utils';
import {Context} from '@actions/github/lib/context';
import * as httpm from '@actions/http-client';
import {TransferProgressEvent} from '@azure/core-http';
import {BlobClient, BlobHTTPHeaders} from '@azure/storage-blob';
import {jwtDecode, JwtPayload} from 'jwt-decode';
import {Util} from './util';
import {BuildSummaryOpts, GitHubActionsRuntimeToken, GitHubActionsRuntimeTokenAC, GitHubRepo, UploadArtifactOpts, UploadArtifactResponse} from './types/github';
import {BuildSummaryOpts, GitHubActionsRuntimeToken, GitHubActionsRuntimeTokenAC, GitHubContentOpts, GitHubRelease, GitHubRepo, UploadArtifactOpts, UploadArtifactResponse} from './types/github';
export interface GitHubOpts {
token?: string;
}
export class GitHub {
private readonly githubToken?: string;
public readonly octokit: InstanceType<typeof Octokit>;
constructor(opts?: GitHubOpts) {
this.octokit = github.getOctokit(`${opts?.token}`);
this.githubToken = opts?.token || process.env.GITHUB_TOKEN;
this.octokit = github.getOctokit(`${this.githubToken}`);
}
public repoData(): Promise<GitHubRepo> {
return this.octokit.rest.repos.get({...github.context.repo}).then(response => response.data as GitHubRepo);
}
public async releases(name: string, opts: GitHubContentOpts): Promise<Record<string, GitHubRelease>> {
const url = `https://raw.githubusercontent.com/${opts.owner}/${opts.repo}/${opts.ref}/${opts.path}`;
const http: httpm.HttpClient = new httpm.HttpClient('docker-actions-toolkit');
// prettier-ignore
const httpResp: httpm.HttpClientResponse = await http.get(url, this.githubToken ? {
Authorization: `token ${this.githubToken}`
} : undefined);
const dt = await httpResp.readBody();
const statusCode = httpResp.message.statusCode || 500;
if (statusCode >= 400) {
throw new Error(`Failed to get ${name} releases from ${url} with status code ${statusCode}: ${dt}`);
}
return <Record<string, GitHubRelease>>JSON.parse(dt);
}
static get context(): Context {
return github.context;
}
@@ -233,10 +251,24 @@ export class GitHub {
return `<a href="${url}">${text}</a>` + (addEOL ? os.EOL : '');
};
const refsSize = Object.keys(opts.exportRes.refs).length;
const refsSize = opts.exportRes.refs.length;
const firstRef = refsSize > 0 ? opts.exportRes.refs?.[0] : undefined;
const firstSummary = firstRef ? opts.exportRes.summaries?.[firstRef] : undefined;
const dbcAccount = opts.driver === 'cloud' && opts.endpoint ? opts.endpoint?.replace(/^cloud:\/\//, '').split('/')[0] : undefined;
const sum = core.summary.addHeading('Docker Build summary', 2);
if (dbcAccount && refsSize === 1 && firstRef && firstSummary) {
const buildURL = GitHub.formatDBCBuildURL(dbcAccount, firstRef, firstSummary.defaultPlatform);
// prettier-ignore
sum.addRaw(`<p>`)
.addRaw(`For a detailed look at the build, you can check the results at:`)
.addRaw('</p>')
.addRaw(`<p>`)
.addRaw(`:whale: ${addLink(`<strong>${buildURL}</strong>`, buildURL)}`)
.addRaw(`</p>`);
}
if (opts.uploadRes) {
// we just need the last two parts of the URL as they are always relative
// to the workflow run URL otherwise URL could be broken if GitHub
@@ -246,17 +278,29 @@ export class GitHub {
// https://github.com/docker/actions-toolkit/issues/367
const artifactRelativeURL = `./${GitHub.runId}/${opts.uploadRes.url.split('/').slice(-2).join('/')}`;
if (dbcAccount && refsSize === 1) {
// prettier-ignore
sum.addRaw(`<p>`)
.addRaw(`You can also download the following build record archive and import it into Docker Desktop's Builds view. `)
.addBreak()
.addRaw(`Build records include details such as timing, dependencies, results, logs, traces, and other information about a build. `)
.addRaw(addLink('Learn more', 'https://www.docker.com/blog/new-beta-feature-deep-dive-into-github-actions-docker-builds-with-docker-desktop/?utm_source=github&utm_medium=actions'))
.addRaw('</p>')
} else {
// prettier-ignore
sum.addRaw(`<p>`)
.addRaw(`For a detailed look at the build, download the following build record archive and import it into Docker Desktop's Builds view. `)
.addBreak()
.addRaw(`Build records include details such as timing, dependencies, results, logs, traces, and other information about a build. `)
.addRaw(addLink('Learn more', 'https://www.docker.com/blog/new-beta-feature-deep-dive-into-github-actions-docker-builds-with-docker-desktop/?utm_source=github&utm_medium=actions'))
.addRaw('</p>')
}
// prettier-ignore
sum.addRaw(`<p>`)
.addRaw(`For a detailed look at the build, download the following build record archive and import it into Docker Desktop's Builds view. `)
.addBreak()
.addRaw(`Build records include details such as timing, dependencies, results, logs, traces, and other information about a build. `)
.addRaw(addLink('Learn more', 'https://www.docker.com/blog/new-beta-feature-deep-dive-into-github-actions-docker-builds-with-docker-desktop/?utm_source=github&utm_medium=actions'))
.addRaw('</p>')
.addRaw(`<p>`)
.addRaw(`:arrow_down: ${addLink(`<strong>${Util.stringToUnicodeEntities(opts.uploadRes.filename)}</strong>`, artifactRelativeURL)} (${Util.formatFileSize(opts.uploadRes.size)} - includes <strong>${refsSize} build record${refsSize > 1 ? 's' : ''}</strong>)`)
.addRaw(`</p>`);
} else {
} else if (opts.exportRes.summaries) {
// prettier-ignore
sum.addRaw(`<p>`)
.addRaw(`The following table provides a brief summary of your build.`)
@@ -269,56 +313,61 @@ export class GitHub {
// Feedback survey
sum.addRaw(`<p>`).addRaw(`Find this useful? `).addRaw(addLink('Let us know', 'https://docs.docker.com/feedback/gha-build-summary')).addRaw('</p>');
// Preview
sum.addRaw('<p>');
const summaryTableData: Array<Array<SummaryTableCell>> = [
[
{header: true, data: 'ID'},
{header: true, data: 'Name'},
{header: true, data: 'Status'},
{header: true, data: 'Cached'},
{header: true, data: 'Duration'}
]
];
let buildError: string | undefined;
for (const ref in opts.exportRes.summaries) {
if (Object.prototype.hasOwnProperty.call(opts.exportRes.summaries, ref)) {
const summary = opts.exportRes.summaries[ref];
if (opts.exportRes.summaries) {
// Preview
sum.addRaw('<p>');
const summaryTableData: Array<Array<SummaryTableCell>> = [
// prettier-ignore
summaryTableData.push([
{data: `<code>${ref.substring(0, 6).toUpperCase()}</code>`},
{data: `<strong>${Util.stringToUnicodeEntities(summary.name)}</strong>`},
{data: `${summary.status === 'completed' ? ':white_check_mark:' : summary.status === 'canceled' ? ':no_entry_sign:' : ':x:'} ${summary.status}`},
{data: `${summary.numCachedSteps > 0 ? Math.round((summary.numCachedSteps / summary.numTotalSteps) * 100) : 0}%`},
{data: summary.duration}
]);
if (summary.error) {
buildError = summary.error;
[
{header: true, data: 'ID'},
{header: true, data: 'Name'},
{header: true, data: 'Status'},
{header: true, data: 'Cached'},
{header: true, data: 'Duration'},
...(dbcAccount && refsSize > 1 ? [{header: true, data: 'Build result URL'}] : [])
]
];
let buildError: string | undefined;
for (const ref in opts.exportRes.summaries) {
if (Object.prototype.hasOwnProperty.call(opts.exportRes.summaries, ref)) {
const summary = opts.exportRes.summaries[ref];
// prettier-ignore
summaryTableData.push([
{data: `<code>${ref.substring(0, 6).toUpperCase()}</code>`},
{data: `<strong>${Util.stringToUnicodeEntities(summary.name)}</strong>`},
{data: `${summary.status === 'completed' ? ':white_check_mark:' : summary.status === 'canceled' ? ':no_entry_sign:' : ':x:'} ${summary.status}`},
{data: `${summary.numCachedSteps > 0 ? Math.round((summary.numCachedSteps / summary.numTotalSteps) * 100) : 0}%`},
{data: summary.duration},
...(dbcAccount && refsSize > 1 ? [{data: addLink(':whale: Open', GitHub.formatDBCBuildURL(dbcAccount, ref, summary.defaultPlatform))}] : [])
]);
if (summary.error) {
buildError = summary.error;
}
}
}
}
sum.addTable([...summaryTableData]);
sum.addRaw(`</p>`);
sum.addTable([...summaryTableData]);
sum.addRaw(`</p>`);
// Build error
if (buildError) {
sum.addRaw(`<blockquote>`);
if (Util.countLines(buildError) > 10) {
// prettier-ignore
sum
// Build error
if (buildError) {
sum.addRaw(`<blockquote>`);
if (Util.countLines(buildError) > 10) {
// prettier-ignore
sum
.addRaw(`<details><summary><strong>Error</strong></summary>`)
.addCodeBlock(he.encode(buildError), 'text')
.addRaw(`</details>`);
} else {
// prettier-ignore
sum
} else {
// prettier-ignore
sum
.addRaw(`<strong>Error</strong>`)
.addBreak()
.addRaw(`<p>`)
.addCodeBlock(he.encode(buildError), 'text')
.addRaw(`</p>`);
}
sum.addRaw(`</blockquote>`);
}
sum.addRaw(`</blockquote>`);
}
// Build inputs
@@ -326,7 +375,7 @@ export class GitHub {
// prettier-ignore
sum.addRaw(`<details><summary><strong>Build inputs</strong></summary>`)
.addCodeBlock(
jsyaml.dump(opts.inputs, {
yamldump(opts.inputs, {
indent: 2,
lineWidth: -1
}), 'yaml'
@@ -345,4 +394,8 @@ export class GitHub {
core.info(`Writing summary`);
await sum.addSeparator().write();
}
private static formatDBCBuildURL(account: string, ref: string, platform?: string): string {
return `https://app.docker.com/build/accounts/${account}/builds/${(platform ?? 'linux/amd64').replace('/', '-')}/${ref}`;
}
}

View File

@@ -1,174 +0,0 @@
/**
* Copyright 2023 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as httpm from '@actions/http-client';
import {Index} from './types/oci';
import os from 'os';
import * as core from '@actions/core';
import {Manifest} from './types/oci/manifest';
import * as tc from '@actions/tool-cache';
import fs from 'fs';
import {MEDIATYPE_IMAGE_CONFIG_V1, MEDIATYPE_IMAGE_INDEX_V1, MEDIATYPE_IMAGE_MANIFEST_V1} from './types/oci/mediatype';
import {MEDIATYPE_IMAGE_CONFIG_V1 as DOCKER_MEDIATYPE_IMAGE_CONFIG_V1, MEDIATYPE_IMAGE_MANIFEST_LIST_V2, MEDIATYPE_IMAGE_MANIFEST_V2} from './types/docker/mediatype';
import {DockerHub} from './dockerhub';
export class HubRepository {
private repo: string;
private token: string;
private static readonly http: httpm.HttpClient = new httpm.HttpClient('setup-docker-action');
private constructor(repository: string, token: string) {
this.repo = repository;
this.token = token;
}
public static async build(repository: string): Promise<HubRepository> {
const token = await this.getToken(repository);
return new HubRepository(repository, token);
}
public async getPlatformManifest(tagOrDigest: string, os?: string): Promise<Manifest> {
const index = await this.getManifest<Index>(tagOrDigest);
if (index.mediaType != MEDIATYPE_IMAGE_INDEX_V1 && index.mediaType != MEDIATYPE_IMAGE_MANIFEST_LIST_V2) {
core.error(`Unsupported image media type: ${index.mediaType}`);
throw new Error(`Unsupported image media type: ${index.mediaType}`);
}
const digest = HubRepository.getPlatformManifestDigest(index, os);
return await this.getManifest<Manifest>(digest);
}
// Unpacks the image layers and returns the path to the extracted image.
// Only OCI indexes/manifest list are supported for now.
public async extractImage(tag: string, destDir?: string): Promise<string> {
const manifest = await this.getPlatformManifest(tag);
const paths = manifest.layers.map(async layer => {
const url = this.blobUrl(layer.digest);
return await tc.downloadTool(url, undefined, undefined, {
authorization: `Bearer ${this.token}`
});
});
let files = await Promise.all(paths);
let extractFolder: string;
if (!destDir) {
extractFolder = await tc.extractTar(files[0]);
files = files.slice(1);
} else {
extractFolder = destDir;
}
await Promise.all(
files.map(async file => {
return await tc.extractTar(file, extractFolder);
})
);
fs.readdirSync(extractFolder).forEach(file => {
core.info(`extractImage(${this.repo}:${tag}) file: ${file}`);
});
return extractFolder;
}
private static async getToken(repo: string): Promise<string> {
const url = `https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull`;
const resp = await this.http.get(url);
const body = await resp.readBody();
const statusCode = resp.message.statusCode || 500;
if (statusCode != 200) {
throw DockerHub.parseError(resp, body);
}
const json = JSON.parse(body);
return json.token;
}
private blobUrl(digest: string): string {
return `https://registry-1.docker.io/v2/${this.repo}/blobs/${digest}`;
}
public async getManifest<T>(tagOrDigest: string): Promise<T> {
return await this.registryGet<T>(tagOrDigest, 'manifests', [MEDIATYPE_IMAGE_INDEX_V1, MEDIATYPE_IMAGE_MANIFEST_LIST_V2, MEDIATYPE_IMAGE_MANIFEST_V1, MEDIATYPE_IMAGE_MANIFEST_V2]);
}
public async getJSONBlob<T>(tagOrDigest: string): Promise<T> {
return await this.registryGet<T>(tagOrDigest, 'blobs', [MEDIATYPE_IMAGE_CONFIG_V1, DOCKER_MEDIATYPE_IMAGE_CONFIG_V1]);
}
private async registryGet<T>(tagOrDigest: string, endpoint: 'manifests' | 'blobs', accept: Array<string>): Promise<T> {
const url = `https://registry-1.docker.io/v2/${this.repo}/${endpoint}/${tagOrDigest}`;
const headers = {
Authorization: `Bearer ${this.token}`,
Accept: accept.join(', ')
};
const resp = await HubRepository.http.get(url, headers);
const body = await resp.readBody();
const statusCode = resp.message.statusCode || 500;
if (statusCode != 200) {
core.error(`registryGet(${this.repo}:${tagOrDigest}) failed: ${statusCode} ${body}`);
throw DockerHub.parseError(resp, body);
}
return <T>JSON.parse(body);
}
private static getPlatformManifestDigest(index: Index, osOverride?: string): string {
// This doesn't handle all possible platforms normalizations, but it's good enough for now.
let pos: string = osOverride || os.platform();
if (pos == 'win32') {
pos = 'windows';
}
let arch = os.arch();
if (arch == 'x64') {
arch = 'amd64';
}
let variant = '';
if (arch == 'arm') {
variant = 'v7';
}
const manifest = index.manifests.find(m => {
if (!m.platform) {
return false;
}
if (m.platform.os != pos) {
core.debug(`Skipping manifest ${m.digest} because of os: ${m.platform.os} != ${pos}`);
return false;
}
if (m.platform.architecture != arch) {
core.debug(`Skipping manifest ${m.digest} because of arch: ${m.platform.architecture} != ${arch}`);
return false;
}
if ((m.platform.variant || '') != variant) {
core.debug(`Skipping manifest ${m.digest} because of variant: ${m.platform.variant} != ${variant}`);
return false;
}
return true;
});
if (!manifest) {
core.error(`Cannot find manifest for ${pos}/${arch}/${variant}`);
throw new Error(`Cannot find manifest for ${pos}/${arch}/${variant}`);
}
return manifest.digest;
}
}

164
src/regclient/install.ts Normal file
View File

@@ -0,0 +1,164 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fs from 'fs';
import os from 'os';
import path from 'path';
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import * as semver from 'semver';
import * as util from 'util';
import {Cache} from '../cache';
import {Context} from '../context';
import {GitHub} from '../github';
import {GitHubRelease} from '../types/github';
import {DownloadVersion} from '../types/regclient/regclient';
export interface InstallOpts {
githubToken?: string;
}
export class Install {
private readonly githubToken: string | undefined;
constructor(opts?: InstallOpts) {
this.githubToken = opts?.githubToken || process.env.GITHUB_TOKEN;
}
/*
* Download regclient binary from GitHub release
* @param v: version semver version or latest
* @param ghaNoCache: disable binary caching in GitHub Actions cache backend
* @returns path to the regclient binary
*/
public async download(v: string, ghaNoCache?: boolean): Promise<string> {
const version: DownloadVersion = await Install.getDownloadVersion(v);
core.debug(`Install.download version: ${version.version}`);
const release: GitHubRelease = await Install.getRelease(version, this.githubToken);
core.debug(`Install.download release tag name: ${release.tag_name}`);
const vspec = await this.vspec(release.tag_name);
core.debug(`Install.download vspec: ${vspec}`);
const c = semver.clean(vspec) || '';
if (!semver.valid(c)) {
throw new Error(`Invalid regclient version "${vspec}".`);
}
const installCache = new Cache({
htcName: 'regctl-dl-bin',
htcVersion: vspec,
baseCacheDir: path.join(os.homedir(), '.bin'),
cacheFile: os.platform() == 'win32' ? 'regctl.exe' : 'regctl',
ghaNoCache: ghaNoCache
});
const cacheFoundPath = await installCache.find();
if (cacheFoundPath) {
core.info(`regctl binary found in ${cacheFoundPath}`);
return cacheFoundPath;
}
const downloadURL = util.format(version.downloadURL, vspec, this.filename());
core.info(`Downloading ${downloadURL}`);
const htcDownloadPath = await tc.downloadTool(downloadURL, undefined, this.githubToken);
core.debug(`Install.download htcDownloadPath: ${htcDownloadPath}`);
const cacheSavePath = await installCache.save(htcDownloadPath);
core.info(`Cached to ${cacheSavePath}`);
return cacheSavePath;
}
public async install(binPath: string, dest?: string): Promise<string> {
dest = dest || Context.tmpDir();
const binDir = path.join(dest, 'regctl-bin');
if (!fs.existsSync(binDir)) {
fs.mkdirSync(binDir, {recursive: true});
}
const binName: string = os.platform() == 'win32' ? 'regctl.exe' : 'regctl';
const regctlPath: string = path.join(binDir, binName);
fs.copyFileSync(binPath, regctlPath);
core.info('Fixing perms');
fs.chmodSync(regctlPath, '0755');
core.addPath(binDir);
core.info('Added regctl to PATH');
core.info(`Binary path: ${regctlPath}`);
return regctlPath;
}
private filename(): string {
let arch: string;
switch (os.arch()) {
case 'x64': {
arch = 'amd64';
break;
}
case 'ppc64': {
arch = 'ppc64le';
break;
}
case 'arm': {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const arm_version = (process.config.variables as any).arm_version;
arch = arm_version ? 'armv' + arm_version : 'arm';
break;
}
default: {
arch = os.arch();
break;
}
}
const platform: string = os.platform() == 'win32' ? 'windows' : os.platform();
const ext: string = os.platform() == 'win32' ? '.exe' : '';
return util.format('regctl-%s-%s%s', platform, arch, ext);
}
private async vspec(version: string): Promise<string> {
const v = version.replace(/^v+|v+$/g, '');
core.info(`Use ${v} version spec cache key for ${version}`);
return v;
}
public static async getDownloadVersion(v: string): Promise<DownloadVersion> {
return {
version: v,
downloadURL: 'https://github.com/regclient/regclient/releases/download/v%s/%s',
contentOpts: {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/regclient-releases.json'
}
};
}
public static async getRelease(version: DownloadVersion, githubToken?: string): Promise<GitHubRelease> {
const github = new GitHub({token: githubToken});
const releases = await github.releases('regclient', version.contentOpts);
if (!releases[version.version]) {
throw new Error(`Cannot find regclient release ${version.version} in releases JSON`);
}
return releases[version.version];
}
}

128
src/regclient/regctl.ts Normal file
View File

@@ -0,0 +1,128 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as core from '@actions/core';
import * as semver from 'semver';
import {Exec} from '../exec';
import {Manifest} from '../types/oci/manifest';
export interface RegctlOpts {
binPath?: string;
}
export interface RegctlBlobGetOpts {
repository: string;
digest: string;
}
export interface RegctlManifestGetOpts {
image: string;
platform?: string;
}
export class Regctl {
private readonly binPath: string;
private _version: string;
private _versionOnce: boolean;
constructor(opts?: RegctlOpts) {
this.binPath = opts?.binPath || 'regctl';
this._version = '';
this._versionOnce = false;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public async blobGet(opts: RegctlBlobGetOpts): Promise<any> {
return await Exec.getExecOutput(this.binPath, ['blob', 'get', opts.repository, opts.digest], {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
return res.stdout;
});
}
public async manifestGet(opts: RegctlManifestGetOpts): Promise<Manifest> {
return await Exec.getExecOutput(this.binPath, ['manifest', 'get', opts.image, `--platform=${opts.platform ?? 'local'}`, `--format={{json .}}`], {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
return <Manifest>JSON.parse(res.stdout.trim());
});
}
public async isAvailable(): Promise<boolean> {
const ok: boolean = await Exec.getExecOutput(this.binPath, [], {
ignoreReturnCode: true,
silent: true
})
.then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
core.debug(`Regctl.isAvailable cmd err: ${res.stderr.trim()}`);
return false;
}
return res.exitCode == 0;
})
.catch(error => {
core.debug(`Regctl.isAvailable error: ${error}`);
return false;
});
core.debug(`Regctl.isAvailable: ${ok}`);
return ok;
}
public async version(): Promise<string> {
if (this._versionOnce) {
return this._version;
}
this._versionOnce = true;
this._version = await Exec.getExecOutput(this.binPath, ['version', '--format', '{{.VCSTag}}'], {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
return res.stdout.trim();
});
return this._version;
}
public async printVersion() {
await Exec.exec(this.binPath, ['version'], {
failOnStdErr: false
});
}
public async versionSatisfies(range: string, version?: string): Promise<boolean> {
const ver = version ?? (await this.version());
if (!ver) {
core.debug(`Regctl.versionSatisfies false: undefined version`);
return false;
}
const res = semver.satisfies(ver, range) || /^[0-9a-f]{7}$/.exec(ver) !== null;
core.debug(`Regctl.versionSatisfies ${ver} statisfies ${range}: ${res}`);
return res;
}
}

388
src/sigstore/sigstore.ts Normal file
View File

@@ -0,0 +1,388 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {X509Certificate} from 'crypto';
import fs from 'fs';
import path from 'path';
import {Endpoints} from '@actions/attest/lib/endpoints';
import * as core from '@actions/core';
import {signPayload} from '@actions/attest/lib/sign';
import {bundleFromJSON, bundleToJSON} from '@sigstore/bundle';
import {Attestation} from '@actions/attest';
import {Bundle} from '@sigstore/sign';
import {Cosign} from '../cosign/cosign';
import {Exec} from '../exec';
import {GitHub} from '../github';
import {ImageTools} from '../buildx/imagetools';
import {MEDIATYPE_PAYLOAD as INTOTO_MEDIATYPE_PAYLOAD, Subject} from '../types/intoto/intoto';
import {FULCIO_URL, REKOR_URL, SEARCH_URL, TSASERVER_URL} from '../types/sigstore/sigstore';
export interface SignAttestationManifestsOpts {
imageNames: Array<string>;
imageDigest: string;
noTransparencyLog?: boolean;
}
export interface SignAttestationManifestsResult extends Attestation {
imageName: string;
}
export interface VerifySignedManifestsOpts {
certificateIdentityRegexp: string;
retries?: number;
}
export interface VerifySignedManifestsResult {
cosignArgs: Array<string>;
signatureManifestDigest: string;
}
export interface SignProvenanceBlobsOpts {
localExportDir: string;
name?: string;
noTransparencyLog?: boolean;
}
export interface SignProvenanceBlobsResult extends Attestation {
bundlePath: string;
subjects: Array<Subject>;
}
export interface VerifySignedArtifactsOpts {
certificateIdentityRegexp: string;
}
export interface VerifySignedArtifactsResult {
bundlePath: string;
cosignArgs: Array<string>;
}
export interface SigstoreOpts {
cosign?: Cosign;
imageTools?: ImageTools;
}
export class Sigstore {
private readonly cosign: Cosign;
private readonly imageTools: ImageTools;
constructor(opts?: SigstoreOpts) {
this.cosign = opts?.cosign || new Cosign();
this.imageTools = opts?.imageTools || new ImageTools();
}
public async signAttestationManifests(opts: SignAttestationManifestsOpts): Promise<Record<string, SignAttestationManifestsResult>> {
if (!(await this.cosign.isAvailable())) {
throw new Error('Cosign is required to sign attestation manifests');
}
const result: Record<string, SignAttestationManifestsResult> = {};
try {
if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
throw new Error('missing "id-token" permission. Please add "permissions: id-token: write" to your workflow.');
}
const endpoints = this.signingEndpoints(opts.noTransparencyLog);
core.info(`Using Sigstore signing endpoint: ${endpoints.fulcioURL}`);
const noTransparencyLog = Sigstore.noTransparencyLog(opts.noTransparencyLog);
for (const imageName of opts.imageNames) {
const attestationDigests = await this.imageTools.attestationDigests(`${imageName}@${opts.imageDigest}`);
for (const attestationDigest of attestationDigests) {
const attestationRef = `${imageName}@${attestationDigest}`;
await core.group(`Signing attestation manifest ${attestationRef}`, async () => {
// prettier-ignore
const cosignArgs = [
'--verbose',
'sign',
'--yes',
'--oidc-provider', 'github-actions',
'--registry-referrers-mode', 'oci-1-1',
'--new-bundle-format',
'--use-signing-config'
];
if (noTransparencyLog) {
cosignArgs.push('--tlog-upload=false');
}
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
const execRes = await Exec.getExecOutput('cosign', [...cosignArgs, attestationRef], {
ignoreReturnCode: true,
silent: true,
env: Object.assign({}, process.env, {
COSIGN_EXPERIMENTAL: '1'
}) as {
[key: string]: string;
}
});
const signResult = Cosign.parseCommandOutput(execRes.stderr.trim());
if (execRes.exitCode != 0) {
if (signResult.errors && signResult.errors.length > 0) {
const errorMessages = signResult.errors.map(e => `- [${e.code}] ${e.message} : ${e.detail}`).join('\n');
throw new Error(`Cosign sign command failed with errors:\n${errorMessages}`);
} else {
throw new Error(`Cosign sign command failed with exit code ${execRes.exitCode}`);
}
}
const attest = Sigstore.toAttestation(bundleFromJSON(signResult.bundle));
if (attest.tlogID) {
core.info(`Uploaded to Rekor transparency log: ${SEARCH_URL}?logIndex=${attest.tlogID}`);
}
core.info(`Signature manifest pushed: https://oci.dag.dev/?referrers=${attestationRef}`);
result[attestationRef] = {
...attest,
imageName: imageName
};
});
}
}
} catch (err) {
throw new Error(`Signing BuildKit attestation manifests failed: ${(err as Error).message}`);
}
return result;
}
public async verifySignedManifests(opts: VerifySignedManifestsOpts, signed: Record<string, SignAttestationManifestsResult>): Promise<Record<string, VerifySignedManifestsResult>> {
const result: Record<string, VerifySignedManifestsResult> = {};
const retries = opts.retries ?? 15;
if (!(await this.cosign.isAvailable())) {
throw new Error('Cosign is required to verify signed manifests');
}
let lastError: Error | undefined;
for (const [attestationRef, signedRes] of Object.entries(signed)) {
await core.group(`Verifying signature of ${attestationRef}`, async () => {
// prettier-ignore
const cosignArgs = [
'--verbose',
'verify',
'--experimental-oci11',
'--new-bundle-format',
'--certificate-oidc-issuer', 'https://token.actions.githubusercontent.com',
'--certificate-identity-regexp', opts.certificateIdentityRegexp
];
if (!signedRes.tlogID) {
// skip tlog verification but still verify the signed timestamp
cosignArgs.push('--use-signed-timestamps', '--insecure-ignore-tlog');
}
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
for (let attempt = 0; attempt < retries; attempt++) {
const execRes = await Exec.getExecOutput('cosign', [...cosignArgs, attestationRef], {
ignoreReturnCode: true,
silent: true,
env: Object.assign({}, process.env, {
COSIGN_EXPERIMENTAL: '1'
}) as {[key: string]: string}
});
const verifyResult = Cosign.parseCommandOutput(execRes.stderr.trim());
if (execRes.exitCode === 0) {
result[attestationRef] = {
cosignArgs: cosignArgs,
signatureManifestDigest: verifyResult.signatureManifestDigest!
};
lastError = undefined;
core.info(`Signature manifest verified: https://oci.dag.dev/?image=${signedRes.imageName}@${verifyResult.signatureManifestDigest}`);
break;
} else {
if (verifyResult.errors && verifyResult.errors.length > 0) {
const errorMessages = verifyResult.errors.map(e => `- [${e.code}] ${e.message} : ${e.detail}`).join('\n');
lastError = new Error(`Cosign verify command failed with errors:\n${errorMessages}`);
if (verifyResult.errors.some(e => e.code === 'MANIFEST_UNKNOWN')) {
core.info(`Cosign verify command failed with MANIFEST_UNKNOWN, retrying attempt ${attempt + 1}/${retries}...\n${errorMessages}`);
await new Promise(res => setTimeout(res, Math.pow(2, attempt) * 100));
} else {
throw lastError;
}
} else {
throw new Error(`Cosign verify command failed: ${execRes.stderr}`);
}
}
}
});
}
if (lastError) {
throw lastError;
}
return result;
}
public async signProvenanceBlobs(opts: SignProvenanceBlobsOpts): Promise<Record<string, SignProvenanceBlobsResult>> {
const result: Record<string, SignProvenanceBlobsResult> = {};
try {
if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
throw new Error('missing "id-token" permission. Please add "permissions: id-token: write" to your workflow.');
}
const endpoints = this.signingEndpoints(opts.noTransparencyLog);
core.info(`Using Sigstore signing endpoint: ${endpoints.fulcioURL}`);
const provenanceBlobs = Sigstore.getProvenanceBlobs(opts);
for (const p of Object.keys(provenanceBlobs)) {
await core.group(`Signing ${p}`, async () => {
const blob = provenanceBlobs[p];
const bundlePath = path.join(path.dirname(p), `${opts.name ?? 'provenance'}.sigstore.json`);
const subjects = Sigstore.getProvenanceSubjects(blob);
if (subjects.length === 0) {
core.warning(`No subjects found in provenance ${p}, skip signing.`);
return;
}
const bundle = await signPayload(
{
body: blob,
type: INTOTO_MEDIATYPE_PAYLOAD
},
endpoints
);
const attest = Sigstore.toAttestation(bundle);
core.info(`Provenance blob signed for:`);
for (const subject of subjects) {
const [digestAlg, digestValue] = Object.entries(subject.digest)[0] || [];
core.info(` - ${subject.name} (${digestAlg}:${digestValue})`);
}
if (attest.tlogID) {
core.info(`Attestation signature uploaded to Rekor transparency log: ${SEARCH_URL}?logIndex=${attest.tlogID}`);
}
core.info(`Writing Sigstore bundle to: ${bundlePath}`);
fs.writeFileSync(bundlePath, JSON.stringify(attest.bundle, null, 2), {
encoding: 'utf-8'
});
result[p] = {
...attest,
bundlePath: bundlePath,
subjects: subjects
};
});
}
} catch (err) {
throw new Error(`Signing BuildKit provenance blobs failed: ${(err as Error).message}`);
}
return result;
}
public async verifySignedArtifacts(opts: VerifySignedArtifactsOpts, signed: Record<string, SignProvenanceBlobsResult>): Promise<Record<string, VerifySignedArtifactsResult>> {
const result: Record<string, VerifySignedArtifactsResult> = {};
if (!(await this.cosign.isAvailable())) {
throw new Error('Cosign is required to verify signed artifacts');
}
for (const [provenancePath, signedRes] of Object.entries(signed)) {
const baseDir = path.dirname(provenancePath);
await core.group(`Verifying signature bundle ${signedRes.bundlePath}`, async () => {
for (const subject of signedRes.subjects) {
const artifactPath = path.join(baseDir, subject.name);
core.info(`Verifying signed artifact ${artifactPath}`);
// prettier-ignore
const cosignArgs = [
'verify-blob-attestation',
'--new-bundle-format',
'--certificate-oidc-issuer', 'https://token.actions.githubusercontent.com',
'--certificate-identity-regexp', opts.certificateIdentityRegexp
]
if (!signedRes.tlogID) {
// if there is no tlog entry, we skip tlog verification but still verify the signed timestamp
cosignArgs.push('--use-signed-timestamps', '--insecure-ignore-tlog');
}
const execRes = await Exec.getExecOutput('cosign', [...cosignArgs, '--bundle', signedRes.bundlePath, artifactPath], {
ignoreReturnCode: true
});
if (execRes.stderr.length > 0 && execRes.exitCode != 0) {
throw new Error(execRes.stderr);
}
result[artifactPath] = {
bundlePath: signedRes.bundlePath,
cosignArgs: cosignArgs
};
}
});
}
return result;
}
private signingEndpoints(noTransparencyLog?: boolean): Endpoints {
noTransparencyLog = Sigstore.noTransparencyLog(noTransparencyLog);
core.info(`Upload to transparency log: ${noTransparencyLog ? 'disabled' : 'enabled'}`);
return {
fulcioURL: FULCIO_URL,
rekorURL: noTransparencyLog ? undefined : REKOR_URL,
tsaServerURL: TSASERVER_URL
};
}
private static noTransparencyLog(noTransparencyLog?: boolean): boolean {
return noTransparencyLog ?? GitHub.context.payload.repository?.private;
}
private static getProvenanceBlobs(opts: SignProvenanceBlobsOpts): Record<string, Buffer> {
// For single platform build
const singleProvenance = path.join(opts.localExportDir, 'provenance.json');
if (fs.existsSync(singleProvenance)) {
return {[singleProvenance]: fs.readFileSync(singleProvenance)};
}
// For multi-platform build
const dirents = fs.readdirSync(opts.localExportDir, {withFileTypes: true});
const platformFolders = dirents.filter(dirent => dirent.isDirectory());
if (platformFolders.length > 0 && platformFolders.length === dirents.length && platformFolders.every(platformFolder => fs.existsSync(path.join(opts.localExportDir, platformFolder.name, 'provenance.json')))) {
const result: Record<string, Buffer> = {};
for (const platformFolder of platformFolders) {
const p = path.join(opts.localExportDir, platformFolder.name, 'provenance.json');
result[p] = fs.readFileSync(p);
}
return result;
}
throw new Error(`No valid provenance.json found in ${opts.localExportDir}`);
}
private static getProvenanceSubjects(body: Buffer): Array<Subject> {
const statement = JSON.parse(body.toString()) as {
subject: Array<{name: string; digest: Record<string, string>}>;
};
return statement.subject.map(s => ({
name: s.name,
digest: s.digest
}));
}
// https://github.com/actions/toolkit/blob/d3ab50471b4ff1d1274dffb90ef9c5d9949b4886/packages/attest/src/attest.ts#L90
private static toAttestation(bundle: Bundle): Attestation {
let certBytes: Buffer;
switch (bundle.verificationMaterial.content.$case) {
case 'x509CertificateChain':
certBytes = bundle.verificationMaterial.content.x509CertificateChain.certificates[0].rawBytes;
break;
case 'certificate':
certBytes = bundle.verificationMaterial.content.certificate.rawBytes;
break;
default:
throw new Error('Bundle must contain an x509 certificate');
}
const signingCert = new X509Certificate(certBytes);
// Collect transparency log ID if available
const tlogEntries = bundle.verificationMaterial.tlogEntries;
const tlogID = tlogEntries.length > 0 ? tlogEntries[0].logIndex : undefined;
return {
bundle: bundleToJSON(bundle),
certificate: signingCert.toString(),
tlogID: tlogID
};
}
}

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
import {GitHub} from './github';
import {Buildx} from './buildx/buildx';
import {Build as BuildxBuild} from './buildx/build';
import {Bake as BuildxBake} from './buildx/bake';
@@ -22,8 +23,13 @@ import {Builder} from './buildx/builder';
import {BuildKit} from './buildkit/buildkit';
import {Compose} from './compose/compose';
import {Install as ComposeInstall} from './compose/install';
import {Cosign} from './cosign/cosign';
import {Install as CosignInstall} from './cosign/install';
import {Regctl} from './regclient/regctl';
import {Install as RegctlInstall} from './regclient/install';
import {Undock} from './undock/undock';
import {GitHub} from './github';
import {Install as UndockInstall} from './undock/install';
import {Sigstore} from './sigstore/sigstore';
export interface ToolkitOpts {
/**
@@ -43,7 +49,13 @@ export class Toolkit {
public buildkit: BuildKit;
public compose: Compose;
public composeInstall: ComposeInstall;
public cosign: Cosign;
public cosignInstall: CosignInstall;
public regctl: Regctl;
public regctlInstall: RegctlInstall;
public sigstore: Sigstore;
public undock: Undock;
public undockInstall: UndockInstall;
constructor(opts: ToolkitOpts = {}) {
this.github = new GitHub({token: opts.githubToken});
@@ -55,6 +67,12 @@ export class Toolkit {
this.buildkit = new BuildKit({buildx: this.buildx});
this.compose = new Compose();
this.composeInstall = new ComposeInstall();
this.cosign = new Cosign();
this.cosignInstall = new CosignInstall({buildx: this.buildx});
this.regctl = new Regctl();
this.regctlInstall = new RegctlInstall();
this.sigstore = new Sigstore();
this.undock = new Undock();
this.undockInstall = new UndockInstall();
}
}

View File

@@ -34,13 +34,24 @@ export interface NodeInfo extends Node {
buildkit?: string;
features?: Record<string, boolean>;
labels?: Record<string, string>;
devices?: Array<Device>;
gcPolicy?: Array<GCPolicy>;
files?: Record<string, string>;
}
export interface Device {
name?: string;
annotations?: Record<string, string>;
autoAllow?: boolean;
onDemand?: boolean;
}
export interface GCPolicy {
all?: boolean;
filter?: string[];
keepDuration?: string;
keepBytes?: string;
keepBytes?: string; // deprecated, use reservedSpace instead
reservedSpace?: string;
maxUsedSpace?: string;
minFreeSpace?: string;
}

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
import {GitHubContentOpts} from '../github';
export interface Cert {
cacert?: string;
cert?: string;
@@ -24,7 +26,7 @@ export interface DownloadVersion {
key: string;
version: string;
downloadURL: string;
releasesURL: string;
contentOpts: GitHubContentOpts;
}
export interface LocalRefsOpts {

View File

@@ -14,31 +14,123 @@
* limitations under the License.
*/
export interface ExportRecordOpts {
refs: Array<string>;
image?: string;
export interface InspectOpts {
ref?: string;
builder?: string;
}
export interface ExportRecordResponse {
export type BuildStatus = 'completed' | 'running' | 'failed' | 'canceled';
export interface InspectResponse {
Name: string;
Ref: string;
Context?: string;
Dockerfile?: string;
VCSRepository?: string;
VCSRevision?: string;
Target?: string;
Platform?: Array<string>;
KeepGitDir?: boolean;
NamedContexts?: Array<InspectKeyValueOutput>;
StartedAt?: Date;
CompletedAt?: Date;
Duration: number;
Status: BuildStatus;
Error?: InspectErrorOutput;
NumCompletedSteps: number;
NumTotalSteps: number;
NumCachedSteps: number;
BuildArgs?: Array<InspectKeyValueOutput>;
Labels?: Array<InspectKeyValueOutput>;
Config?: InspectConfigOutput;
Materials?: InspectMaterialOutput[];
Attachments?: InspectAttachmentOutput[];
Errors?: Array<string>;
}
export interface InspectConfigOutput {
Network?: string;
ExtraHosts?: Array<string>;
Hostname?: string;
CgroupParent?: string;
ImageResolveMode?: string;
MultiPlatform?: boolean;
NoCache?: boolean;
NoCacheFilter?: Array<string>;
ShmSize?: string;
Ulimit?: string;
CacheMountNS?: string;
DockerfileCheckConfig?: string;
SourceDateEpoch?: string;
SandboxHostname?: string;
RestRaw?: Array<InspectKeyValueOutput>;
}
export interface InspectMaterialOutput {
URI?: string;
Digests?: Array<string>;
}
export interface InspectAttachmentOutput {
Digest?: string;
Platform?: string;
Type?: string;
}
export interface InspectErrorOutput {
Code?: number;
Message?: string;
Name?: string;
Logs?: Array<string>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Sources?: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Stack?: any;
}
export interface InspectKeyValueOutput {
Name?: string;
Value?: string;
}
export interface ExportOpts {
refs: Array<string>;
noSummaries?: boolean;
image?: string;
useContainer?: boolean;
}
export interface ExportResponse {
dockerbuildFilename: string;
dockerbuildSize: number;
summaries: Summaries;
builderName: string;
nodeName: string;
refs: Array<string>;
summaries?: Summaries;
}
export interface Summaries {
[ref: string]: RecordSummary;
[ref: string]: Summary;
}
export interface RecordSummary {
export interface Summary {
name: string;
status: string;
duration: string;
numCachedSteps: number;
numTotalSteps: number;
numCompletedSteps: number;
frontendAttrs: Record<string, string>;
frontendAttrs?: Record<string, string>;
defaultPlatform?: string;
error?: string;
}

View File

@@ -0,0 +1,28 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Versioned} from '../oci/versioned';
import {Descriptor} from '../oci/descriptor';
import {Digest} from '../oci/digest';
// https://github.com/docker/buildx/blob/62857022a08552bee5cad0c3044a9a3b185f0b32/util/imagetools/printers.go#L109-L123
export interface Manifest extends Versioned {
mediaType?: string;
digest: Digest;
size: number;
manifests?: Descriptor[];
annotations?: Record<string, string>;
}

View File

@@ -14,9 +14,11 @@
* limitations under the License.
*/
import {GitHubContentOpts} from '../github';
export interface DownloadVersion {
key: string;
version: string;
downloadURL: string;
releasesURL: string;
contentOpts: GitHubContentOpts;
}

View File

@@ -0,0 +1,23 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {GitHubContentOpts} from '../github';
export interface DownloadVersion {
version: string;
downloadURL: string;
contentOpts: GitHubContentOpts;
}

View File

@@ -19,7 +19,7 @@ import {components as OctoOpenApiTypes} from '@octokit/openapi-types';
import {JwtPayload} from 'jwt-decode';
import {BakeDefinition} from './buildx/bake';
import {ExportRecordResponse} from './buildx/history';
import {ExportResponse} from './buildx/history';
export interface GitHubRelease {
id: number;
@@ -28,6 +28,13 @@ export interface GitHubRelease {
assets: Array<string>;
}
export interface GitHubContentOpts {
owner: string;
repo: string;
ref?: string;
path: string;
}
export type GitHubRepo = OctoOpenApiTypes['schemas']['repository'];
export interface GitHubActionsRuntimeToken extends JwtPayload {
@@ -57,9 +64,12 @@ export interface UploadArtifactResponse {
}
export interface BuildSummaryOpts {
exportRes: ExportRecordResponse;
exportRes: ExportResponse;
uploadRes?: UploadArtifactResponse;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
inputs?: any;
bakeDefinition?: BakeDefinition;
// builder options
driver?: string;
endpoint?: string;
}

View File

@@ -18,3 +18,9 @@
export const MEDIATYPE_PAYLOAD = 'application/vnd.in-toto+json';
export const MEDIATYPE_PREDICATE = 'in-toto.io/predicate-type';
// https://github.com/in-toto/in-toto-golang/blob/0a34c087cedcc36de065b4fccb7cf7c9bc16e29f/in_toto/attestations.go#L30-L42
export interface Subject {
name: string;
digest: Record<string, string>;
}

View File

@@ -0,0 +1,23 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {GitHubContentOpts} from '../github';
export interface DownloadVersion {
version: string;
downloadURL: string;
contentOpts: GitHubContentOpts;
}

View File

@@ -0,0 +1,20 @@
/**
* Copyright 2025 actions-toolkit authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const FULCIO_URL = 'https://fulcio.sigstore.dev';
export const REKOR_URL = 'https://rekor.sigstore.dev';
export const TSASERVER_URL = 'https://timestamp.sigstore.dev';
export const SEARCH_URL = 'https://search.sigstore.dev';

View File

@@ -14,8 +14,10 @@
* limitations under the License.
*/
import {GitHubContentOpts} from '../github';
export interface DownloadVersion {
version: string;
downloadURL: string;
releasesURL: string;
contentOpts: GitHubContentOpts;
}

View File

@@ -18,18 +18,28 @@ import fs from 'fs';
import os from 'os';
import path from 'path';
import * as core from '@actions/core';
import * as httpm from '@actions/http-client';
import * as tc from '@actions/tool-cache';
import * as semver from 'semver';
import * as util from 'util';
import {Cache} from '../cache';
import {Context} from '../context';
import {GitHub} from '../github';
import {GitHubRelease} from '../types/github';
import {DownloadVersion} from '../types/undock/undock';
export interface InstallOpts {
githubToken?: string;
}
export class Install {
private readonly githubToken: string | undefined;
constructor(opts?: InstallOpts) {
this.githubToken = opts?.githubToken || process.env.GITHUB_TOKEN;
}
/*
* Download undock binary from GitHub release
* @param v: version semver version or latest
@@ -40,7 +50,7 @@ export class Install {
const version: DownloadVersion = await Install.getDownloadVersion(v);
core.debug(`Install.download version: ${version.version}`);
const release: GitHubRelease = await Install.getRelease(version);
const release: GitHubRelease = await Install.getRelease(version, this.githubToken);
core.debug(`Install.download release tag name: ${release.tag_name}`);
const vspec = await this.vspec(release.tag_name);
@@ -61,14 +71,14 @@ export class Install {
const cacheFoundPath = await installCache.find();
if (cacheFoundPath) {
core.info(`Unodck binary found in ${cacheFoundPath}`);
core.info(`Undock binary found in ${cacheFoundPath}`);
return cacheFoundPath;
}
const downloadURL = util.format(version.downloadURL, vspec, this.filename(vspec));
core.info(`Downloading ${downloadURL}`);
const htcDownloadPath = await tc.downloadTool(downloadURL);
const htcDownloadPath = await tc.downloadTool(downloadURL, undefined, this.githubToken);
core.debug(`Install.download htcDownloadPath: ${htcDownloadPath}`);
let htcExtPath: string;
@@ -102,7 +112,7 @@ export class Install {
fs.chmodSync(undockPath, '0755');
core.addPath(binDir);
core.info('Added Unodck to PATH');
core.info('Added Undock to PATH');
core.info(`Binary path: ${undockPath}`);
return undockPath;
@@ -145,21 +155,20 @@ export class Install {
return {
version: v,
downloadURL: 'https://github.com/crazy-max/undock/releases/download/v%s/%s',
releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/undock-releases.json'
contentOpts: {
owner: 'docker',
repo: 'actions-toolkit',
ref: 'main',
path: '.github/undock-releases.json'
}
};
}
public static async getRelease(version: DownloadVersion): Promise<GitHubRelease> {
const http: httpm.HttpClient = new httpm.HttpClient('docker-actions-toolkit');
const resp: httpm.HttpClientResponse = await http.get(version.releasesURL);
const body = await resp.readBody();
const statusCode = resp.message.statusCode || 500;
if (statusCode >= 400) {
throw new Error(`Failed to get Undock releases from ${version.releasesURL} with status code ${statusCode}: ${body}`);
}
const releases = <Record<string, GitHubRelease>>JSON.parse(body);
public static async getRelease(version: DownloadVersion, githubToken?: string): Promise<GitHubRelease> {
const github = new GitHub({token: githubToken});
const releases = await github.releases('Undock', version.contentOpts);
if (!releases[version.version]) {
throw new Error(`Cannot find Undock release ${version.version} in ${version.releasesURL}`);
throw new Error(`Cannot find Undock release ${version.version} in releases JSON`);
}
return releases[version.version];
}

View File

@@ -204,4 +204,20 @@ export class Util {
const rcp = path.resolve(childPath);
return rcp.startsWith(rpp.endsWith(path.sep) ? rpp : `${rpp}${path.sep}`);
}
public static formatDuration(ns: number): string {
if (ns === 0) return '0s';
const totalSeconds = Math.floor(ns / 1e9);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
const parts: string[] = [];
if (hours) parts.push(`${hours}h`);
if (minutes) parts.push(`${minutes}m`);
if (seconds || parts.length === 0) parts.push(`${seconds}s`);
return parts.join('');
}
}

7535
yarn.lock

File diff suppressed because it is too large Load Diff