Compare commits

...

607 Commits

Author SHA1 Message Date
CrazyMax
79a6dd0432 Merge pull request #938 from crazy-max/bake-def-envs
Some checks failed
publish / publish (push) Has been cancelled
buildx(bake): merge existing env vars when parsing definition
2026-01-14 14:03:57 +01:00
CrazyMax
306d954be2 buildx(bake): merge existing env vars when parsing definition
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-14 13:51:42 +01:00
CrazyMax
65261f5a19 Merge pull request #937 from crazy-max/sigstore-platform
sigstore: opt to verify attestation manifest for specific platform
2026-01-14 12:59:10 +01:00
CrazyMax
a5dc8e7614 sigstore: opt to verify attestation manifest for specific platform
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-14 12:23:11 +01:00
CrazyMax
c9ffda6adf Merge pull request #936 from crazy-max/oci-defaultPlatform
oci: defaultPlatform function
2026-01-14 12:01:47 +01:00
CrazyMax
af989cc324 oci: defaultPlatform function
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-14 11:49:45 +01:00
CrazyMax
18f82ba384 Merge pull request #935 from crazy-max/imagetools-filter-platform
buildx(imagetools): opt to filter attestation manifests by platform
2026-01-14 11:12:59 +01:00
CrazyMax
f136d06171 buildx(imagetools): opt to filter attestation manifests by platform
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-14 10:52:51 +01:00
CrazyMax
6e1b0e6179 Merge pull request #934 from docker/sigstore-verify-retry
Some checks failed
publish / publish (push) Has been cancelled
sigstore: make retry on manifest unknown optional
2026-01-13 17:33:53 +01:00
CrazyMax
b4f34ed319 sigstore: make retry on manifest unknown optional
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-13 16:21:46 +01:00
CrazyMax
ba992bb822 Merge pull request #933 from crazy-max/sigstore-test-sign
Some checks failed
publish / publish (push) Has been cancelled
sigstore: test signAttestationManifests
2026-01-13 15:07:08 +01:00
CrazyMax
345531d0a4 sigstore: test signAttestationManifests
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-13 14:56:12 +01:00
CrazyMax
2e620f9c90 Merge pull request #932 from crazy-max/sigstore-verifyimage
sigstore: add function to verify image attestations
2026-01-13 14:50:59 +01:00
CrazyMax
0162b2cf8b cosign: clear errors if manifest or bundle payload found
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-13 13:25:39 +01:00
CrazyMax
7397cfe37c sigstore: add function to verify image attestations
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-13 13:21:55 +01:00
CrazyMax
a3d5eee63a Merge pull request #928 from docker/bot/cosign-releases-json
Update `.github/cosign-releases.json`
2026-01-12 14:18:20 +01:00
crazy-max
85c3d8b7f3 github: update .github/cosign-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-10 00:13:01 +00:00
CrazyMax
22773fa848 Merge pull request #927 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2026-01-09 13:16:03 +01:00
crazy-max
cbf7323bc1 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-09 12:14:24 +00:00
CrazyMax
382ab4c9ac Merge pull request #924 from docker/dependabot/npm_and_yarn/actions/tool-cache-3.0.0
build(deps): bump @actions/tool-cache from 2.0.2 to 3.0.0
2026-01-08 16:33:06 +01:00
CrazyMax
b0b34198c4 Merge pull request #925 from docker/dependabot/npm_and_yarn/actions/cache-5.0.2
build(deps): bump @actions/cache from 5.0.1 to 5.0.2
2026-01-08 16:30:42 +01:00
dependabot[bot]
842eaf5ac0 build(deps): bump @actions/cache from 5.0.1 to 5.0.2
Bumps [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) from 5.0.1 to 5.0.2.
- [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: 5.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-08 15:21:39 +00:00
CrazyMax
2f0f57f46e Merge pull request #926 from docker/dependabot/npm_and_yarn/actions/artifact-5.0.2
build(deps): bump @actions/artifact from 5.0.1 to 5.0.2
2026-01-08 16:19:26 +01:00
dependabot[bot]
4f8b9ae301 build(deps): bump @actions/tool-cache from 2.0.2 to 3.0.0
Bumps [@actions/tool-cache](https://github.com/actions/toolkit/tree/HEAD/packages/tool-cache) from 2.0.2 to 3.0.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/tool-cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/tool-cache)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-08 15:12:22 +00:00
dependabot[bot]
0aaa94bdee build(deps): bump @actions/artifact from 5.0.1 to 5.0.2
Bumps [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) from 5.0.1 to 5.0.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-version: 5.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-08 15:12:07 +00:00
CrazyMax
654afbf8c5 Merge pull request #922 from docker/dependabot/npm_and_yarn/actions/core-2.0.2
build(deps): bump @actions/core from 2.0.1 to 2.0.2
2026-01-08 16:09:49 +01:00
CrazyMax
d256fc587d Merge pull request #923 from docker/dependabot/npm_and_yarn/actions/github-7.0.0
build(deps): bump @actions/github from 6.0.1 to 7.0.0
2026-01-08 16:08:23 +01:00
dependabot[bot]
ca8ad9e7ab build(deps): bump @actions/github from 6.0.1 to 7.0.0
Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 6.0.1 to 7.0.0.
- [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: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-08 14:53:30 +00:00
dependabot[bot]
53aedd9542 build(deps): bump @actions/core from 2.0.1 to 2.0.2
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 2.0.1 to 2.0.2.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-08 14:53:07 +00:00
CrazyMax
01fb6c8d3b Merge pull request #921 from docker/dependabot/npm_and_yarn/actions/http-client-3.0.1
build(deps): bump @actions/http-client from 3.0.0 to 3.0.1
2026-01-08 10:28:17 +01:00
dependabot[bot]
6439a13308 build(deps): bump @actions/http-client from 3.0.0 to 3.0.1
Bumps [@actions/http-client](https://github.com/actions/toolkit/tree/HEAD/packages/http-client) from 3.0.0 to 3.0.1.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/http-client/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/http-client)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-08 01:10:26 +00:00
CrazyMax
a6ccf4cb79 Merge pull request #919 from crazy-max/fix-publish-workflow
ci(publish): fix permissions to create GitHub Release
2026-01-07 17:17:31 +01:00
CrazyMax
333909f560 Merge pull request #920 from crazy-max/buildkit-0.26.3
update buildkit to 0.26.3
2026-01-05 16:08:22 +01:00
CrazyMax
0b7584385a update buildkit to 0.26.3
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-05 14:58:42 +01:00
CrazyMax
3a94f7311f ci(publish): fix permissions to create GitHub Release
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-05 14:47:21 +01:00
CrazyMax
f2404dca2f Merge pull request #918 from crazy-max/isolated-modules
Some checks failed
publish / publish (push) Has been cancelled
set isolatedModules=true to fix ts-jest TS151002 warning
2026-01-05 13:58:14 +01:00
CrazyMax
8bae8c963f Merge pull request #913 from docker/dependabot/npm_and_yarn/sigstore/verify-3.1.0
build(deps): bump @sigstore/verify from 3.0.0 to 3.1.0
2026-01-05 13:46:58 +01:00
CrazyMax
c00b0d2393 set isolatedModules=true to fix ts-jest TS151002 warning
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-05 13:45:55 +01:00
dependabot[bot]
f861f8df56 build(deps): bump @sigstore/verify from 3.0.0 to 3.1.0
Bumps [@sigstore/verify](https://github.com/sigstore/sigstore-js) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/sigstore/sigstore-js/releases)
- [Commits](https://github.com/sigstore/sigstore-js/compare/@sigstore/verify@3.0.0...sigstore@3.1.0)

---
updated-dependencies:
- dependency-name: "@sigstore/verify"
  dependency-version: 3.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-05 11:05:33 +00:00
CrazyMax
7b8ae12eb0 Merge pull request #917 from crazy-max/update-sigstore-sign
update @sigstore/sign to 4.1.0
2026-01-05 12:03:24 +01:00
CrazyMax
10fbe0d8d4 update @sigstore/sign to 4.1.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-05 10:48:28 +01:00
CrazyMax
8ba5f4ae6f enable Node 16–style ESM resolution
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-01-05 10:48:28 +01:00
CrazyMax
fcb1e5a298 Merge pull request #914 from docker/dependabot/npm_and_yarn/sigstore/tuf-4.0.1
build(deps): bump @sigstore/tuf from 4.0.0 to 4.0.1
2026-01-05 10:02:48 +01:00
CrazyMax
459eee50e8 Merge pull request #916 from docker/bot/undock-releases-json
Update `.github/undock-releases.json`
2025-12-31 23:47:14 +01:00
crazy-max
9c67bc4427 github: update .github/undock-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-31 13:50:26 +00:00
CrazyMax
d86ab59115 Merge pull request #915 from neilime/feat/handle-detached-head-error
fix: handle detached head error
2025-12-31 14:50:01 +01:00
copilot-swe-agent[bot]
945d269b25 fix: handle detached head error 2025-12-23 18:48:02 +01:00
dependabot[bot]
692b091ac0 build(deps): bump @sigstore/tuf from 4.0.0 to 4.0.1
Bumps [@sigstore/tuf](https://github.com/sigstore/sigstore-js) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/sigstore/sigstore-js/releases)
- [Commits](https://github.com/sigstore/sigstore-js/compare/@sigstore/tuf@4.0.0...@sigstore/sign@4.0.1)

---
updated-dependencies:
- dependency-name: "@sigstore/tuf"
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-19 22:06:19 +00:00
CrazyMax
3984b38120 Merge pull request #909 from crazy-max/publish-commitish
ci(publish): no need to set target_commitish
2025-12-18 18:20:18 +01:00
CrazyMax
57c7ba07e5 Merge pull request #908 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-12-18 16:53:50 +01:00
CrazyMax
73ff711ca0 ci(publish): no need to set target_commitish
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-18 16:52:40 +01:00
crazy-max
ce2ae460d6 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-18 15:51:44 +00:00
CrazyMax
f61800c7a9 Merge pull request #907 from crazy-max/publish-release
ci(publish): create github release
2025-12-18 16:51:15 +01:00
CrazyMax
45b39556af ci(publish): create github release
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-18 13:30:31 +01:00
CrazyMax
5172be8e2f Merge pull request #906 from crazy-max/npm-publish
Some checks failed
publish / publish (push) Has been cancelled
ci: use trusted publishing to publish our package
2025-12-18 13:04:59 +01:00
CrazyMax
1ded416304 ci(publish): generate provenance attestation
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-18 12:05:50 +01:00
CrazyMax
2ea2c9d9ee ci: use trusted publishing to publish our npm package
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-18 12:05:50 +01:00
CrazyMax
9442c70243 Merge pull request #904 from crazy-max/cosign-bin-verify
Some checks failed
publish / publish (push) Has been cancelled
cosign(install): verify binary signature with keyless verification bundle
2025-12-18 09:19:02 +01:00
CrazyMax
36dc518728 Merge pull request #905 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-12-18 09:18:30 +01:00
crazy-max
a05039c77d github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-18 00:31:44 +00:00
CrazyMax
eb8ed6b687 cosign(install): use sigstore module to verify signature
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-16 19:44:45 +01:00
CrazyMax
44e7279490 cosign(install): verify binary signature with keyless verification bundle
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-16 15:02:36 +01:00
CrazyMax
5e6dd63795 Merge pull request #903 from crazy-max/update-tsconfig
chore: update tsconfig
2025-12-16 10:20:25 +01:00
CrazyMax
9ab04625a7 chore: update tsconfig
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-16 10:15:42 +01:00
CrazyMax
974eb14a42 Merge pull request #902 from crazy-max/dev-deps
update dev dependencies
2025-12-16 10:05:22 +01:00
CrazyMax
b13a880f18 update jest config since 30.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-15 23:57:24 +01:00
CrazyMax
a198dbc46d migrate eslint config to new format required since 9.0.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-15 23:10:13 +01:00
CrazyMax
d82a614b83 update dev dependencies
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-15 22:25:01 +01:00
CrazyMax
945397f145 Merge pull request #892 from docker/dependabot/npm_and_yarn/actions/cache-5.0.1
build(deps): bump @actions/cache from 4.1.0 to 5.0.1
2025-12-15 12:32:33 +01:00
CrazyMax
33cdba4686 github: fix import of TransferProgressEvent
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-15 11:28:24 +01:00
dependabot[bot]
5eeec21377 build(deps): bump @actions/cache from 4.1.0 to 5.0.1
Bumps [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) from 4.1.0 to 5.0.1.
- [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: 5.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 10:08:44 +00:00
CrazyMax
cc10fd84d6 Merge pull request #893 from docker/dependabot/npm_and_yarn/actions/artifact-5.0.1
build(deps): bump @actions/artifact from 4.0.0 to 5.0.1
2025-12-15 11:06:37 +01:00
CrazyMax
48394148f4 Merge pull request #900 from docker/cosign-3.0.3
dockerfile: update cosign to 3.0.3
2025-12-15 11:05:32 +01:00
Paweł Gronowski
3c97831db9 Merge pull request #896 from crazy-max/unpin-qemu
docker(install): unpin QEMU
2025-12-15 10:04:03 +00:00
CrazyMax
2aaf8dc22d bump @azure/storage-blob from 12.15.0 to 12.29.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-15 10:41:11 +01:00
dependabot[bot]
d4379528b4 build(deps): bump @actions/artifact from 4.0.0 to 5.0.1
Bumps [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) from 4.0.0 to 5.0.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-version: 5.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 09:23:37 +00:00
CrazyMax
8b935c624b Merge pull request #889 from docker/dependabot/npm_and_yarn/actions/core-2.0.1
build(deps): bump @actions/core from 1.11.1 to 2.0.1
2025-12-15 10:21:25 +01:00
CrazyMax
e0deaff943 dockerfile: update cosign to 3.0.3
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-15 10:02:13 +01:00
dependabot[bot]
2149af8d90 build(deps): bump @actions/core from 1.11.1 to 2.0.1
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.11.1 to 2.0.1.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/@actions/artifact@2.0.1/packages/core)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 08:56:39 +00:00
CrazyMax
1e11a6ae9d Merge pull request #885 from docker/dependabot/npm_and_yarn/actions/exec-2.0.0
build(deps): bump @actions/exec from 1.1.1 to 2.0.0
2025-12-15 09:54:31 +01:00
CrazyMax
8ef5b18fcf Merge pull request #886 from docker/dependabot/github_actions/peter-evans/create-pull-request-8.0.0
build(deps): bump peter-evans/create-pull-request from 7.0.9 to 8.0.0
2025-12-15 09:27:41 +01:00
CrazyMax
7d9e85a9da Merge pull request #883 from docker/bot/regclient-releases-json
Update `.github/regclient-releases.json`
2025-12-15 09:27:08 +01:00
CrazyMax
3616f2901b Merge pull request #887 from docker/bot/cosign-releases-json
Update `.github/cosign-releases.json`
2025-12-15 09:26:49 +01:00
crazy-max
b1d718004d github: update .github/regclient-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-15 08:26:49 +00:00
CrazyMax
077fb8ba53 Merge pull request #890 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-12-15 09:26:21 +01:00
CrazyMax
2a71af4445 Merge pull request #891 from docker/dependabot/github_actions/actions/download-artifact-7
build(deps): bump actions/download-artifact from 6 to 7
2025-12-15 09:26:02 +01:00
CrazyMax
4a30d04fe2 docker(install): unpin QEMU
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-15 09:23:27 +01:00
crazy-max
0c34b0e7cf github: update .github/cosign-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-15 06:51:15 +00:00
crazy-max
c447ec0b97 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-15 06:51:13 +00:00
CrazyMax
7b4504332f Merge pull request #894 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-12-15 07:50:49 +01:00
crazy-max
a980bcd0c5 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-13 00:33:07 +00:00
dependabot[bot]
7a87dc0d65 build(deps): bump actions/download-artifact from 6 to 7
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v6...v7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 22:05:16 +00:00
dependabot[bot]
18946344af build(deps): bump peter-evans/create-pull-request from 7.0.9 to 8.0.0
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.9 to 8.0.0.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](84ae59a2cd...98357b18bf)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-09 22:08:28 +00:00
dependabot[bot]
3d735ba61a build(deps): bump @actions/exec from 1.1.1 to 2.0.0
Bumps [@actions/exec](https://github.com/actions/toolkit/tree/HEAD/packages/exec) from 1.1.1 to 2.0.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/exec/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/exec)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-09 22:07:13 +00:00
CrazyMax
14952de7ed Merge pull request #881 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-12-03 09:34:40 +01:00
crazy-max
12285e1fc3 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-03 00:33:25 +00:00
CrazyMax
473d258161 Merge pull request #880 from crazy-max/pin-qemu
Some checks failed
publish / publish (push) Has been cancelled
docker(install): pin QEMU to 10.1.1
2025-12-02 15:00:51 +01:00
CrazyMax
8d87ba5a72 docker(install): pin QEMU to 10.1.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-12-02 14:31:18 +01:00
CrazyMax
841fd33bb7 Merge pull request #878 from docker/bot/regclient-releases-json
Update `.github/regclient-releases.json`
2025-12-02 13:33:39 +01:00
CrazyMax
a3709540ed Merge pull request #877 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-12-02 13:33:23 +01:00
CrazyMax
6371b3d325 Merge pull request #879 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-12-02 13:33:06 +01:00
crazy-max
f8df53283c github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-02 12:15:39 +00:00
crazy-max
f312d8d21e github: update .github/regclient-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-02 00:12:17 +00:00
crazy-max
41a2ea0c9b github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-29 00:32:08 +00:00
CrazyMax
d5209cea68 Merge pull request #876 from crazy-max/docker-install-disable-macos-tests
Some checks failed
publish / publish (push) Has been cancelled
test: disable docker install tests on macos
2025-11-27 11:25:49 +01:00
CrazyMax
4f0696b47c test: disable docker install tests on macos
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-27 10:53:27 +01:00
CrazyMax
f0de40cffa Merge pull request #832 from docker/dependabot/npm_and_yarn/actions/io-2.0.0
build(deps): bump @actions/io from 1.1.3 to 2.0.0
2025-11-27 10:49:43 +01:00
CrazyMax
abec938c9b Merge pull request #875 from crazy-max/releases-without-token
releases: download releases JSON without token first
2025-11-27 10:49:00 +01:00
CrazyMax
1d22f02ce4 releases: download releases JSON without token first
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-27 10:22:18 +01:00
dependabot[bot]
a5ead9a86c build(deps): bump @actions/io from 1.1.3 to 2.0.0
Bumps [@actions/io](https://github.com/actions/toolkit/tree/HEAD/packages/io) from 1.1.3 to 2.0.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/io/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/io)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-27 09:14:13 +00:00
CrazyMax
b42885d9a9 Merge pull request #831 from docker/dependabot/npm_and_yarn/actions/http-client-3.0.0
build(deps): bump @actions/http-client from 2.2.3 to 3.0.0
2025-11-27 10:12:10 +01:00
CrazyMax
8d01bf1bfc Merge pull request #856 from neilime/fix/git-ref-in-detached-head
fix(git): support getting ref in various detached HEAD contexts
2025-11-27 10:10:44 +01:00
CrazyMax
ccdd59f096 Merge pull request #874 from crazy-max/dependabot-pr-limit
chore: increase prs limit for dependabot
2025-11-27 10:06:42 +01:00
CrazyMax
949f09fa44 chore: increase prs limit for dependabot
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-27 10:03:47 +01:00
CrazyMax
5f53738d84 Merge pull request #860 from docker/dependabot/npm_and_yarn/js-yaml-4.1.1
build(deps): bump js-yaml from 4.1.0 to 4.1.1
2025-11-27 09:59:58 +01:00
CrazyMax
a111fe1e61 Merge pull request #870 from docker/dependabot/github_actions/peter-evans/create-pull-request-7.0.9
build(deps): bump peter-evans/create-pull-request from 7.0.8 to 7.0.9
2025-11-27 09:59:22 +01:00
CrazyMax
ccfdc68a38 Merge pull request #873 from crazy-max/bake-attest-check
buildx(bake): funcs to check attest set in bake definition
2025-11-26 12:40:39 +01:00
CrazyMax
9c05197992 buildx(bake): funcs to check attest set in bake definition
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-26 11:08:57 +01:00
CrazyMax
764a608ae0 Merge pull request #865 from docker/dependabot/github_actions/actions/checkout-6
build(deps): bump actions/checkout from 5 to 6
2025-11-25 15:49:58 +01:00
CrazyMax
be39e7c75a Merge pull request #871 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-11-25 02:31:46 +01:00
crazy-max
81f1dd4f57 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-25 00:31:54 +00:00
dependabot[bot]
4634011afa build(deps): bump peter-evans/create-pull-request from 7.0.8 to 7.0.9
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.8 to 7.0.9.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](271a8d0340...84ae59a2cd)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 22:14:25 +00:00
CrazyMax
535c57eda3 Merge pull request #869 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-11-24 15:24:41 +01:00
crazy-max
d57249b699 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-24 14:24:02 +00:00
CrazyMax
0bc914c6cd Merge pull request #866 from crazy-max/docker-install-fix
ci(test): allow failure for docker install on macos
2025-11-24 13:20:40 +01:00
CrazyMax
f636ea29ca Merge pull request #868 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-11-24 13:20:26 +01:00
crazy-max
3fe3252d57 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-24 12:19:57 +00:00
CrazyMax
5e6eb921cf Merge pull request #867 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-11-24 13:19:34 +01:00
crazy-max
ce5e865551 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-24 12:08:23 +00:00
CrazyMax
7736c355dc ci(test): allow failure for docker install on macos
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-23 15:16:14 +01:00
dependabot[bot]
944ec75cf6 build(deps): bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [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/v5...v6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-20 22:06:10 +00:00
CrazyMax
d727f06dc0 Merge pull request #864 from crazy-max/buildkit-0.26.2
update buildkit to 0.26.2 and buildx to 0.30.1
2025-11-20 16:35:48 +01:00
CrazyMax
3c4372146e update buildkit to 0.26.2 and buildx to 0.30.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-20 14:18:28 +01:00
CrazyMax
d5be659121 Merge pull request #863 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-11-18 09:13:23 +01:00
crazy-max
2f9b11c5ca github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-18 00:32:53 +00:00
CrazyMax
93ca750952 Merge pull request #862 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-11-17 19:04:28 +01:00
crazy-max
fbfc9b33af github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-17 18:03:39 +00:00
CrazyMax
bb9028cd44 Merge pull request #861 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-11-15 09:26:56 +01:00
crazy-max
72fab21aba github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-15 00:31:47 +00:00
Emilien Escalle
ad7ffdebbe fix(git): support getting ref in various detached HEAD contexts
Signed-off-by: Emilien Escalle <emilien.escalle@escemi.com>
2025-11-14 08:50:10 +01:00
dependabot[bot]
a9e04b410c build(deps): bump js-yaml from 4.1.0 to 4.1.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-13 22:06:20 +00:00
CrazyMax
747bc1653d Merge pull request #859 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-11-13 13:16:15 +01:00
crazy-max
8dac860c22 github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-13 12:14:37 +00:00
CrazyMax
074578feee Merge pull request #858 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-11-13 08:46:52 +01:00
CrazyMax
22bb9492bf Merge pull request #857 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-11-13 08:46:38 +01:00
crazy-max
5515e9705a github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-13 00:35:35 +00:00
jsternberg
517e370b73 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-12 22:05:49 +00:00
CrazyMax
4f8424eebb Merge pull request #854 from crazy-max/cosign-no-verbose
sigstore: remove verbose flag from persisted cosign args
2025-11-12 15:52:35 +01:00
CrazyMax
d018ed13d0 sigstore: remove verbose flag from persisted cosign args
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-12 14:44:23 +01:00
CrazyMax
fd15fa02c0 Merge pull request #849 from docker/bot/regclient-releases-json
Update `.github/regclient-releases.json`
2025-11-12 11:22:56 +01:00
crazy-max
4eade91d5b github: update .github/regclient-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-12 10:20:37 +00:00
CrazyMax
d235481ee7 Merge pull request #853 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-11-12 11:20:09 +01:00
CrazyMax
f0bd06d036 Merge pull request #850 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-11-12 11:19:52 +01:00
crazy-max
e958ed5b3f github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-12 10:15:21 +00:00
crazy-max
29f8f30aa9 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-12 10:15:15 +00:00
CrazyMax
6aa7c206c6 Merge pull request #851 from crazy-max/update-releases-json
ci: update crazy-max/.github/.github/workflows/releases-json to 2842b80
2025-11-12 11:14:49 +01:00
CrazyMax
e05a413e8a ci: update crazy-max/.github/.github/workflows/releases-json to 2842b80
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-12 10:23:32 +01:00
CrazyMax
965b96d275 Merge pull request #847 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-11-07 17:13:59 +01:00
CrazyMax
f04e1d3acb Merge pull request #846 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-11-07 17:13:44 +01:00
crazy-max
2a13876756 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-07 12:13:03 +00:00
crazy-max
5197b8fa3d github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-07 00:24:20 +00:00
CrazyMax
fc1b7fac4b Merge pull request #845 from crazy-max/buildkit-0.25.2
update buildkit to 0.25.2
2025-11-05 13:58:11 +01:00
CrazyMax
af0095404d update buildkit to 0.25.2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-05 13:15:42 +01:00
CrazyMax
7ee633887d Merge pull request #844 from docker/dependabot/npm_and_yarn/sigstore/sign-4.0.1
Some checks failed
publish / publish (push) Has been cancelled
build(deps): bump @sigstore/sign from 3.1.0 to 4.0.1
2025-11-05 12:31:11 +01:00
dependabot[bot]
9c7140767c build(deps): bump @sigstore/sign from 3.1.0 to 4.0.1
Bumps [@sigstore/sign](https://github.com/sigstore/sigstore-js) from 3.1.0 to 4.0.1.
- [Release notes](https://github.com/sigstore/sigstore-js/releases)
- [Commits](https://github.com/sigstore/sigstore-js/compare/@sigstore/sign@3.1.0...@sigstore/sign@4.0.1)

---
updated-dependencies:
- dependency-name: "@sigstore/sign"
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-05 11:16:10 +00:00
CrazyMax
7cb0fac5c0 Merge pull request #840 from docker/dependabot/npm_and_yarn/sigstore/bundle-4.0.0
build(deps): bump @sigstore/bundle from 3.1.0 to 4.0.0
2025-11-05 12:13:25 +01:00
dependabot[bot]
9b9d27dc4c build(deps): bump @sigstore/bundle from 3.1.0 to 4.0.0
Bumps [@sigstore/bundle](https://github.com/sigstore/sigstore-js) from 3.1.0 to 4.0.0.
- [Release notes](https://github.com/sigstore/sigstore-js/releases)
- [Commits](https://github.com/sigstore/sigstore-js/compare/@sigstore/bundle@3.1.0...@sigstore/bundle@4.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-05 10:45:32 +00:00
dependabot[bot]
e5e1cd0f99 build(deps): bump @actions/http-client from 2.2.3 to 3.0.0
Bumps [@actions/http-client](https://github.com/actions/toolkit/tree/HEAD/packages/http-client) from 2.2.3 to 3.0.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/http-client/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/http-client)

---
updated-dependencies:
- dependency-name: "@actions/http-client"
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-05 10:45:26 +00:00
CrazyMax
a84516d0dd Merge pull request #843 from crazy-max/rm-actions-attest
sigstore: remove @actions/attest dependency
2025-11-05 11:43:19 +01:00
CrazyMax
85dfc7a573 sigstore: remove @actions/attest dependency
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-05 11:11:57 +01:00
CrazyMax
5c04d3904d Merge pull request #842 from crazy-max/cache-failsafe
cache: gracefully handle cache restore failures with warning
2025-11-05 10:27:59 +01:00
CrazyMax
d8def31251 cache: gracefully handle cache restore failures with warning
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-11-05 10:02:21 +01:00
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
6cd97b3669 Merge pull request #612 from docker/dependabot/npm_and_yarn/actions/cache-4.0.2
Some checks failed
publish / publish (push) Has been cancelled
build(deps): bump @actions/cache from 4.0.1 to 4.0.2
2025-02-26 15:20:03 +01:00
dependabot[bot]
4a13975fd1 build(deps): bump @actions/cache from 4.0.1 to 4.0.2
Bumps [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) from 4.0.1 to 4.0.2.
- [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-02-25 22:22:45 +00:00
CrazyMax
97a949444d Merge pull request #611 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-02-25 10:45:22 +01:00
crazy-max
77e52fe6b0 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-25 00:18:52 +00:00
CrazyMax
60f9b4c28d Merge pull request #610 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-02-24 13:18:10 +01:00
crazy-max
2a091a2c69 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-24 12:07:43 +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
CrazyMax
834b79b6b3 Merge pull request #603 from docker/dependabot/npm_and_yarn/actions/artifact-2.2.2
build(deps): bump @actions/artifact from 2.2.1 to 2.2.2
2025-02-22 13:30:01 +01:00
CrazyMax
a83640a03c Merge pull request #609 from docker/bot/compose-releases-json
Update `.github/compose-releases.json`
2025-02-22 13:29:09 +01:00
CrazyMax
ec774f564b Merge pull request #608 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-02-22 13:28:42 +01:00
crazy-max
51a104851d github: update .github/compose-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-22 00:29:39 +00:00
crazy-max
af36b73f0f github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-22 00:17:43 +00:00
CrazyMax
4e27e0c148 Merge pull request #607 from crazy-max/buildx-0.21.1
dockerfile: update buildx to 0.21.1
2025-02-21 15:01:59 +01:00
CrazyMax
17de3961ec dockerfile: update buildx to 0.21.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-02-21 14:31:33 +01:00
CrazyMax
5ec79aa91e Merge pull request #606 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-02-21 14:29:57 +01:00
crazy-max
fd005ff6bd github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-21 13:29:01 +00:00
CrazyMax
44525b4c00 Merge pull request #605 from docker/bot/buildx-lab-releases-json
Update `.github/buildx-lab-releases.json`
2025-02-21 01:30:15 +01:00
crazy-max
c1a823ad97 github: update .github/buildx-lab-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-21 00:18:29 +00:00
dependabot[bot]
2a3bfd0f48 build(deps): bump @actions/artifact from 2.2.1 to 2.2.2
Bumps [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) from 2.2.1 to 2.2.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-02-20 22:25:21 +00:00
CrazyMax
4ecc47d56a Merge pull request #602 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2025-02-20 11:00:52 +01:00
crazy-max
9408be1597 github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-20 09:57:02 +00:00
CrazyMax
a66547715c Merge pull request #601 from thompson-shaun/bump-buildkit-buildx
update buildkit to v0.20.0 and buildx to v0.21.0
2025-02-20 10:56:33 +01:00
Tõnis Tiigi
d6de3818d5 Merge pull request #600 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2025-02-19 13:39:26 -08:00
Shaun Thompson
3b8fc6d50c update buildkit to v0.20.0 and buildx to v0.21.0
Signed-off-by: Shaun Thompson <shaun.thompson@docker.com>
2025-02-19 16:23:59 -05:00
thompson-shaun
67d9ba86a9 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-19 21:05:32 +00:00
116 changed files with 26635 additions and 5733 deletions

View File

@@ -1,4 +0,0 @@
/.yarn/**
/lib/**
/coverage/**
/node_modules/**

View File

@@ -1,36 +0,0 @@
{
"env": {
"node": true,
"es6": true,
"mocha": true,
"jest": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/errors",
"plugin:import/typescript", // this is needed to allow importing typescript files from JS
"plugin:import/warnings",
"plugin:jest/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2023,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"jest",
"prettier"
],
"rules": {
"import/no-unresolved": [
"error", {
"ignore": ["csv-parse/sync", "@octokit/openapi-types"]
}
],
"jest/no-disabled-tests": 0
}
}

View File

@@ -1,17 +0,0 @@
name: 'Setup QEMU on macOS'
description: 'Set up QEMU on macOS runners'
# FIXME: Remove this composite once QEMU issue is fixed on macOS runners
# https://github.com/docker/actions-toolkit/issues/455
runs:
using: composite
steps:
- run: |
set -ex
brew uninstall --ignore-dependencies qemu || true
brew autoremove || true
curl -o /tmp/qemu.rb https://raw.githubusercontent.com/Homebrew/homebrew-core/f1a9cf104a9a51779c7a532b658c490f69974839/Formula/q/qemu.rb
brew install /tmp/qemu.rb
continue-on-error: true
shell: bash

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

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
version: 2
updates:
- package-ecosystem: "github-actions"
open-pull-requests-limit: 20
directory: "/"
schedule:
interval: "daily"
@@ -8,6 +9,7 @@ updates:
- "dependencies"
- "bot"
- package-ecosystem: "npm"
open-pull-requests-limit: 20
directory: "/"
schedule:
interval: "daily"

View File

@@ -1,14 +1,308 @@
{
"latest": {
"id": 196137348,
"tag_name": "v27.5.1",
"html_url": "https://github.com/moby/moby/releases/tag/v27.5.1",
"id": 275290406,
"tag_name": "docker-v29.1.4",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.1.4",
"assets": []
},
"v29.1.4": {
"id": 275290406,
"tag_name": "docker-v29.1.4",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.1.4",
"assets": []
},
"edge": {
"id": 201046359,
"tag_name": "v28.0.0-rc.3",
"html_url": "https://github.com/moby/moby/releases/tag/v28.0.0-rc.3",
"id": 271147963,
"tag_name": "docker-v29.2.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.2.0-rc.1",
"assets": []
},
"v29.2.0-rc.1": {
"id": 271147963,
"tag_name": "docker-v29.2.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.2.0-rc.1",
"assets": []
},
"v29.1.3": {
"id": 269884470,
"tag_name": "docker-v29.1.3",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.1.3",
"assets": []
},
"v29.1.2": {
"id": 266898070,
"tag_name": "docker-v29.1.2",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.1.2",
"assets": []
},
"v29.1.1": {
"id": 265971746,
"tag_name": "docker-v29.1.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.1.1",
"assets": []
},
"v29.1.0": {
"id": 265770897,
"tag_name": "docker-v29.1.0",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.1.0",
"assets": []
},
"v29.0.4": {
"id": 264940208,
"tag_name": "docker-v29.0.4",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.4",
"assets": []
},
"v29.0.3": {
"id": 264058657,
"tag_name": "docker-v29.0.3",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.3",
"assets": []
},
"v29.0.2": {
"id": 262951416,
"tag_name": "docker-v29.0.2",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.2",
"assets": []
},
"v29.1.0-rc.1": {
"id": 263125085,
"tag_name": "docker-v29.1.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.1.0-rc.1",
"assets": []
},
"v29.0.1": {
"id": 262245944,
"tag_name": "docker-v29.0.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.1",
"assets": []
},
"v29.0.0": {
"id": 261265152,
"tag_name": "docker-v29.0.0",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.0",
"assets": []
},
"v29.0.0-rc.3": {
"id": 260452080,
"tag_name": "docker-v29.0.0-rc.3",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.0.0-rc.3",
"assets": []
},
"v28.5.2": {
"id": 259852183,
"tag_name": "v28.5.2",
"html_url": "https://github.com/moby/moby/releases/tag/v28.5.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",
"assets": []
},
"v28.0.0-rc.3": {

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +1,134 @@
{
"latest": {
"id": 192171889,
"tag_name": "v0.9.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.9.0",
"id": 273439938,
"tag_name": "v0.11.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.11.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.11.0/checksums.txt",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.zip",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_arm64.zip"
]
},
"v0.11.0": {
"id": 273439938,
"tag_name": "v0.11.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.11.0",
"assets": [
"https://github.com/crazy-max/undock/releases/download/v0.11.0/checksums.txt",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.zip",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.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 +241,47 @@
]
},
"edge": {
"id": 192171889,
"tag_name": "v0.9.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.9.0",
"id": 273439938,
"tag_name": "v0.11.0",
"html_url": "https://github.com/crazy-max/undock/releases/tag/v0.11.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.11.0/checksums.txt",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_darwin_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_amd64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_arm64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv5.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv6.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_armv7.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_ppc64le.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_riscv64.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_linux_s390x.tar.gz",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_amd64.zip",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_arm64.provenance.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.0_windows_arm64.sbom.json",
"https://github.com/crazy-max/undock/releases/download/v0.11.0/undock_0.11.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@2842b806167c9dbacf5f972e0fcf47204a99d987
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@v6
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
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@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
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@2842b806167c9dbacf5f972e0fcf47204a99d987
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@v6
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
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@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
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@v6
-
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@2842b806167c9dbacf5f972e0fcf47204a99d987
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@v6
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
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@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
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@2842b806167c9dbacf5f972e0fcf47204a99d987
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@v6
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
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@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
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@2842b806167c9dbacf5f972e0fcf47204a99d987
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@v6
-
name: Download
uses: actions/download-artifact@v7
with:
name: cosign-releases-json
path: .github
-
name: Commit changes
run: |
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
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,28 @@ on:
jobs:
generate:
uses: crazy-max/.github/.github/workflows/releases-json.yml@7f83a5a887650a38e4d0e05d5262309cfaa31459
uses: crazy-max/.github/.github/workflows/releases-json.yml@2842b806167c9dbacf5f972e0fcf47204a99d987
with:
repository: moby/moby
artifact_name: docker-releases-json
filename: docker-releases.json
tag_patterns: |
^docker-(.*)$
^(v.*)$
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@v6
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: docker-releases-json
path: .github
@@ -45,7 +48,7 @@ jobs:
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
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

@@ -1,5 +1,9 @@
name: publish
permissions:
id-token: write # required for OIDC
contents: write # required to create GitHub Release
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
@@ -9,17 +13,49 @@ on:
tags:
- 'v*'
env:
NODE_VERSION: "24" # at least Node 24 is required for Trusted Publishing with OIDC
jobs:
publish:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
name: Checkout
uses: actions/checkout@v6
-
name: Enable corepack
run: |
corepack enable
yarn --version
-
name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
package-manager-cache: false
-
name: Print versions
run: |
node --version
npm --version
yarn --version
-
name: Build
run: |
yarn install
yarn run build
-
name: Publish
uses: docker/bake-action@v6
run: |
npm version --no-git-tag-version ${GITHUB_REF#refs/tags/v}
npm publish --provenance --access public
-
name: Create Release
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
targets: publish
draft: true
generate_release_notes: true
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

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@2842b806167c9dbacf5f972e0fcf47204a99d987
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@v6
-
name: Download
uses: actions/download-artifact@v7
with:
name: regclient-releases-json
path: .github
-
name: Commit changes
run: |
git add -A .
-
name: Create PR
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
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.19.0"
BUILDKIT_IMAGE: "moby/buildkit:v0.26.3"
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@v6
-
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@v6
-
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,25 @@ 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
packages: write # needed for pushing to GitHub Container Registry
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
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 +172,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 +197,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 +213,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@2842b806167c9dbacf5f972e0fcf47204a99d987
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@v6
-
name: Download
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
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@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
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@v6
-
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,15 @@
[
{
"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"
}
}
]

View File

@@ -0,0 +1,15 @@
[
{
"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"
}
}
]

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

@@ -485,3 +485,113 @@ describe('hasGitAuthTokenSecret', () => {
expect(Bake.hasGitAuthTokenSecret(def)).toEqual(expected);
});
});
describe('hasProvenanceAttestation', () => {
// prettier-ignore
test.each([
[
{
"target": {
"build": {
"attest": [
{
"type": "provenance",
"mode": "max"
}
]
},
}
} as unknown as BakeDefinition,
true
],
[
{
"target": {
"build": {
"attest": [
{
"type": "sbom"
}
]
},
}
} as unknown as BakeDefinition,
false
],
[
{
"target": {
"build": {
"attest": [
{
"type": "sbom"
},
{
"type": "provenance",
"mode": "max"
}
]
},
}
} as unknown as BakeDefinition,
true
]
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
expect(Bake.hasProvenanceAttestation(def)).toEqual(expected);
});
});
describe('hasSBOMAttestation', () => {
// prettier-ignore
test.each([
[
{
"target": {
"build": {
"attest": [
{
"type": "provenance",
"mode": "max"
}
]
},
}
} as unknown as BakeDefinition,
false
],
[
{
"target": {
"build": {
"attest": [
{
"type": "sbom"
}
]
},
}
} as unknown as BakeDefinition,
true
],
[
{
"target": {
"build": {
"attest": [
{
"type": "sbom"
},
{
"type": "provenance",
"mode": "max"
}
]
},
}
} as unknown as BakeDefinition,
true
]
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
expect(Bake.hasSBOMAttestation(def)).toEqual(expected);
});
});

View File

@@ -49,7 +49,6 @@ describe('exists', () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
const builder = new Builder();
await builder.exists('foo');
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx', 'inspect', 'foo'], {
silent: true,
ignoreReturnCode: true
@@ -466,6 +465,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

@@ -91,7 +91,6 @@ describe('isAvailable', () => {
standalone: false
});
await buildx.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], {
silent: true,
ignoreReturnCode: true
@@ -103,7 +102,6 @@ describe('isAvailable', () => {
standalone: true
});
await buildx.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`buildx`, [], {
silent: true,
ignoreReturnCode: true

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,57 @@ 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);
});
it('returns buildkit attestations descriptors for linux/amd64', async () => {
const attestations = await new ImageTools().attestationDescriptors('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', {os: 'linux', architecture: 'amd64'});
const expectedAttestations = <Array<Descriptor>>JSON.parse(fs.readFileSync(path.join(fixturesDir, 'imagetools-06.json'), {encoding: 'utf-8'}).trim());
expect(attestations).toEqual(expectedAttestations);
});
it('returns buildkit attestations descriptors for linux/arm/v7', async () => {
const attestations = await new ImageTools().attestationDescriptors('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', {os: 'linux', architecture: 'arm', variant: 'v7'});
const expectedAttestations = <Array<Descriptor>>JSON.parse(fs.readFileSync(path.join(fixturesDir, 'imagetools-07.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'
]);
});
it('returns buildkit attestations digests for linux/amd64', async () => {
const digests = await new ImageTools().attestationDigests('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', {os: 'linux', architecture: 'amd64'});
expect(digests).toEqual(['sha256:2ba4ad6eae1efcafee73a971953093c7c32b6938f2f9fd4998c8bf4d0fbe76f2']);
});
it('returns buildkit attestations digests for linux/arm/v7', async () => {
const digests = await new ImageTools().attestationDigests('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', {os: 'linux', architecture: 'arm', variant: 'v7'});
expect(digests).toEqual(['sha256:0709528fae1747ce17638ad2978ee7936b38a294136eaadaf692e415f64b1e03']);
});
});

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,19 +84,16 @@ 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', () => {
// eslint-disable-next-line jest/no-disabled-tests
it.skip('builds refs/pull/648/head', async () => {
const install = new Install();
const toolPath = await install.build('https://github.com/docker/buildx.git#refs/pull/648/head');
@@ -111,7 +102,6 @@ describe('build', () => {
expect(fs.existsSync(buildxBin)).toBe(true);
}, 100000);
// eslint-disable-next-line jest/no-disabled-tests
it.skip('builds 67bd6f4dc82a9cd96f34133dab3f6f7af803bb14', async () => {
const install = new Install();
const toolPath = await install.build('https://github.com/docker/buildx.git#67bd6f4dc82a9cd96f34133dab3f6f7af803bb14');
@@ -127,7 +117,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 +130,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 +143,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 +156,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 +169,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 +210,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

@@ -49,7 +49,6 @@ describe('isAvailable', () => {
standalone: false
});
await compose.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`docker`, ['compose'], {
silent: true,
ignoreReturnCode: true
@@ -61,7 +60,6 @@ describe('isAvailable', () => {
standalone: true
});
await compose.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`compose`, [], {
silent: true,
ignoreReturnCode: true

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,89 @@
/**
* 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();
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,53 @@
/**
* 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: version,
verifySignature: true
});
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,137 @@
/**
* 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: version,
ghaNoCache: 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({
version: '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

@@ -57,7 +57,7 @@ describe('isInsideWorkTree', () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
try {
await Git.isInsideWorkTree();
} catch (err) {
} catch {
// noop
}
expect(execSpy).toHaveBeenCalledWith(`git`, ['rev-parse', '--is-inside-work-tree'], {
@@ -81,7 +81,7 @@ describe('remoteURL', () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
try {
await Git.remoteURL();
} catch (err) {
} catch {
// noop
}
expect(execSpy).toHaveBeenCalledWith(`git`, ['remote', 'get-url', 'origin'], {
@@ -233,6 +233,208 @@ describe('ref', () => {
expect(ref).toEqual('refs/heads/test');
});
it('returns mocked detached branch ref checked out by SHA', async () => {
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
const fullCmd = `${cmd} ${args?.join(' ')}`;
let result = '';
switch (fullCmd) {
case 'git branch --show-current':
result = '';
break;
case 'git show -s --pretty=%D':
result = 'HEAD, origin/feature-branch';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});
const ref = await Git.ref();
expect(ref).toEqual('refs/heads/feature-branch');
});
it('infers ref from local branch when detached HEAD returns only "HEAD"', async () => {
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
const fullCmd = `${cmd} ${args?.join(' ')}`;
let result = '';
switch (fullCmd) {
case 'git branch --show-current':
result = '';
break;
case 'git show -s --pretty=%D':
result = 'HEAD';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/heads/':
result = 'refs/heads/main\nrefs/heads/develop';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});
const ref = await Git.ref();
expect(ref).toEqual('refs/heads/main');
});
it('infers ref from local branch when detached HEAD returns only "grafted, HEAD"', async () => {
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
const fullCmd = `${cmd} ${args?.join(' ')}`;
let result = '';
switch (fullCmd) {
case 'git branch --show-current':
result = '';
break;
case 'git show -s --pretty=%D':
result = 'grafted, HEAD';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/heads/':
result = 'refs/heads/main\nrefs/heads/develop';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});
const ref = await Git.ref();
expect(ref).toEqual('refs/heads/main');
});
it('infers ref from remote branch when no local branch contains HEAD', async () => {
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
const fullCmd = `${cmd} ${args?.join(' ')}`;
let result = '';
switch (fullCmd) {
case 'git branch --show-current':
result = '';
break;
case 'git show -s --pretty=%D':
result = 'HEAD';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/heads/':
result = '';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/remotes/':
result = 'refs/remotes/origin/feature';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});
const ref = await Git.ref();
expect(ref).toEqual('refs/heads/feature');
});
it('infers ref from tag when no branch contains HEAD', async () => {
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
const fullCmd = `${cmd} ${args?.join(' ')}`;
let result = '';
switch (fullCmd) {
case 'git branch --show-current':
result = '';
break;
case 'git show -s --pretty=%D':
result = 'HEAD';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/heads/':
result = '';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/remotes/':
result = '';
break;
case 'git tag --contains HEAD':
result = 'v1.0.0\nv0.9.0';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});
const ref = await Git.ref();
expect(ref).toEqual('refs/tags/v1.0.0');
});
it('throws error when cannot infer ref from detached HEAD', async () => {
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
const fullCmd = `${cmd} ${args?.join(' ')}`;
let result = '';
switch (fullCmd) {
case 'git branch --show-current':
result = '';
break;
case 'git show -s --pretty=%D':
result = 'HEAD';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/heads/':
result = '';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/remotes/':
result = '';
break;
case 'git tag --contains HEAD':
result = '';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});
await expect(Git.ref()).rejects.toThrow('Cannot infer ref from detached HEAD');
});
it('handles remote ref without branch pattern when inferring from remote', async () => {
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
const fullCmd = `${cmd} ${args?.join(' ')}`;
let result = '';
switch (fullCmd) {
case 'git branch --show-current':
result = '';
break;
case 'git show -s --pretty=%D':
result = 'HEAD';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/heads/':
result = '';
break;
case 'git for-each-ref --format=%(refname) --contains HEAD --sort=-committerdate refs/remotes/':
result = 'refs/remotes/unusual-format';
break;
}
return Promise.resolve({
stdout: result,
stderr: '',
exitCode: 0
});
});
const ref = await Git.ref();
expect(ref).toEqual('refs/remotes/unusual-format');
});
});
describe('fullCommit', () => {
@@ -240,7 +442,7 @@ describe('fullCommit', () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
try {
await Git.fullCommit();
} catch (err) {
} catch {
// noop
}
expect(execSpy).toHaveBeenCalledWith(`git`, ['show', '--format=%H', 'HEAD', '--quiet', '--'], {
@@ -255,7 +457,7 @@ describe('shortCommit', () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
try {
await Git.shortCommit();
} catch (err) {
} catch {
// noop
}
expect(execSpy).toHaveBeenCalledWith(`git`, ['show', '--format=%h', 'HEAD', '--quiet', '--'], {
@@ -270,7 +472,7 @@ describe('tag', () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
try {
await Git.tag();
} catch (err) {
} catch {
// noop
}
expect(execSpy).toHaveBeenCalledWith(`git`, ['tag', '--points-at', 'HEAD', '--sort', '-version:creatordate'], {

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(() => {
@@ -118,6 +141,7 @@ describe('actionsRuntimeToken', () => {
it('malformed', async () => {
process.env.ACTIONS_RUNTIME_TOKEN = 'foo';
expect(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
GitHub.actionsRuntimeToken;
}).toThrow();
});

View File

@@ -14,14 +14,17 @@
* limitations under the License.
*/
import {afterEach, describe, expect, test} from '@jest/globals';
import {afterEach, describe, expect, jest, test} 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 {OCI} from '../../src/oci/oci';
import {Platform} from '../../src/types/oci/descriptor';
const fixturesDir = path.join(__dirname, '..', '.fixtures');
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'oci-oci-'));
@@ -29,6 +32,25 @@ afterEach(function () {
rimraf.sync(tmpDir);
});
describe('defaultPlatform', () => {
test.each([
['win32', 'x64', {architecture: 'amd64', os: 'windows'}],
['win32', 'arm64', {architecture: 'arm64', os: 'windows'}],
['darwin', 'x64', {architecture: 'amd64', os: 'darwin'}],
['darwin', 'arm64', {architecture: 'arm64', os: 'darwin'}],
['linux', 'ia32', {architecture: '386', os: 'linux'}],
['linux', 'x64', {architecture: 'amd64', os: 'linux'}],
['linux', 'arm64', {architecture: 'arm64', os: 'linux'}],
['linux', 'ppc64', {architecture: 'ppc64le', os: 'linux'}],
['linux', 's390x', {architecture: 's390x', os: 'linux'}]
])('default platform for %s/%s', async (os: string, arch: string, expected: Platform) => {
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
const res = OCI.defaultPlatform();
expect(res).toEqual(expected);
});
});
describe('loadArchive', () => {
// prettier-ignore
test.each(fs.readdirSync(path.join(fixturesDir, 'oci-archive')).filter(file => {

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,122 @@
/**
* 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();
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,184 @@
/**
* 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 {beforeAll, describe, expect, jest, it, test} from '@jest/globals';
import fs from 'fs';
import * as path from 'path';
import {Buildx} from '../../src/buildx/buildx';
import {Build} from '../../src/buildx/build';
import {Install as CosignInstall} from '../../src/cosign/install';
import {Docker} from '../../src/docker/docker';
import {Exec} from '../../src/exec';
import {OCI} from '../../src/oci/oci';
import {Sigstore} from '../../src/sigstore/sigstore';
const fixturesDir = path.join(__dirname, '..', '.fixtures');
const runTest = process.env.GITHUB_ACTIONS && process.env.GITHUB_ACTIONS === 'true' && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu');
const maybe = runTest ? describe : describe.skip;
const maybeIdToken = runTest && process.env.ACTIONS_ID_TOKEN_REQUEST_URL ? describe : describe.skip;
// needs current GitHub repo info
jest.unmock('@actions/github');
beforeAll(async () => {
const cosignInstall = new CosignInstall();
const cosignBinPath = await cosignInstall.download({
version: 'v3.0.2'
});
await cosignInstall.install(cosignBinPath);
}, 100000);
maybeIdToken('signAttestationManifests', () => {
it('build, sign and verify', async () => {
const buildx = new Buildx();
const build = new Build({buildx: buildx});
const imageName = 'ghcr.io/docker/actions-toolkit/test';
await expect(
(async () => {
await Docker.getExecOutput(['login', '--password-stdin', '--username', process.env.GITHUB_REPOSITORY_OWNER || 'docker', 'ghcr.io'], {
input: Buffer.from(process.env.GITHUB_TOKEN || '')
});
})()
).resolves.not.toThrow();
await expect(
(async () => {
// prettier-ignore
const buildCmd = await buildx.getCommand([
'--builder', process.env.CTN_BUILDER_NAME ?? 'default',
'build',
'-f', path.join(fixturesDir, 'hello.Dockerfile'),
'--provenance=mode=max',
'--tag', `${imageName}:sigstore-itg`,
'--platform', 'linux/amd64,linux/arm64',
'--push',
'--metadata-file', build.getMetadataFilePath(),
fixturesDir
]);
await Exec.exec(buildCmd.command, buildCmd.args);
})()
).resolves.not.toThrow();
const metadata = build.resolveMetadata();
expect(metadata).toBeDefined();
const buildDigest = build.resolveDigest(metadata);
expect(buildDigest).toBeDefined();
const sigstore = new Sigstore();
const signResults = await sigstore.signAttestationManifests({
imageNames: [imageName],
imageDigest: buildDigest!
});
expect(Object.keys(signResults).length).toEqual(2);
const verifyResults = await sigstore.verifySignedManifests(signResults, {
certificateIdentityRegexp: `^https://github.com/docker/actions-toolkit/.github/workflows/test.yml.*$`
});
expect(Object.keys(verifyResults).length).toEqual(2);
}, 100000);
});
maybe('verifyImageAttestations', () => {
test.each([
['moby/buildkit:master@sha256:84014da3581b2ff2c14cb4f60029cf9caa272b79e58f2e89c651ea6966d7a505', `^https://github.com/docker/github-builder-experimental/.github/workflows/bake.yml.*$`],
['docker/dockerfile-upstream:master@sha256:3e8cd5ebf48acd1a1939649ad1c62ca44c029852b22493c16a9307b654334958', `^https://github.com/docker/github-builder-experimental/.github/workflows/bake.yml.*$`]
])(
'given %p',
async (image, certificateIdentityRegexp) => {
const sigstore = new Sigstore();
const verifyResults = await sigstore.verifyImageAttestations(image, {
certificateIdentityRegexp: certificateIdentityRegexp
});
expect(Object.keys(verifyResults).length).toBeGreaterThan(0);
for (const [attestationRef, res] of Object.entries(verifyResults)) {
expect(attestationRef).toBeDefined();
expect(res.cosignArgs).toBeDefined();
expect(res.signatureManifestDigest).toBeDefined();
}
},
60000
);
it('default platform', async () => {
const sigstore = new Sigstore();
const verifyResults = await sigstore.verifyImageAttestations('moby/buildkit:master@sha256:84014da3581b2ff2c14cb4f60029cf9caa272b79e58f2e89c651ea6966d7a505', {
certificateIdentityRegexp: `^https://github.com/docker/github-builder-experimental/.github/workflows/bake.yml.*$`,
platform: OCI.defaultPlatform()
});
expect(Object.keys(verifyResults).length).toEqual(1);
for (const [attestationRef, res] of Object.entries(verifyResults)) {
expect(attestationRef).toBeDefined();
expect(res.cosignArgs).toBeDefined();
expect(res.signatureManifestDigest).toBeDefined();
}
});
});
maybeIdToken('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].payload).toBeDefined();
expect(results[provenancePath].certificate).toBeDefined();
expect(results[provenancePath].tlogID).toBeDefined();
console.log(provenancePath, JSON.stringify(results[provenancePath].payload, 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.payload).toBeDefined();
expect(res.certificate).toBeDefined();
expect(res.tlogID).toBeDefined();
console.log(provenancePath, JSON.stringify(res.payload, null, 2));
}
});
});
maybeIdToken('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(signResults, {
certificateIdentityRegexp: `^https://github.com/docker/actions-toolkit/.github/workflows/test.yml.*$`
});
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

@@ -14,16 +14,14 @@
* limitations under the License.
*/
// eslint-disable-next-line @typescript-eslint/no-var-requires
/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('fs');
module.exports = results => {
const allSkipped = results.testResults.every(result => {
return result.skipped;
});
const allSkipped = results.testResults.every(result => result.skipped);
if (allSkipped) {
console.log('All tests were skipped!');
// create an empty file to signal that all tests were skipped for CI
fs.mkdirSync('./coverage', {recursive: true});
fs.closeSync(fs.openSync('./coverage/allSkipped.txt', 'w'));
}
return results;

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', () => {
@@ -46,7 +46,6 @@ describe('isAvailable', () => {
const execSpy = jest.spyOn(Exec, 'getExecOutput');
const undock = new Undock();
await undock.isAvailable();
// eslint-disable-next-line jest/no-standalone-expect
expect(execSpy).toHaveBeenCalledWith(`undock`, [], {
silent: true,
ignoreReturnCode: true

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.20.1
ARG COMPOSE_VERSION=2.32.4
ARG UNDOCK_VERSION=0.8.0
ARG DOCKER_VERSION=28.3
ARG BUILDX_VERSION=0.30.1
ARG COMPOSE_VERSION=2.39.1
ARG UNDOCK_VERSION=0.10.0
ARG REGCTL_VERSION=v0.8.2
ARG COSIGN_VERSION=v3.0.3
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git
@@ -75,44 +77,27 @@ 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
FROM scratch AS test-coverage
COPY --from=test /tmp/coverage /
FROM base AS publish
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
set -e
if ! [[ $GITHUB_REF =~ ^refs/tags/v ]]; then
echo "GITHUB_REF is not a tag"
exit 1
fi
yarn install
yarn run build
npm config set //registry.npmjs.org/:_authToken $(cat /run/secrets/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}
EOT

View File

@@ -99,23 +99,6 @@ target "test-coverage" {
secret = ["id=GITHUB_TOKEN,env=GITHUB_TOKEN"]
}
# GITHUB_REF is the actual ref that triggers the workflow and used as version
# when a tag is pushed: https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
variable "GITHUB_REF" {
default = ""
}
target "publish" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
args = {
GITHUB_REF = GITHUB_REF
}
target = "publish"
output = ["type=cacheonly"]
secret = ["id=NODE_AUTH_TOKEN,env=NODE_AUTH_TOKEN"]
}
target "license-validate" {
inherits = ["_common"]
dockerfile = "./hack/dockerfiles/license.Dockerfile"

84
eslint.config.js Normal file
View File

@@ -0,0 +1,84 @@
/**
* 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.
*/
/* eslint-disable @typescript-eslint/no-require-imports */
const {defineConfig, globalIgnores} = require('eslint/config');
const {fixupConfigRules, fixupPluginRules} = require('@eslint/compat');
const typescriptEslint = require('@typescript-eslint/eslint-plugin');
const jestPlugin = require('eslint-plugin-jest');
const prettier = require('eslint-plugin-prettier');
const globals = require('globals');
const tsParser = require('@typescript-eslint/parser');
const js = require('@eslint/js');
const {FlatCompat} = require('@eslint/eslintrc');
// __dirname and __filename exist natively in CommonJS
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});
module.exports = defineConfig([
globalIgnores(['.yarn/**/*', 'lib/**/*', 'coverage/**/*', 'node_modules/**/*']),
{
extends: fixupConfigRules(
compat.extends(
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:import/errors',
'plugin:import/typescript',
'plugin:import/warnings',
'plugin:jest/recommended',
'plugin:prettier/recommended'
)
),
plugins: {
'@typescript-eslint': fixupPluginRules(typescriptEslint),
jest: fixupPluginRules(jestPlugin),
prettier: fixupPluginRules(prettier)
},
languageOptions: {
globals: {
...globals.node,
...globals.mocha,
...globals.jest
},
parser: tsParser,
ecmaVersion: 2023,
sourceType: 'commonjs'
},
rules: {
'@typescript-eslint/no-require-imports': [
'error',
{
allowAsImport: true
}
],
'import/no-unresolved': [
'error',
{
ignore: ['csv-parse/sync', '@octokit/openapi-types']
}
],
'jest/no-disabled-tests': 0
}
}
]);

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'],
@@ -40,6 +26,6 @@ module.exports = {
moduleNameMapper: {
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
},
testResultsProcessor: './__tests__/testResultsProcessor.ts',
testResultsProcessor: '<rootDir>/__tests__/testResultsProcessor.js',
verbose: false
};

View File

@@ -14,9 +14,10 @@
* limitations under the License.
*/
import fs from 'fs';
import os from 'os';
import path from 'path';
/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('fs');
const os = require('os');
const path = require('path');
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-'));
@@ -28,9 +29,7 @@ process.env = Object.assign({}, process.env, {
GITHUB_RUN_NUMBER: 15,
RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
}) as {
[key: string]: string;
};
});
module.exports = {
clearMocks: true,
@@ -46,6 +45,6 @@ module.exports = {
},
collectCoverageFrom: ['src/**/{!(index.ts),}.ts'],
coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__mocks__/', '__tests__/'],
testResultsProcessor: './__tests__/testResultsProcessor.ts',
testResultsProcessor: '<rootDir>/__tests__/testResultsProcessor.js',
verbose: true
};

View File

@@ -12,9 +12,9 @@
"prettier:fix": "prettier --write \"./**/*.ts\"",
"test": "jest",
"test:coverage": "jest --coverage",
"test:itg": "jest -c jest.config.itg.ts --runInBand --detectOpenHandles",
"test:itg-list": "jest -c jest.config.itg.ts --listTests",
"test:itg-coverage": "jest --coverage -c jest.config.itg.ts --runInBand --detectOpenHandles"
"test:itg": "jest -c jest.config.itg.js --runInBand",
"test:itg-list": "jest -c jest.config.itg.js --listTests",
"test:itg-coverage": "jest -c jest.config.itg.js --coverage --runInBand"
},
"repository": {
"type": "git",
@@ -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,57 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"@actions/artifact": "^2.2.1",
"@actions/cache": "^4.0.1",
"@actions/core": "^1.11.1",
"@actions/exec": "^1.1.1",
"@actions/github": "^6.0.0",
"@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",
"@actions/artifact": "^5.0.2",
"@actions/cache": "^5.0.2",
"@actions/core": "^2.0.2",
"@actions/exec": "^2.0.0",
"@actions/github": "^7.0.0",
"@actions/http-client": "^3.0.1",
"@actions/io": "^2.0.0",
"@actions/tool-cache": "^3.0.0",
"@azure/storage-blob": "^12.29.1",
"@octokit/core": "^5.2.2",
"@octokit/plugin-rest-endpoint-methods": "^10.4.1",
"@sigstore/bundle": "^4.0.0",
"@sigstore/sign": "^4.1.0",
"@sigstore/tuf": "^4.0.1",
"@sigstore/verify": "^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",
"js-yaml": "^4.1.1",
"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",
"@types/gunzip-maybe": "^1.4.2",
"@eslint/compat": "^2.0.0",
"@eslint/eslintrc": "^3.3.3",
"@eslint/js": "^9.39.2",
"@sigstore/rekor-types": "^4.0.0",
"@types/gunzip-maybe": "^1.4.3",
"@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.27",
"@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",
"jest": "^29.7.0",
"prettier": "^3.2.5",
"rimraf": "^5.0.5",
"ts-jest": "^29.1.2",
"@typescript-eslint/eslint-plugin": "^8.50.0",
"@typescript-eslint/parser": "^8.50.0",
"dotenv": "^17.2.3",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.5.0",
"eslint-plugin-prettier": "^5.5.4",
"jest": "^30.2.0",
"prettier": "^3.7.4",
"rimraf": "^6.1.2",
"ts-jest": "^29.4.6",
"ts-node": "^10.9.2",
"typescript": "^5.4.5"
"typescript": "^5.9.3"
}
}

View File

@@ -85,7 +85,7 @@ export class BuildKit {
if (!bkversion) {
try {
bkversion = await this.getVersionWithinImage(node.name || '');
} catch (e) {
} catch {
core.debug(`BuildKit.versionSatisfies ${node.name}: can't get version`);
return false;
}

View File

@@ -105,13 +105,7 @@ export class Bake {
public async getDefinition(cmdOpts: BakeCmdOpts, execOptions?: ExecOptions): Promise<BakeDefinition> {
execOptions = execOptions || {ignoreReturnCode: true};
execOptions.ignoreReturnCode = true;
if (cmdOpts.githubToken) {
execOptions.env = Object.assign({}, process.env, {
BUILDX_BAKE_GIT_AUTH_TOKEN: cmdOpts.githubToken
}) as {
[key: string]: string;
};
}
execOptions.env = Object.assign({}, process.env, execOptions.env || {}, cmdOpts.githubToken ? {BUILDX_BAKE_GIT_AUTH_TOKEN: cmdOpts.githubToken} : {});
const args = ['bake'];
@@ -424,4 +418,34 @@ export class Bake {
}
return false;
}
public static hasProvenanceAttestation(def: BakeDefinition): boolean {
return Bake.hasAttestationType('provenance', Bake.attestations(def));
}
public static hasSBOMAttestation(def: BakeDefinition): boolean {
return Bake.hasAttestationType('sbom', Bake.attestations(def));
}
public static hasAttestationType(name: string, attestations: Array<AttestEntry>): boolean {
for (const attestation of attestations) {
if (attestation.type == name) {
return true;
}
}
return false;
}
private static attestations(def: BakeDefinition): Array<AttestEntry> {
const attestations = new Array<AttestEntry>();
for (const key in def.target) {
const target = def.target[key];
if (target.attest) {
for (const attest of target.attest) {
attestations.push(Bake.parseAttestEntry(attest));
}
}
}
return attestations;
}
}

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`);
}
@@ -160,7 +169,7 @@ export class Build {
}
try {
return core.getBooleanInput(name) ? `builder-id=${GitHub.workflowRunURL(true)}` : 'false';
} catch (err) {
} catch {
// not a valid boolean, so we assume it's a string
return Build.resolveProvenanceAttrs(input);
}
@@ -293,7 +302,7 @@ export class Build {
// https://github.com/docker/buildx/blob/8abef5908705e49f7ba88ef8c957e1127b597a2a/util/buildflags/attests.go#L13-L21
const v = Util.parseBool(attr);
res.push(`disabled=${!v}`);
} catch (err) {
} catch {
res.push(attr);
}
}
@@ -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

@@ -148,7 +148,7 @@ export class Buildx {
let url: URL;
try {
url = new URL(endpoint);
} catch (e) {
} catch {
return [];
}
if (url.protocol != 'tcp:') {
@@ -280,7 +280,7 @@ export class Buildx {
const fnGitURL = function (inp: string): GitURL | undefined {
try {
return Git.parseURL(inp);
} catch (e) {
} catch {
// noop
}
};

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, Platform} from '../types/oci/descriptor';
import {Digest} from '../types/oci/digest';
export interface ImageToolsOpts {
buildx?: Buildx;
@@ -58,4 +61,61 @@ 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, platform?: Platform): Promise<Array<Descriptor>> {
const manifest = await this.inspectManifest(name);
if (typeof manifest !== 'object' || manifest === null || !('manifests' in manifest) || !Array.isArray(manifest.manifests)) {
throw new Error(`No descriptor found for ${name}`);
}
const attestations = manifest.manifests.filter(m => m.annotations?.['vnd.docker.reference.type'] === 'attestation-manifest');
if (!platform) {
return attestations;
}
const manifestByDigest = new Map<string, Descriptor>();
for (const m of manifest.manifests) {
if (m.digest) {
manifestByDigest.set(m.digest, m);
}
}
return attestations.filter(attestation => {
const refDigest = attestation.annotations?.['vnd.docker.reference.digest'];
if (!refDigest) {
return false;
}
const referencedManifest = manifestByDigest.get(refDigest);
if (!referencedManifest) {
return false;
}
return referencedManifest.platform?.os === platform.os && referencedManifest.platform?.architecture === platform.architecture && (referencedManifest.platform?.variant ?? '') === (platform.variant ?? '');
});
}
public async attestationDigests(name: string, platform?: Platform): Promise<Array<Digest>> {
return (await this.attestationDescriptors(name, platform)).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

@@ -64,8 +64,12 @@ export class Cache {
if (!this.ghaNoCache && cache.isFeatureAvailable()) {
if (skipState) {
core.debug(`Cache.save caching ${this.ghaCacheKey} to GitHub Actions cache`);
await cache.saveCache([this.cacheDir], this.ghaCacheKey);
try {
core.debug(`Cache.save caching ${this.ghaCacheKey} to GitHub Actions cache`);
await cache.saveCache([this.cacheDir], this.ghaCacheKey);
} catch (e) {
core.warning(`Failed to save cache: ${e}`);
}
} else {
core.debug(`Cache.save sending ${this.ghaCacheKey} to post state`);
core.saveState(
@@ -82,26 +86,28 @@ export class Cache {
}
public async find(): Promise<string> {
let htcPath = tc.find(this.opts.htcName, this.opts.htcVersion, this.platform());
if (htcPath) {
core.info(`Restored from hosted tool cache ${htcPath}`);
return this.copyToCache(`${htcPath}/${this.opts.cacheFile}`);
}
if (!this.ghaNoCache && cache.isFeatureAvailable()) {
core.debug(`GitHub Actions cache feature available`);
if (await cache.restoreCache([this.cacheDir], this.ghaCacheKey)) {
core.info(`Restored ${this.ghaCacheKey} from GitHub Actions cache`);
htcPath = await tc.cacheDir(this.cacheDir, this.opts.htcName, this.opts.htcVersion, this.platform());
core.info(`Cached to hosted tool cache ${htcPath}`);
try {
let htcPath = tc.find(this.opts.htcName, this.opts.htcVersion, this.platform());
if (htcPath) {
core.info(`Restored from hosted tool cache ${htcPath}`);
return this.copyToCache(`${htcPath}/${this.opts.cacheFile}`);
}
} else if (this.ghaNoCache) {
core.info(`GitHub Actions cache disabled`);
} else {
core.info(`GitHub Actions cache feature not available`);
if (!this.ghaNoCache && cache.isFeatureAvailable()) {
core.debug(`GitHub Actions cache feature available`);
if (await cache.restoreCache([this.cacheDir], this.ghaCacheKey)) {
core.info(`Restored ${this.ghaCacheKey} from GitHub Actions cache`);
htcPath = await tc.cacheDir(this.cacheDir, this.opts.htcName, this.opts.htcVersion, this.platform());
core.info(`Cached to hosted tool cache ${htcPath}`);
return this.copyToCache(`${htcPath}/${this.opts.cacheFile}`);
}
} else if (this.ghaNoCache) {
core.info(`GitHub Actions cache disabled`);
} else {
core.info(`GitHub Actions cache feature not available`);
}
} catch (e) {
core.warning(`Failed to restore cache: ${e}`);
}
return '';
}
@@ -120,13 +126,17 @@ export class Cache {
if (!cacheState.dir || !cacheState.key) {
throw new Error(`Invalid cache post state: ${state}`);
}
core.info(`Caching ${cacheState.key} to GitHub Actions cache`);
await cache.saveCache([cacheState.dir], cacheState.key);
try {
core.info(`Caching ${cacheState.key} to GitHub Actions cache`);
await cache.saveCache([cacheState.dir], cacheState.key);
} catch (e) {
core.warning(`Failed to save cache: ${e}`);
}
return cacheState;
}
private copyToCache(file: string): string {
core.debug(`Copying ${file} to ${this.cachePath}`);
core.info(`Copying ${file} to ${this.cachePath}`);
fs.copyFileSync(file, this.cachePath);
return this.cachePath;
}

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];
}

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

@@ -0,0 +1,157 @@
/**
* 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 || signatureManifestFallbackDigest)) {
errors = undefined; // clear errors if we have both payload and manifest digest
break;
}
}
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 /
`;

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

@@ -0,0 +1,291 @@
/**
* 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 {bundleFromJSON, SerializedBundle} from '@sigstore/bundle';
import * as tuf from '@sigstore/tuf';
import {toSignedEntity, toTrustMaterial, Verifier} from '@sigstore/verify';
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 DownloadOpts {
version: string;
ghaNoCache?: boolean;
skipState?: boolean;
verifySignature?: boolean;
}
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(opts: DownloadOpts): Promise<string> {
const version: DownloadVersion = await Install.getDownloadVersion(opts.version);
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: opts.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}`);
if (opts.verifySignature && semver.satisfies(vspec, '>=3.0.1')) {
await this.verifySignature(htcDownloadPath, downloadURL);
}
const cacheSavePath = await installCache.save(htcDownloadPath, opts.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 async verifySignature(cosignBinPath: string, downloadURL: string): Promise<void> {
const bundleURL = `${downloadURL}.sigstore.json`;
core.info(`Downloading keyless verification bundle at ${bundleURL}`);
const bundlePath = await tc.downloadTool(bundleURL, undefined, this.githubToken);
core.debug(`Install.verifySignature bundlePath: ${bundlePath}`);
core.info(`Verifying keyless verification bundle signature`);
const parsedBundle = JSON.parse(fs.readFileSync(bundlePath, 'utf-8')) as SerializedBundle;
const bundle = bundleFromJSON(parsedBundle);
core.info(`Fetching Sigstore TUF trusted root metadata`);
const trustedRoot = await tuf.getTrustedRoot();
const trustMaterial = toTrustMaterial(trustedRoot);
try {
core.info(`Verifying cosign binary signature`);
const signedEntity = toSignedEntity(bundle, fs.readFileSync(cosignBinPath));
const verifier = new Verifier(trustMaterial);
const signer = verifier.verify(signedEntity, {
subjectAlternativeName: 'keyless@projectsigstore.iam.gserviceaccount.com',
extensions: {issuer: 'https://accounts.google.com'}
});
core.debug(`Install.verifySignature signer: ${JSON.stringify(signer)}`);
core.info(`Cosign binary signature verified!`);
} catch (err) {
throw new Error(`Failed to verify cosign binary signature: ${err}`);
}
}
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

@@ -60,7 +60,7 @@ export class Docker {
silent: true
});
return true;
} catch (e) {
} catch {
return false;
}
}

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.');
@@ -241,22 +269,12 @@ export class Install {
await io.mkdirP(limaDir);
const dockerHost = `unix://${limaDir}/docker.sock`;
// avoid brew to auto update and upgrade unrelated packages.
let envs = Object.assign({}, process.env, {
HOMEBREW_NO_AUTO_UPDATE: '1',
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: '1'
}) as {
[key: string]: string;
};
if (!(await Install.limaInstalled())) {
await core.group('Installing lima', async () => {
await Exec.exec('brew', ['install', 'lima'], {env: envs});
});
await this.brewInstall('lima');
}
await core.group('Lima version', async () => {
await Exec.exec('lima', ['--version'], {env: envs});
await Exec.exec('lima', ['--version']);
});
await core.group('Creating lima config', async () => {
@@ -285,9 +303,7 @@ export class Install {
});
if (!(await Install.qemuInstalled())) {
await core.group('Installing QEMU', async () => {
await Exec.exec('brew', ['install', 'qemu'], {env: envs});
});
await this.brewInstall('qemu');
}
const qemuBin = await Install.qemuBin();
await core.group('QEMU version', async () => {
@@ -296,14 +312,14 @@ export class Install {
// lima might already be started on the runner so env var added in download
// method is not expanded to the running process.
envs = Object.assign({}, envs, {
const envs = Object.assign({}, process.env, {
PATH: `${this.toolDir}:${process.env.PATH}`
}) as {
[key: string]: string;
};
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 +411,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 +686,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 +723,88 @@ 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);
}
private async brewInstall(packageName: string, revision?: string): Promise<void> {
// avoid brew to auto update and upgrade unrelated packages.
const envs = Object.assign({}, process.env, {
HOMEBREW_NO_AUTO_UPDATE: '1',
HOMEBREW_NO_INSTALL_UPGRADE: '1',
HOMEBREW_NO_INSTALL_CLEANUP: '1'
}) as {
[key: string]: string;
};
await core.group(`Installing ${packageName}`, async () => {
if (!revision) {
await Exec.exec('brew', ['install', packageName]);
} else {
const dockerTap = 'docker-actions-toolkit/tap';
const hasDockerTap = await Exec.getExecOutput('brew', ['tap'], {
ignoreReturnCode: true,
silent: true,
env: envs
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr);
}
for (const line of res.stdout.trim().split('\n')) {
if (line.includes(dockerTap)) {
return true;
}
}
return false;
});
if (!hasDockerTap) {
await Exec.exec('brew', ['tap-new', dockerTap], {env: envs});
}
const brewRepoTapPath = await Exec.getExecOutput('brew', ['--repo', dockerTap], {
ignoreReturnCode: true,
silent: true,
env: envs
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr);
}
return res.stdout.trim();
});
const formulaURL = `https://raw.githubusercontent.com/Homebrew/homebrew-core/${revision}/Formula/${packageName.charAt(0)}/${packageName}.rb`;
await tc.downloadTool(formulaURL, path.join(brewRepoTapPath, 'Formula', `${packageName}.rb`));
const hasFormulaInstalled = await Exec.getExecOutput('brew', ['ls', '-1'], {
ignoreReturnCode: true,
silent: true,
env: envs
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr);
}
for (const line of res.stdout.trim().split('\n')) {
if (line.trim() == packageName) {
return true;
}
}
return false;
});
if (hasFormulaInstalled) {
await Exec.exec('brew', ['uninstall', packageName, '--ignore-dependencies'], {env: envs});
}
await Exec.exec('brew', ['install', `${dockerTap}/${packageName}`], {env: envs});
}
});
}
}

View File

@@ -122,31 +122,44 @@ export class Git {
private static async getDetachedRef(): Promise<string> {
const res = await Git.exec(['show', '-s', '--pretty=%D']);
core.debug(`detached HEAD ref: ${res}`);
const normalizedRef = res.replace(/^grafted, /, '').trim();
if (normalizedRef === 'HEAD') {
return await Git.inferRefFromHead();
}
// Can be "HEAD, <tagname>" or "grafted, HEAD, <tagname>"
const refMatch = res.match(/^(grafted, )?HEAD, (.*)$/);
const refMatch = normalizedRef.match(/^HEAD, (.*)$/);
if (!refMatch || !refMatch[2]) {
if (!refMatch || !refMatch[1]) {
throw new Error(`Cannot find detached HEAD ref in "${res}"`);
}
const ref = refMatch[2].trim();
const ref = refMatch[1].trim();
// Tag refs are formatted as "tag: <tagname>"
if (ref.startsWith('tag: ')) {
return `refs/tags/${ref.split(':')[1].trim()}`;
}
// Branch refs are formatted as "<origin>/<branch-name>, <branch-name>"
// Pull request merge refs are formatted as "pull/<number>/<state>"
const prMatch = ref.match(/^pull\/\d+\/(head|merge)$/);
if (prMatch) {
return `refs/${ref}`;
}
// Branch refs can be formatted as "<origin>/<branch-name>, <branch-name>"
const branchMatch = ref.match(/^[^/]+\/[^/]+, (.+)$/);
if (branchMatch) {
return `refs/heads/${branchMatch[1].trim()}`;
}
// Pull request merge refs are formatted as "pull/<number>/<state>"
const prMatch = ref.match(/^pull\/\d+\/(head|merge)$/);
if (prMatch) {
return `refs/${ref}`;
// Branch refs checked out by its latest SHA can be formatted as "<origin>/<branch-name>"
const shaBranchMatch = ref.match(/^[^/]+\/(.+)$/);
if (shaBranchMatch) {
return `refs/heads/${shaBranchMatch[1].trim()}`;
}
throw new Error(`Unsupported detached HEAD ref in "${res}"`);
@@ -164,6 +177,43 @@ export class Git {
});
}
private static async inferRefFromHead(): Promise<string> {
const localRef = await Git.findContainingRef('refs/heads/');
if (localRef) {
return localRef;
}
const remoteRef = await Git.findContainingRef('refs/remotes/');
if (remoteRef) {
const remoteMatch = remoteRef.match(/^refs\/remotes\/[^/]+\/(.+)$/);
if (remoteMatch) {
return `refs/heads/${remoteMatch[1]}`;
}
return remoteRef;
}
const tagRef = await Git.exec(['tag', '--contains', 'HEAD']);
const [firstTag] = tagRef
.split('\n')
.map(tag => tag.trim())
.filter(tag => tag.length > 0);
if (firstTag) {
return `refs/tags/${firstTag}`;
}
throw new Error(`Cannot infer ref from detached HEAD`);
}
private static async findContainingRef(scope: string): Promise<string | undefined> {
const refs = await Git.exec(['for-each-ref', '--format=%(refname)', '--contains', 'HEAD', '--sort=-committerdate', scope]);
const [first] = refs
.split('\n')
.map(r => r.trim())
.filter(r => r.length > 0);
return first;
}
public static async commitDate(ref: string): Promise<Date> {
return new Date(await Git.exec(['show', '-s', '--format="%ci"', ref]));
}

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,62 @@ 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 {TransferProgressEvent} from '@azure/core-http';
import * as httpm from '@actions/http-client';
import {TransferProgressEvent} from '@azure/core-rest-pipeline';
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>> {
let releases: Record<string, GitHubRelease>;
try {
// try without token first
releases = await this.releasesRaw(name, opts);
} catch (error) {
if (!this.githubToken) {
throw error;
}
// try with token
releases = await this.releasesRaw(name, opts, this.githubToken);
}
return releases;
}
public async releasesRaw(name: string, opts: GitHubContentOpts, token?: string): 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, token ? {
Authorization: `token ${token}`
} : 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 +266,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 +293,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 +328,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 +390,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 +409,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;
}
}

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
import fs from 'fs';
import os from 'os';
import gunzip from 'gunzip-maybe';
import * as path from 'path';
import {Readable} from 'stream';
@@ -21,12 +22,59 @@ import * as tar from 'tar-stream';
import {Archive, LoadArchiveOpts} from '../types/oci/oci';
import {Index} from '../types/oci';
import {Platform} from '../types/oci/descriptor';
import {Manifest} from '../types/oci/manifest';
import {Image} from '../types/oci/config';
import {IMAGE_BLOBS_DIR_V1, IMAGE_INDEX_FILE_V1, IMAGE_LAYOUT_FILE_V1, ImageLayout} from '../types/oci/layout';
import {MEDIATYPE_IMAGE_INDEX_V1, MEDIATYPE_IMAGE_MANIFEST_V1} from '../types/oci/mediatype';
export class OCI {
public static defaultPlatform(): Platform {
const nodePlatform = os.platform();
const nodeArch = os.arch();
const goosMap: Record<string, string> = {
win32: 'windows',
sunos: 'solaris'
// others (linux, darwin, freebsd, openbsd, netbsd, aix, android) match Go already
};
const goArchMap: Record<string, string> = {
x64: 'amd64',
ia32: '386',
arm: 'arm',
arm64: 'arm64',
ppc64: 'ppc64le',
s390x: 's390x',
riscv64: 'riscv64',
loong64: 'loong64',
mips: 'mips',
mipsel: 'mipsle',
mips64: 'mips64',
mips64el: 'mips64le'
};
const goos = goosMap[nodePlatform] ?? nodePlatform;
const goarch = goArchMap[nodeArch] ?? nodeArch;
let variant: string | undefined;
if (goarch === 'arm') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const armVersionRaw = (process.config.variables as any)?.arm_version;
const armVersion = Number(armVersionRaw);
// Go only recognizes v5/v6/v7 for GOARM. Do not emit v8+ (that would be arm64).
if ([5, 6, 7].includes(armVersion)) {
variant = `v${armVersion}`;
}
}
return {
architecture: goarch,
os: goos,
variant: variant
};
}
public static loadArchive(opts: LoadArchiveOpts): Promise<Archive> {
return new Promise<Archive>((resolve, reject) => {
const tarex: tar.Extract = tar.extract();

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;
}
}

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

@@ -0,0 +1,437 @@
/**
* 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 * as core from '@actions/core';
import {bundleFromJSON, bundleToJSON} from '@sigstore/bundle';
import {Artifact, Bundle, CIContextProvider, DSSEBundleBuilder, FulcioSigner, RekorWitness, TSAWitness, Witness} 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 {
Endpoints,
FULCIO_URL,
ParsedBundle,
REKOR_URL,
SEARCH_URL,
SignAttestationManifestsOpts,
SignAttestationManifestsResult,
SignProvenanceBlobsOpts,
SignProvenanceBlobsResult,
TSASERVER_URL,
VerifySignedArtifactsOpts,
VerifySignedArtifactsResult,
VerifySignedManifestsOpts,
VerifySignedManifestsResult
} from '../types/sigstore/sigstore';
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 = [
'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', ['--verbose', ...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 {
// prettier-ignore
throw new Error(`Cosign sign command failed with: ${execRes.stderr.trim().split(/\r?\n/).filter(line => line.length > 0).pop() ?? 'unknown error'}`);
}
}
const parsedBundle = Sigstore.parseBundle(bundleFromJSON(signResult.bundle));
if (parsedBundle.tlogID) {
core.info(`Uploaded to Rekor transparency log: ${SEARCH_URL}?logIndex=${parsedBundle.tlogID}`);
}
core.info(`Signature manifest pushed: https://oci.dag.dev/?referrers=${attestationRef}`);
result[attestationRef] = {
...parsedBundle,
imageName: imageName
};
});
}
}
} catch (err) {
throw new Error(`Signing BuildKit attestation manifests failed: ${(err as Error).message}`);
}
return result;
}
public async verifySignedManifests(signedManifestsResult: Record<string, SignAttestationManifestsResult>, opts: VerifySignedManifestsOpts): Promise<Record<string, VerifySignedManifestsResult>> {
const result: Record<string, VerifySignedManifestsResult> = {};
for (const [attestationRef, signedRes] of Object.entries(signedManifestsResult)) {
await core.group(`Verifying signature of ${attestationRef}`, async () => {
const verifyResult = await this.verifyImageAttestation(attestationRef, {
certificateIdentityRegexp: opts.certificateIdentityRegexp,
noTransparencyLog: opts.noTransparencyLog || !signedRes.tlogID,
retryOnManifestUnknown: opts.retryOnManifestUnknown
});
core.info(`Signature manifest verified: https://oci.dag.dev/?image=${signedRes.imageName}@${verifyResult.signatureManifestDigest}`);
result[attestationRef] = verifyResult;
});
}
return result;
}
public async verifyImageAttestations(image: string, opts: VerifySignedManifestsOpts): Promise<Record<string, VerifySignedManifestsResult>> {
const result: Record<string, VerifySignedManifestsResult> = {};
const attestationDigests = await this.imageTools.attestationDigests(image, opts.platform);
if (attestationDigests.length === 0) {
throw new Error(`No attestation manifests found for ${image}`);
}
const imageName = image.split(':', 1)[0];
for (const attestationDigest of attestationDigests) {
const attestationRef = `${imageName}@${attestationDigest}`;
const verifyResult = await this.verifyImageAttestation(attestationRef, opts);
core.info(`Signature manifest verified: https://oci.dag.dev/?image=${imageName}@${verifyResult.signatureManifestDigest}`);
result[attestationRef] = verifyResult;
}
return result;
}
public async verifyImageAttestation(attestationRef: string, opts: VerifySignedManifestsOpts): Promise<VerifySignedManifestsResult> {
if (!(await this.cosign.isAvailable())) {
throw new Error('Cosign is required to verify signed manifests');
}
// prettier-ignore
const cosignArgs = [
'verify',
'--experimental-oci11',
'--new-bundle-format',
'--certificate-oidc-issuer', 'https://token.actions.githubusercontent.com',
'--certificate-identity-regexp', opts.certificateIdentityRegexp
];
if (opts.noTransparencyLog) {
// skip tlog verification but still verify the signed timestamp
cosignArgs.push('--use-signed-timestamps', '--insecure-ignore-tlog');
}
if (!opts.retryOnManifestUnknown) {
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
const execRes = await Exec.getExecOutput('cosign', ['--verbose', ...cosignArgs, attestationRef], {
ignoreReturnCode: true,
silent: true,
env: Object.assign({}, process.env, {
COSIGN_EXPERIMENTAL: '1'
}) as {[key: string]: string}
});
if (execRes.exitCode !== 0) {
// prettier-ignore
throw new Error(`Cosign verify command failed with: ${execRes.stderr.trim().split(/\r?\n/).filter(line => line.length > 0).pop() ?? 'unknown error'}`);
}
const verifyResult = Cosign.parseCommandOutput(execRes.stderr.trim());
return {
cosignArgs: cosignArgs,
signatureManifestDigest: verifyResult.signatureManifestDigest!
};
}
const retries = 15;
let lastError: Error | undefined;
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
for (let attempt = 0; attempt < retries; attempt++) {
const execRes = await Exec.getExecOutput('cosign', ['--verbose', ...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) {
return {
cosignArgs: cosignArgs,
signatureManifestDigest: verifyResult.signatureManifestDigest!
};
} 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 {
// prettier-ignore
throw new Error(`Cosign verify command failed with: ${execRes.stderr.trim().split(/\r?\n/).filter(line => line.length > 0).pop() ?? 'unknown error'}`);
}
}
}
throw lastError;
}
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 Sigstore.signPayload(
{
data: blob,
type: INTOTO_MEDIATYPE_PAYLOAD
},
endpoints
);
const parsedBundle = Sigstore.parseBundle(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 (parsedBundle.tlogID) {
core.info(`Attestation signature uploaded to Rekor transparency log: ${SEARCH_URL}?logIndex=${parsedBundle.tlogID}`);
}
core.info(`Writing Sigstore bundle to: ${bundlePath}`);
fs.writeFileSync(bundlePath, JSON.stringify(parsedBundle.payload, null, 2), {
encoding: 'utf-8'
});
result[p] = {
...parsedBundle,
bundlePath: bundlePath,
subjects: subjects
};
});
}
} catch (err) {
throw new Error(`Signing BuildKit provenance blobs failed: ${(err as Error).message}`);
}
return result;
}
public async verifySignedArtifacts(signedArtifactsResult: Record<string, SignProvenanceBlobsResult>, opts: VerifySignedArtifactsOpts): 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(signedArtifactsResult)) {
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 (opts.noTransparencyLog || !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
}));
}
private static async signPayload(artifact: Artifact, endpoints: Endpoints, timeout?: number, retries?: number): Promise<Bundle> {
const witnesses: Witness[] = [];
const signer = new FulcioSigner({
identityProvider: new CIContextProvider('sigstore'),
fulcioBaseURL: endpoints.fulcioURL,
timeout: timeout,
retry: retries
});
if (endpoints.rekorURL) {
witnesses.push(
new RekorWitness({
rekorBaseURL: endpoints.rekorURL,
fetchOnConflict: true,
timeout: timeout,
retry: retries
})
);
}
if (endpoints.tsaServerURL) {
witnesses.push(
new TSAWitness({
tsaBaseURL: endpoints.tsaServerURL,
timeout: timeout,
retry: retries
})
);
}
return new DSSEBundleBuilder({signer, witnesses}).create(artifact);
}
private static parseBundle(bundle: Bundle): ParsedBundle {
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 {
payload: 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();
}
}

Some files were not shown because too many files have changed in this diff Show More