Compare commits

...

58 Commits

Author SHA1 Message Date
CrazyMax
29efe4d6a8 Merge pull request #1024 from crazy-max/subdir-dot
Some checks failed
publish / publish (push) Has been cancelled
buildx(build): ignore dot git context subdir
2026-03-18 09:59:13 +01:00
CrazyMax
aacbc67b8d buildx(build): ignore dot git context subdir
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-18 09:53:58 +01:00
CrazyMax
d71b84aad5 Merge pull request #1020 from crazy-max/build-git-context-opts
Some checks failed
publish / publish (push) Has been cancelled
buildx(build): support git context subdir and other query options
2026-03-18 09:24:44 +01:00
CrazyMax
ea05649ce1 Merge pull request #1023 from crazy-max/bake-vars
bake: var cmd opt support
2026-03-18 09:24:22 +01:00
CrazyMax
012ae0603d bake: var cmd opt support
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-18 09:15:22 +01:00
CrazyMax
6194cf96c1 Merge pull request #1022 from docker/dependabot/npm_and_yarn/fast-xml-parser-5.5.6
build(deps): bump fast-xml-parser from 5.4.1 to 5.5.6
2026-03-18 09:00:41 +01:00
CrazyMax
e804b694a2 Merge pull request #1021 from docker/dependabot/npm_and_yarn/csv-parse-6.2.0
build(deps): bump csv-parse from 6.1.0 to 6.2.0
2026-03-18 09:00:07 +01:00
dependabot[bot]
d2a882884d build(deps): bump fast-xml-parser from 5.4.1 to 5.5.6
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.4.1 to 5.5.6.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.4.1...v5.5.6)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-version: 5.5.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-18 01:53:33 +00:00
dependabot[bot]
d820ad4123 build(deps): bump csv-parse from 6.1.0 to 6.2.0
Bumps [csv-parse](https://github.com/adaltas/node-csv/tree/HEAD/packages/csv-parse) from 6.1.0 to 6.2.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.2.0/packages/csv-parse)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-17 22:53:46 +00:00
CrazyMax
a5d905690f Merge pull request #1019 from docker/dependabot/github_actions/softprops/action-gh-release-2.6.1
build(deps): bump softprops/action-gh-release from 2.5.0 to 2.6.1
2026-03-17 15:42:31 +01:00
CrazyMax
6233293ae6 buildx(build): support git context subdir and other query options
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-17 13:09:33 +01:00
dependabot[bot]
9d10fe0e06 build(deps): bump softprops/action-gh-release from 2.5.0 to 2.6.1
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.5.0 to 2.6.1.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](a06a81a03e...153bb8e044)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.6.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-16 22:53:05 +00:00
CrazyMax
a8dc8088d4 Merge pull request #1018 from docker/dependabot/npm_and_yarn/undici-6.24.1
build(deps): bump undici from 6.23.0 to 6.24.1
2026-03-14 12:51:58 +01:00
dependabot[bot]
4bc2c14908 build(deps): bump undici from 6.23.0 to 6.24.1
Bumps [undici](https://github.com/nodejs/undici) from 6.23.0 to 6.24.1.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.23.0...v6.24.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-14 09:18:22 +00:00
CrazyMax
ad2312d5f1 Merge pull request #1016 from crazy-max/imagetools-inspect-retry
Some checks failed
publish / publish (push) Has been cancelled
buildx(imagetools): make manifest retries configurable
2026-03-13 13:46:44 +01:00
CrazyMax
21e2b75b0b buildx(imagetools): make manifest retries configurable
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-13 13:29:09 +01:00
CrazyMax
4d926d8b7b Merge pull request #1015 from docker/dependabot/npm_and_yarn/actions/artifact-6.2.1
Some checks failed
publish / publish (push) Has been cancelled
build(deps): bump @actions/artifact from 6.2.0 to 6.2.1
2026-03-13 11:19:34 +01:00
dependabot[bot]
293c3cdcfe build(deps): bump @actions/artifact from 6.2.0 to 6.2.1
Bumps [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) from 6.2.0 to 6.2.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: 6.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-11 22:53:45 +00:00
CrazyMax
17071615a7 Merge pull request #1014 from crazy-max/imagetools-annotations
buildx(imagetools): add annotations support for create command
2026-03-10 12:22:44 +01:00
CrazyMax
0cc9e68b03 buildx(imagetools): add annotations support for create command
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-10 12:06:12 +01:00
CrazyMax
b732db2937 Merge pull request #809 from crazy-max/git-query-url
Some checks failed
publish / publish (push) Has been cancelled
build: git context query format support
2026-03-09 17:26:11 +01:00
CrazyMax
8696544f14 Merge pull request #1013 from crazy-max/imagetools-silent
buildx(imagetools): add skip support and configurable create command silence
2026-03-09 11:32:54 +01:00
CrazyMax
d92ed04680 buildx(imagetools): add skip support and configurable create command silence
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-09 11:17:55 +01:00
CrazyMax
3bb4ae38ea build: git context query format support
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-09 10:47:48 +01:00
CrazyMax
09c0f6a78e Merge pull request #1009 from crazy-max/imagetools-create
Some checks failed
publish / publish (push) Has been cancelled
buildx(imagetools): implement create func with metadata parsing
2026-03-06 09:37:07 +01:00
CrazyMax
3c25c1eed2 Merge pull request #1011 from docker/dependabot/github_actions/docker/setup-buildx-action-4
build(deps): bump docker/setup-buildx-action from 3 to 4
2026-03-06 09:36:29 +01:00
CrazyMax
ee671ae33e Merge pull request #1010 from docker/dependabot/github_actions/docker/bake-action-7
build(deps): bump docker/bake-action from 6 to 7
2026-03-06 09:36:05 +01:00
CrazyMax
960acb25ae ci: switch to matrix subaction
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-06 09:28:21 +01:00
CrazyMax
1ff078d955 Merge pull request #1012 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2026-03-06 09:22:38 +01:00
crazy-max
abe7883e9a github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-06 00:46:27 +00:00
dependabot[bot]
c16b4fdf35 build(deps): bump docker/setup-buildx-action from 3 to 4
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-05 23:04:37 +00:00
dependabot[bot]
211c9b2312 build(deps): bump docker/bake-action from 6 to 7
Bumps [docker/bake-action](https://github.com/docker/bake-action) from 6 to 7.
- [Release notes](https://github.com/docker/bake-action/releases)
- [Commits](https://github.com/docker/bake-action/compare/v6...v7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-05 23:04:32 +00:00
CrazyMax
a30e0f51eb Merge pull request #1007 from crazy-max/buildkit-0.28.0
update buildkit to 0.28.0 and buildx to 0.32.1
2026-03-05 14:51:09 +01:00
CrazyMax
61c3c53dbf update buildkit to 0.28.0 and buildx to 0.32.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-05 14:36:36 +01:00
CrazyMax
91a5724116 buildx(imagetools): implement create func with metadata parsing
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-05 13:42:21 +01:00
Tõnis Tiigi
9998df7a3d Merge pull request #1008 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2026-03-04 12:39:44 -08:00
tonistiigi
3d448bd483 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-04 20:39:03 +00:00
CrazyMax
51cc1b5526 Merge pull request #1006 from crazy-max/rm-field-history
Some checks failed
publish / publish (push) Has been cancelled
buildx(history): require buildx >=0.23.0 to export a build record
2026-03-04 14:58:07 +01:00
CrazyMax
58584e3d97 buildx(history): require buildx >=0.23.0 to export a build record
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-04 14:38:19 +01:00
CrazyMax
f06e39e022 buildx(history): remove unused field
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-04 14:34:21 +01:00
CrazyMax
4c705618e1 Merge pull request #1005 from crazy-max/util-inputlist-comment
util: add commentNoInfix support to getInputList
2026-03-04 13:36:35 +01:00
CrazyMax
1ebb922e84 util: add commentNoInfix support to getInputList
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-04 12:57:36 +01:00
Tõnis Tiigi
9e446b0b90 Merge pull request #1004 from docker/bot/buildx-releases-json
Some checks failed
publish / publish (push) Has been cancelled
Update `.github/buildx-releases.json`
2026-03-03 17:29:22 -08:00
tonistiigi
d682d6d4a5 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-04 01:28:43 +00:00
CrazyMax
ca5ab569e5 Merge pull request #895 from crazy-max/remove-export-legacy
buildx(history): remove legacy export-build tool
2026-03-03 21:16:01 +01:00
CrazyMax
5b2d914820 Merge pull request #1002 from docker/dependabot/github_actions/crazy-max/ghaction-github-runtime-4
build(deps): bump crazy-max/ghaction-github-runtime from 3 to 4
2026-03-03 10:54:17 +01:00
CrazyMax
b873721f89 Merge pull request #1000 from crazy-max/node24
update to node 24
2026-03-03 10:53:27 +01:00
dependabot[bot]
c975cd6494 build(deps): bump crazy-max/ghaction-github-runtime from 3 to 4
Bumps [crazy-max/ghaction-github-runtime](https://github.com/crazy-max/ghaction-github-runtime) from 3 to 4.
- [Release notes](https://github.com/crazy-max/ghaction-github-runtime/releases)
- [Commits](https://github.com/crazy-max/ghaction-github-runtime/compare/v3...v4)

---
updated-dependencies:
- dependency-name: crazy-max/ghaction-github-runtime
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-03 00:08:23 +00:00
CrazyMax
a0a3952b2d update to node 24
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-02 19:40:15 +01:00
CrazyMax
4af1413de8 Merge pull request #1001 from crazy-max/buildkit-0.28.0-rc2
update buildkit to 0.28.0-rc2 and buildx to 0.32.0-rc2
2026-03-02 17:13:06 +01:00
CrazyMax
83a4cb6e7f update buildkit to 0.28.0-rc2 and buildx to 0.32.0-rc2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-02 16:19:08 +01:00
CrazyMax
9edbb73678 buildx(history): remove legacy export-build tool
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-02 15:11:54 +01:00
CrazyMax
6fc9119f7e Merge pull request #998 from crazy-max/test-output
test: fix name output
2026-03-01 14:28:17 +01:00
CrazyMax
b2caa9ae45 Merge pull request #997 from docker/bot/docker-releases-json
Update `.github/docker-releases.json`
2026-03-01 11:57:27 +01:00
CrazyMax
80446a55b4 Merge pull request #996 from docker/bot/buildx-releases-json
Update `.github/buildx-releases.json`
2026-03-01 11:57:10 +01:00
CrazyMax
c7c816aa2f test: fix name output
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2026-03-01 11:51:12 +01:00
crazy-max
3f87521aad github: update .github/docker-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-28 00:38:35 +00:00
crazy-max
c186677904 github: update .github/buildx-releases.json
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-28 00:27:57 +00:00
46 changed files with 1215 additions and 553 deletions

View File

@@ -1,150 +1,372 @@
{
"latest": {
"id": 280887108,
"tag_name": "v0.31.1",
"html_url": "https://github.com/docker/buildx/releases/tag/v0.31.1",
"id": 293153745,
"tag_name": "v0.32.1",
"html_url": "https://github.com/docker/buildx/releases/tag/v0.32.1",
"assets": [
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.darwin-amd64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.darwin-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.darwin-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.darwin-arm64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.darwin-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.darwin-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.freebsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.freebsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.freebsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.freebsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.freebsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.freebsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.freebsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.freebsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-amd64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm-v6",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm-v6.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm-v6.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm-v6.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm-v7",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm-v7.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm-v7.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm-v7.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-ppc64le",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-ppc64le.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-ppc64le.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-ppc64le.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-riscv64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-riscv64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-riscv64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-riscv64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-s390x",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-s390x.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-s390x.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.linux-s390x.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.netbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.netbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.netbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.netbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.netbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.netbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.netbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.netbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.openbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.openbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.openbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.openbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.openbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.openbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.openbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.openbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.windows-amd64.exe",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.windows-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.windows-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.windows-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.windows-arm64.exe",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.windows-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.windows-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/buildx-v0.31.1.windows-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.31.1/checksums.txt"
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/checksums.txt"
]
},
"v0.32.1": {
"id": 293153745,
"tag_name": "v0.32.1",
"html_url": "https://github.com/docker/buildx/releases/tag/v0.32.1",
"assets": [
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/checksums.txt"
]
},
"v0.32.0": {
"id": 292739715,
"tag_name": "v0.32.0",
"html_url": "https://github.com/docker/buildx/releases/tag/v0.32.0",
"assets": [
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.darwin-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.darwin-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.darwin-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.darwin-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.darwin-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.darwin-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.freebsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.freebsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.freebsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.freebsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.freebsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.freebsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.freebsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.freebsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm-v6",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm-v6.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm-v6.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm-v6.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm-v7",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm-v7.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm-v7.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm-v7.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-ppc64le",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-ppc64le.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-ppc64le.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-ppc64le.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-riscv64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-riscv64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-riscv64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-riscv64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-s390x",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-s390x.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-s390x.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.linux-s390x.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.netbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.netbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.netbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.netbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.netbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.netbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.netbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.netbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.openbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.openbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.openbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.openbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.openbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.openbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.openbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.openbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.windows-amd64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.windows-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.windows-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.windows-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.windows-arm64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.windows-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.windows-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/buildx-v0.32.0.windows-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0/checksums.txt"
]
},
"edge": {
"id": 290111799,
"tag_name": "v0.32.0-rc1",
"html_url": "https://github.com/docker/buildx/releases/tag/v0.32.0-rc1",
"id": 293153745,
"tag_name": "v0.32.1",
"html_url": "https://github.com/docker/buildx/releases/tag/v0.32.1",
"assets": [
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.darwin-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.darwin-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.darwin-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.darwin-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.darwin-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.darwin-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.freebsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.freebsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.freebsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.freebsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.freebsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.freebsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.freebsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.freebsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm-v6",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm-v6.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm-v6.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm-v6.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm-v7",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm-v7.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm-v7.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm-v7.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-ppc64le",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-ppc64le.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-ppc64le.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-ppc64le.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-riscv64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-riscv64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-riscv64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-riscv64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-s390x",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-s390x.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-s390x.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.linux-s390x.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.netbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.netbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.netbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.netbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.netbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.netbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.netbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.netbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.openbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.openbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.openbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.openbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.openbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.openbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.openbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.openbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.windows-amd64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.windows-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.windows-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.windows-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.windows-arm64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.windows-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.windows-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/buildx-v0.32.0-rc1.windows-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc1/checksums.txt"
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.darwin-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.freebsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v6.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm-v7.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-ppc64le.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-riscv64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.linux-s390x.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.netbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.openbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/buildx-v0.32.1.windows-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.1/checksums.txt"
]
},
"v0.32.0-rc2": {
"id": 291436359,
"tag_name": "v0.32.0-rc2",
"html_url": "https://github.com/docker/buildx/releases/tag/v0.32.0-rc2",
"assets": [
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.darwin-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.darwin-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.darwin-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.darwin-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.darwin-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.darwin-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.freebsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.freebsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.freebsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.freebsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.freebsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.freebsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.freebsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.freebsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm-v6",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm-v6.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm-v6.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm-v6.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm-v7",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm-v7.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm-v7.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm-v7.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-ppc64le",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-ppc64le.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-ppc64le.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-ppc64le.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-riscv64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-riscv64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-riscv64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-riscv64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-s390x",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-s390x.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-s390x.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.linux-s390x.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.netbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.netbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.netbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.netbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.netbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.netbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.netbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.netbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.openbsd-amd64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.openbsd-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.openbsd-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.openbsd-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.openbsd-arm64",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.openbsd-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.openbsd-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.openbsd-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.windows-amd64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.windows-amd64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.windows-amd64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.windows-amd64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.windows-arm64.exe",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.windows-arm64.provenance.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.windows-arm64.sbom.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/buildx-v0.32.0-rc2.windows-arm64.sigstore.json",
"https://github.com/docker/buildx/releases/download/v0.32.0-rc2/checksums.txt"
]
},
"v0.32.0-rc1": {

View File

@@ -1,8 +1,26 @@
{
"latest": {
"id": 282275652,
"tag_name": "docker-v29.2.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.2.1",
"id": 293527283,
"tag_name": "docker-v29.3.0",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.3.0",
"assets": []
},
"v29.3.0": {
"id": 293527283,
"tag_name": "docker-v29.3.0",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.3.0",
"assets": []
},
"edge": {
"id": 293527283,
"tag_name": "docker-v29.3.0",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.3.0",
"assets": []
},
"v29.3.0-rc.1": {
"id": 291481223,
"tag_name": "docker-v29.3.0-rc.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.3.0-rc.1",
"assets": []
},
"v29.2.1": {
@@ -17,12 +35,6 @@
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.2.0",
"assets": []
},
"edge": {
"id": 282275652,
"tag_name": "docker-v29.2.1",
"html_url": "https://github.com/moby/moby/releases/tag/docker-v29.2.1",
"assets": []
},
"v29.2.0-rc.2": {
"id": 277933908,
"tag_name": "docker-v29.2.0-rc.2",

View File

@@ -24,7 +24,7 @@ jobs:
steps:
-
name: Build
uses: docker/bake-action@v6
uses: docker/bake-action@v7
with:
targets: build
env:

View File

@@ -12,7 +12,7 @@ permissions:
security-events: write
env:
NODE_VERSION: 20
NODE_VERSION: "24"
jobs:
analyze:

View File

@@ -14,7 +14,7 @@ on:
- 'v*'
env:
NODE_VERSION: "24" # at least Node 24 is required for Trusted Publishing with OIDC
NODE_VERSION: "24"
jobs:
publish:
@@ -53,7 +53,7 @@ jobs:
npm publish --provenance --access public
-
name: Create Release
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
with:
draft: true
generate_release_notes: true

View File

@@ -14,9 +14,9 @@ on:
- '.github/*-releases.json'
env:
NODE_VERSION: "20"
BUILDX_VERSION: "v0.32.0-rc1"
BUILDKIT_IMAGE: "moby/buildkit:v0.28.0-rc1"
NODE_VERSION: "24"
BUILDX_VERSION: "v0.32.1"
BUILDKIT_IMAGE: "moby/buildkit:v0.28.0"
jobs:
test:
@@ -36,7 +36,7 @@ jobs:
uses: actions/checkout@v6
-
name: Test
uses: docker/bake-action@v6
uses: docker/bake-action@v7
with:
source: .
targets: test-coverage
@@ -156,7 +156,7 @@ jobs:
uses: actions/checkout@v6
-
name: Expose GitHub Runtime
uses: crazy-max/ghaction-github-runtime@v3
uses: crazy-max/ghaction-github-runtime@v4
-
# FIXME: Needs to setup node twice on Windows: https://github.com/actions/setup-node/issues/1357#issuecomment-3254613964
name: Setup Node
@@ -179,7 +179,7 @@ jobs:
-
name: Set up Docker Buildx
if: startsWith(matrix.os, 'ubuntu')
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
with:
version: ${{ env.BUILDX_VERSION }}
driver: docker
@@ -187,7 +187,7 @@ jobs:
name: Set up container builder
if: startsWith(matrix.os, 'ubuntu')
id: builder
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
with:
version: ${{ env.BUILDX_VERSION }}
driver-opts: image=${{ env.BUILDKIT_IMAGE }}

View File

@@ -17,15 +17,15 @@ jobs:
prepare:
runs-on: ubuntu-latest
outputs:
targets: ${{ steps.generate.outputs.targets }}
matrix: ${{ steps.generate.outputs.matrix }}
steps:
-
name: Checkout
uses: actions/checkout@v6
-
name: List targets
name: Generate matrix
id: generate
uses: docker/bake-action/subaction/list-targets@v6
uses: docker/bake-action/subaction/matrix@v7
with:
target: validate
@@ -36,10 +36,10 @@ jobs:
strategy:
fail-fast: false
matrix:
target: ${{ fromJson(needs.prepare.outputs.targets) }}
include: ${{ fromJson(needs.prepare.outputs.matrix) }}
steps:
-
name: Validate
uses: docker/bake-action@v6
uses: docker/bake-action@v7
with:
targets: ${{ matrix.target }}

View File

@@ -54,7 +54,7 @@ describe('satisfies', () => {
test.each([
['builder2', '>=0.10.0', true],
['builder2', '>0.11.0', false]
])('given %p', async (builderName, range, expected) => {
])('given %o', async (builderName, range, expected) => {
const buildkit = new BuildKit();
expect(await buildkit.versionSatisfies(builderName, range)).toBe(expected);
});

View File

@@ -53,7 +53,7 @@ describe('resolve', () => {
`,
null
]
])('given %p config', async (val: string, file: boolean, exValue: string, error: Error | null) => {
])('given %o config', async (val: string, file: boolean, exValue: string, error: Error | null) => {
try {
const buildkit = new BuildKit();
let config: string;

View File

@@ -181,7 +181,7 @@ describe('parseURL', () => {
} as GitURL,
false
],
])('given %p', async (ref: string, expected: GitURL, expectedErr: boolean) => {
])('given %o', async (ref: string, expected: GitURL, expectedErr: boolean) => {
try {
const got = Git.parseURL(ref);
expect(got.scheme).toEqual(expected.scheme);
@@ -329,7 +329,7 @@ describe('parseRef', () => {
'.git',
undefined
],
])('given %p', async (ref: string, expected: GitRef | undefined) => {
])('given %o', async (ref: string, expected: GitRef | undefined) => {
try {
const got = Git.parseRef(ref);
expect(got).toEqual(expected);

View File

@@ -41,7 +41,7 @@ maybe('getDefinition', () => {
// path.join(fixturesDir, 'bake-test-docker-action-remote-private.json'),
// true,
// ]
])('given %p', async (source: string, targets: string[], out: string, auth) => {
])('given %o', async (source: string, targets: string[], out: string, auth) => {
const gitAuthToken = process.env.GITHUB_TOKEN || '';
if (auth && !gitAuthToken) {
console.log(`Git auth token not available, skipping test`);

View File

@@ -102,7 +102,7 @@ describe('getDefinition', () => {
undefined,
path.join(fixturesDir, 'bake-03-default.json')
],
])('given %p', async (files: string[], targets: string[], overrides: string[], execOptions: ExecOptions | undefined, out: string) => {
])('given %o', async (files: string[], targets: string[], overrides: string[], execOptions: ExecOptions | undefined, out: string) => {
const bake = new Bake();
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
expect(await bake.getDefinition({
@@ -185,7 +185,7 @@ describe('hasLocalExporter', () => {
} as unknown as BakeDefinition,
true
]
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
])('given %o returns %o', async (def: BakeDefinition, expected: boolean) => {
expect(Bake.hasLocalExporter(def)).toEqual(expected);
});
});
@@ -285,7 +285,7 @@ describe('hasTarExporter', () => {
} as unknown as BakeDefinition,
false
],
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
])('given %o returns %o', async (def: BakeDefinition, expected: boolean) => {
expect(Bake.hasTarExporter(def)).toEqual(expected);
});
});
@@ -440,7 +440,7 @@ describe('hasDockerExporter', () => {
true,
true
],
])('given %o and load:%p returns %p', async (def: BakeDefinition, expected: boolean, load: boolean | undefined) => {
])('given %o and load: %o returns %o', async (def: BakeDefinition, expected: boolean, load: boolean | undefined) => {
expect(Bake.hasDockerExporter(def, load)).toEqual(expected);
});
});
@@ -481,7 +481,7 @@ describe('hasGitAuthTokenSecret', () => {
} as unknown as BakeDefinition,
true
],
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
])('given %o returns %o', async (def: BakeDefinition, expected: boolean) => {
expect(Bake.hasGitAuthTokenSecret(def)).toEqual(expected);
});
});
@@ -536,7 +536,7 @@ describe('hasProvenanceAttestation', () => {
} as unknown as BakeDefinition,
true
]
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
])('given %o returns %o', async (def: BakeDefinition, expected: boolean) => {
expect(Bake.hasProvenanceAttestation(def)).toEqual(expected);
});
});
@@ -591,7 +591,7 @@ describe('hasSBOMAttestation', () => {
} as unknown as BakeDefinition,
true
]
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
])('given %o returns %o', async (def: BakeDefinition, expected: boolean) => {
expect(Bake.hasSBOMAttestation(def)).toEqual(expected);
});
});

View File

@@ -22,6 +22,9 @@ import * as rimraf from 'rimraf';
import {Context} from '../../src/context.js';
import {Build} from '../../src/buildx/build.js';
import {Buildx} from '../../src/buildx/buildx.js';
import {GitContextFormat} from '../../src/types/buildx/build.js';
const fixturesDir = path.join(__dirname, '..', '.fixtures');
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'buildx-build-'));
@@ -41,6 +44,90 @@ afterEach(() => {
rimraf.sync(tmpDir);
});
describe('gitContext', () => {
const originalEnv = process.env;
beforeEach(() => {
vi.resetModules();
process.env = {
...originalEnv,
DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF: '',
BUILDX_SEND_GIT_QUERY_AS_INPUT: ''
};
});
afterEach(() => {
process.env = originalEnv;
});
type GitContextTestCase = {
ref: string;
format: GitContextFormat | undefined;
prHeadRef: boolean;
sendGitQueryAsInput: boolean;
buildxQuerySupport: boolean;
subdir?: string;
keepGitDir?: boolean;
submodules?: boolean;
};
// prettier-ignore
const gitContextCases: [GitContextTestCase, string][] = [
// no format set (defaults to fragment)
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/merge'],
[{ref: 'refs/tags/v1.0.0', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: undefined, prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/head'],
// no format set (defaults to query only when client-side query resolution is enabled and supported)
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/merge&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: undefined, prHeadRef: true, sendGitQueryAsInput: true, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/head&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: true, buildxQuerySupport: false}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, keepGitDir: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true'],
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: false, keepGitDir: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true'],
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, submodules: false}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: false, submodules: false}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
// query format
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/merge&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/tags/v1.0.0', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/tags/v1.0.0&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: 'query', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/pull/15/head&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir'}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&subdir=subdir'],
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: '.'}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir', keepGitDir: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&subdir=subdir&keep-git-dir=true'],
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, submodules: true}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=true'],
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, submodules: false}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
// fragment format
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/merge'],
[{ref: 'refs/tags/v1.0.0', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: 'fragment', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/head'],
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir'}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37:subdir'],
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: '.'}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
[{ref: 'refs/pull/15/merge', format: 'fragment', prHeadRef: true, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir'}, 'https://github.com/docker/actions-toolkit.git#refs/pull/15/head:subdir'],
];
test.each(gitContextCases)('given %o should return %o', async (input: GitContextTestCase, expected: string) => {
const {ref, format, prHeadRef, sendGitQueryAsInput, buildxQuerySupport, subdir, keepGitDir, submodules} = input;
process.env.DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF = prHeadRef ? 'true' : '';
process.env.BUILDX_SEND_GIT_QUERY_AS_INPUT = sendGitQueryAsInput ? 'true' : '';
const buildx = new Buildx();
vi.spyOn(buildx, 'versionSatisfies').mockResolvedValue(buildxQuerySupport);
const build = new Build({buildx});
expect(
await build.gitContext({
ref,
checksum: '860c1904a1ce19322e91ac35af1ab07466440c37',
format,
subdir,
keepGitDir,
submodules
})
).toEqual(expected);
});
});
describe('resolveImageID', () => {
it('matches', async () => {
const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
@@ -136,7 +223,7 @@ describe('getProvenanceInput', () => {
'',
''
],
])('given input %p', async (input: string, expected: string) => {
])('given input %o', async (input: string, expected: string) => {
setInput('provenance', input);
expect(Build.getProvenanceInput('provenance')).toEqual(expected);
});
@@ -165,7 +252,7 @@ describe('resolveProvenanceAttrs', () => {
'',
'builder-id=https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2'
],
])('given %p', async (input: string, expected: string) => {
])('given %o', async (input: string, expected: string) => {
expect(Build.resolveProvenanceAttrs(input)).toEqual(expected);
});
});
@@ -180,7 +267,7 @@ describe('resolveSecret', () => {
['=bbbbbbb', false, '', '', new Error('=bbbbbbb is not a valid secret')],
[`foo=${path.join(fixturesDir, 'secret.txt')}`, true, 'foo', 'bar', null],
[`notfound=secret`, true, '', '', new Error('secret file secret not found')]
])('given %p key and %p secret', async (kvp: string, file: boolean, exKey: string, exValue: string, error: Error | null) => {
])('given %o key and %o secret', async (kvp: string, file: boolean, exKey: string, exValue: string, error: Error | null) => {
try {
let secret: string;
if (file) {
@@ -201,7 +288,7 @@ describe('resolveSecret', () => {
['FOO=', 'FOO', '', new Error('FOO= is not a valid secret')],
['=bar', '', '', new Error('=bar is not a valid secret')],
['FOO=bar=baz', 'FOO', 'bar=baz', null]
])('given %p key and %p env', async (kvp: string, exKey: string, exValue: string, error: Error | null) => {
])('given %o key and %o env', async (kvp: string, exKey: string, exValue: string, error: Error | null) => {
try {
const secret = Build.resolveSecretEnv(kvp);
expect(secret).toEqual(`id=${exKey},env=${exValue}`);
@@ -255,7 +342,7 @@ describe('resolveCacheToAttrs', () => {
'abcd1234',
'type=gha,repository=foo/bar,mode=max,ghtoken=abcd1234',
],
])('given %p', async (input: string, githubToken: string | undefined, expected: string) => {
])('given %o', async (input: string, githubToken: string | undefined, expected: string) => {
expect(Build.resolveCacheToAttrs(input, githubToken)).toEqual(expected);
});
});
@@ -271,7 +358,7 @@ describe('hasLocalExporter', () => {
[['"type=tar","dest=/tmp/image.tar"'], false],
[['" type= local" , dest=./release-out'], true],
[['.'], true]
])('given %p returns %p', async (exporters: Array<string>, expected: boolean) => {
])('given %o returns %o', async (exporters: Array<string>, expected: boolean) => {
expect(Build.hasLocalExporter(exporters)).toEqual(expected);
});
});
@@ -287,7 +374,7 @@ describe('hasTarExporter', () => {
[['"type=tar","dest=/tmp/image.tar"'], true],
[['" type= local" , dest=./release-out'], false],
[['.'], false]
])('given %p returns %p', async (exporters: Array<string>, expected: boolean) => {
])('given %o returns %o', async (exporters: Array<string>, expected: boolean) => {
expect(Build.hasTarExporter(exporters)).toEqual(expected);
});
});
@@ -305,7 +392,7 @@ describe('hasDockerExporter', () => {
[['type=docker'], true, false],
[['type=docker'], true, true],
[['.'], true, true],
])('given %p returns %p', async (exporters: Array<string>, expected: boolean, load: boolean | undefined) => {
])('given %o returns %o', async (exporters: Array<string>, expected: boolean, load: boolean | undefined) => {
expect(Build.hasDockerExporter(exporters, load)).toEqual(expected);
});
});
@@ -316,7 +403,7 @@ describe('hasAttestationType', () => {
['type=provenance,mode=min', 'provenance', true],
['type=sbom,true', 'sbom', true],
['type=foo,bar', 'provenance', false],
])('given %p for %p returns %p', async (attrs: string, name: string, expected: boolean) => {
])('given %o for %o returns %o', async (attrs: string, name: string, expected: boolean) => {
expect(Build.hasAttestationType(name, attrs)).toEqual(expected);
});
});
@@ -340,7 +427,7 @@ describe('resolveAttestationAttrs', () => {
'',
''
],
])('given %p', async (input: string, expected: string) => {
])('given %o', async (input: string, expected: string) => {
expect(Build.resolveAttestationAttrs(input)).toEqual(expected);
});
});
@@ -351,7 +438,7 @@ describe('hasGitAuthTokenSecret', () => {
[['A_SECRET=abcdef0123456789'], undefined, false],
[['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789'], undefined, true],
[['GIT_AUTH_TOKEN.github.com=abcdefghijklmno=0123456789'], 'github.com', true],
])('given %p secret', async (kvp: Array<string>, domain: string | undefined, expected: boolean) => {
])('given %o secret', async (kvp: Array<string>, domain: string | undefined, expected: boolean) => {
expect(Build.hasGitAuthTokenSecret(kvp, domain)).toBe(expected);
});
});

View File

@@ -548,7 +548,7 @@ baz = qux
]
}
],
])('given %p', async (inspectFile, expected) => {
])('given %o', async (inspectFile, expected) => {
expect(await Builder.parseInspect(fs.readFileSync(path.join(fixturesDir, inspectFile)).toString())).toEqual(expected);
});
});

View File

@@ -145,7 +145,7 @@ describe('parseVersion', () => {
['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'],
['github.com/docker/buildx f117971 f11797113e5a9b86bd976329c5dbb8a8bfdfadfa', 'f117971']
])('given %p', async (stdout, expected) => {
])('given %o', async (stdout, expected) => {
expect(Buildx.parseVersion(stdout)).toEqual(expected);
});
});
@@ -155,7 +155,7 @@ describe('versionSatisfies', () => {
['0.4.1', '>=0.3.2', true],
['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false],
['f117971', '>0.6.0', true]
])('given %p', async (version, range, expected) => {
])('given %o', async (version, range, expected) => {
const buildx = new Buildx();
expect(await buildx.versionSatisfies(range, version)).toBe(expected);
});
@@ -236,7 +236,7 @@ describe('resolveCertsDriverOpts', () => {
],
[]
],
])('%p. given %p endpoint, %p driver', async (id: number, endpoint: string, driver: string, cert: Cert, expectedFiles: Array<string>, expectedOpts: Array<string>) => {
])('%o. given %o endpoint, %o driver', async (id: number, endpoint: string, driver: string, cert: Cert, expectedFiles: Array<string>, expectedOpts: Array<string>) => {
fs.mkdirSync(Buildx.certsDir, {recursive: true});
expect(Buildx.resolveCertsDriverOpts(driver, endpoint, cert)).toEqual(expectedOpts);
for (const k in expectedFiles) {
@@ -298,7 +298,7 @@ describe('localState', () => {
DockerfilePath: '-'
} as LocalState,
]
])('given %p', async (ref: string, expected: LocalState) => {
])('given %o', async (ref: string, expected: LocalState) => {
const localState = Buildx.localState(ref, path.join(fixturesDir, 'buildx-refs'));
expect(localState).toEqual(expected);
});

View File

@@ -187,40 +187,4 @@ maybe('export', () => {
expect(fs.existsSync(exportRes?.dockerbuildFilename)).toBe(true);
expect(exportRes?.summaries).toBeDefined();
});
it('export using container', 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);
expect(buildRef).toBeDefined();
const history = new History({buildx: buildx});
const exportRes = await history.export({
refs: [buildRef ?? ''],
useContainer: true
});
expect(exportRes).toBeDefined();
expect(exportRes?.dockerbuildFilename).toBeDefined();
expect(exportRes?.dockerbuildSize).toBeDefined();
expect(fs.existsSync(exportRes?.dockerbuildFilename)).toBe(true);
expect(exportRes?.summaries).toBeDefined();
});
});

View File

@@ -30,12 +30,12 @@ const maybe = !process.env.GITHUB_ACTIONS || (process.env.GITHUB_ACTIONS === 'tr
maybe('inspectImage', () => {
it('inspect single platform', async () => {
const image = await new ImageTools().inspectImage('moby/buildkit:latest@sha256:5769c54b98840147b74128f38fb0b0a049e24b11a75bd81664131edd2854593f');
const image = await new ImageTools().inspectImage({name: 'moby/buildkit:latest@sha256:5769c54b98840147b74128f38fb0b0a049e24b11a75bd81664131edd2854593f'});
const expectedImage = <Image>JSON.parse(fs.readFileSync(path.join(fixturesDir, 'imagetools-01.json'), {encoding: 'utf-8'}).trim());
expect(image).toEqual(expectedImage);
});
it('inspect multi platform', async () => {
const image = await new ImageTools().inspectImage('moby/buildkit:latest@sha256:86c0ad9d1137c186e9d455912167df20e530bdf7f7c19de802e892bb8ca16552');
const image = await new ImageTools().inspectImage({name: 'moby/buildkit:latest@sha256:86c0ad9d1137c186e9d455912167df20e530bdf7f7c19de802e892bb8ca16552'});
const expectedImage = <Record<string, Image>>JSON.parse(fs.readFileSync(path.join(fixturesDir, 'imagetools-02.json'), {encoding: 'utf-8'}).trim());
expect(image).toEqual(expectedImage);
});
@@ -43,12 +43,12 @@ maybe('inspectImage', () => {
maybe('inspectManifest', () => {
it('inspect descriptor', async () => {
const manifest = await new ImageTools().inspectManifest('moby/buildkit:latest@sha256:dccc69dd895968c4f21aa9e43e715f25f0cedfce4b17f1014c88c307928e22fc');
const manifest = await new ImageTools().inspectManifest({name: '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 manifest = await new ImageTools().inspectManifest({name: '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);
});
@@ -56,17 +56,17 @@ maybe('inspectManifest', () => {
maybe('attestationDescriptors', () => {
it('returns buildkit attestations descriptors', async () => {
const attestations = await new ImageTools().attestationDescriptors('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6');
const attestations = await new ImageTools().attestationDescriptors({name: '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 attestations = await new ImageTools().attestationDescriptors({name: 'moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', platform: {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 attestations = await new ImageTools().attestationDescriptors({name: 'moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', platform: {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);
});
@@ -74,7 +74,7 @@ maybe('attestationDescriptors', () => {
maybe('attestationDigests', () => {
it('returns buildkit attestations digests', async () => {
const digests = await new ImageTools().attestationDigests('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6');
const digests = await new ImageTools().attestationDigests({name: 'moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6'});
// prettier-ignore
expect(digests).toEqual([
'sha256:2ba4ad6eae1efcafee73a971953093c7c32b6938f2f9fd4998c8bf4d0fbe76f2',
@@ -86,11 +86,22 @@ maybe('attestationDigests', () => {
]);
});
it('returns buildkit attestations digests for linux/amd64', async () => {
const digests = await new ImageTools().attestationDigests('moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', {os: 'linux', architecture: 'amd64'});
const digests = await new ImageTools().attestationDigests({name: 'moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', platform: {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'});
const digests = await new ImageTools().attestationDigests({name: 'moby/buildkit:latest@sha256:79cc6476ab1a3371c9afd8b44e7c55610057c43e18d9b39b68e2b0c2475cc1b6', platform: {os: 'linux', architecture: 'arm', variant: 'v7'}});
expect(digests).toEqual(['sha256:0709528fae1747ce17638ad2978ee7936b38a294136eaadaf692e415f64b1e03']);
});
});
maybe('create', () => {
it('skips create command execution when skipExec is set', async () => {
const result = await new ImageTools().create({
sources: ['sha256:0709528fae1747ce17638ad2978ee7936b38a294136eaadaf692e415f64b1e03'],
tags: ['docker.io/user/app', 'docker.io/user/app2'],
skipExec: true
});
expect(result).toBeUndefined();
});
});

View File

@@ -0,0 +1,301 @@
/**
* Copyright 2026 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 {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
import fs from 'fs';
import os from 'os';
import path from 'path';
import * as rimraf from 'rimraf';
import {Buildx} from '../../src/buildx/buildx.js';
import {ImageTools} from '../../src/buildx/imagetools.js';
import {Context} from '../../src/context.js';
import {Exec} from '../../src/exec.js';
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'buildx-imagetools-'));
const metadataFile = path.join(tmpDir, 'imagetools-metadata.json');
vi.spyOn(Context, 'tmpDir').mockImplementation((): string => {
fs.mkdirSync(tmpDir, {recursive: true});
return tmpDir;
});
vi.spyOn(Context, 'tmpName').mockImplementation((): string => {
return metadataFile;
});
afterEach(() => {
vi.useRealTimers();
vi.clearAllMocks();
rimraf.sync(tmpDir);
});
beforeEach(() => {
vi.useRealTimers();
fs.mkdirSync(tmpDir, {recursive: true});
});
describe('inspectManifest', () => {
it('retries transient manifest unknown errors when requested', async () => {
vi.useFakeTimers();
const getCommand = vi.fn().mockResolvedValue({
command: 'docker',
args: ['buildx', 'imagetools', 'inspect']
});
const buildx = {getCommand} as unknown as Buildx;
const execSpy = vi
.spyOn(Exec, 'getExecOutput')
.mockResolvedValueOnce({
exitCode: 1,
stdout: '',
stderr: 'ERROR: MANIFEST_UNKNOWN: manifest unknown'
})
.mockResolvedValueOnce({
exitCode: 0,
stdout: JSON.stringify({
schemaVersion: 2,
mediaType: 'application/vnd.oci.image.index.v1+json',
manifests: []
}),
stderr: ''
});
const inspectPromise = new ImageTools({buildx}).inspectManifest({
name: 'docker.io/library/alpine:latest',
retryOnManifestUnknown: true,
retryLimit: 2
});
await vi.runAllTimersAsync();
expect(await inspectPromise).toEqual({
schemaVersion: 2,
mediaType: 'application/vnd.oci.image.index.v1+json',
manifests: []
});
expect(getCommand).toHaveBeenCalledWith(['imagetools', 'inspect', 'docker.io/library/alpine:latest', '--format', '{{json .Manifest}}']);
expect(execSpy).toHaveBeenCalledTimes(2);
});
it('does not retry non-manifest errors', async () => {
const getCommand = vi.fn().mockResolvedValue({
command: 'docker',
args: ['buildx', 'imagetools', 'inspect']
});
const buildx = {getCommand} as unknown as Buildx;
const execSpy = vi.spyOn(Exec, 'getExecOutput').mockResolvedValue({
exitCode: 1,
stdout: '',
stderr: 'ERROR: unauthorized'
});
const result = await new ImageTools({buildx})
.inspectManifest({
name: 'docker.io/library/alpine:latest',
retryOnManifestUnknown: true
})
.then(
value => ({value, error: undefined}),
error => ({value: undefined, error: error as Error})
);
expect(result.value).toBeUndefined();
expect(result.error).toBeInstanceOf(Error);
expect(result.error?.message).toContain('ERROR: unauthorized');
expect(execSpy).toHaveBeenCalledTimes(1);
});
});
describe('inspectImage', () => {
it('retries transient manifest unknown errors when requested', async () => {
vi.useFakeTimers();
const getCommand = vi.fn().mockResolvedValue({
command: 'docker',
args: ['buildx', 'imagetools', 'inspect']
});
const buildx = {getCommand} as unknown as Buildx;
const execSpy = vi
.spyOn(Exec, 'getExecOutput')
.mockResolvedValueOnce({
exitCode: 1,
stdout: '',
stderr: 'ERROR: MANIFEST_UNKNOWN: manifest unknown'
})
.mockResolvedValueOnce({
exitCode: 0,
stdout: JSON.stringify({
config: {
digest: 'sha256:test'
}
}),
stderr: ''
});
const inspectPromise = new ImageTools({buildx}).inspectImage({
name: 'docker.io/library/alpine:latest',
retryOnManifestUnknown: true,
retryLimit: 2
});
await vi.runAllTimersAsync();
expect(await inspectPromise).toEqual({
config: {
digest: 'sha256:test'
}
});
expect(getCommand).toHaveBeenCalledWith(['imagetools', 'inspect', 'docker.io/library/alpine:latest', '--format', '{{json .Image}}']);
expect(execSpy).toHaveBeenCalledTimes(2);
});
});
describe('create', () => {
it('parses metadata and supports cwd sources', async () => {
const getCommand = vi.fn().mockResolvedValue({
command: 'docker',
args: ['buildx', 'imagetools', 'create']
});
const buildx = {getCommand} as unknown as Buildx;
fs.writeFileSync(
metadataFile,
JSON.stringify({
'containerimage.descriptor': {
mediaType: 'application/vnd.oci.image.index.v1+json',
digest: 'sha256:19ffeab6f8bc9293ac2c3fdf94ebe28396254c993aea0b5a542cfb02e0883fa3',
size: 4654
},
'image.name': 'docker.io/user/app,docker.io/user/app2'
})
);
const execSpy = vi.spyOn(Exec, 'getExecOutput').mockResolvedValue({
exitCode: 0,
stdout: '',
stderr: ''
});
const result = await new ImageTools({buildx}).create({
sources: ['cwd://descriptor.json', 'docker.io/library/alpine:latest'],
tags: ['docker.io/user/app:latest'],
silent: true
});
expect(getCommand).toHaveBeenCalledWith(['imagetools', 'create', '--tag', 'docker.io/user/app:latest', '--metadata-file', metadataFile, '--file', 'descriptor.json', 'docker.io/library/alpine:latest']);
expect(execSpy).toHaveBeenCalledWith('docker', ['buildx', 'imagetools', 'create'], {
ignoreReturnCode: true,
silent: true
});
expect(result).toEqual({
digest: 'sha256:19ffeab6f8bc9293ac2c3fdf94ebe28396254c993aea0b5a542cfb02e0883fa3',
descriptor: {
mediaType: 'application/vnd.oci.image.index.v1+json',
digest: 'sha256:19ffeab6f8bc9293ac2c3fdf94ebe28396254c993aea0b5a542cfb02e0883fa3',
size: 4654
},
imageNames: ['docker.io/user/app', 'docker.io/user/app2']
});
});
it('does not parse metadata in dry-run mode', async () => {
const getCommand = vi.fn().mockResolvedValue({
command: 'docker',
args: ['buildx', 'imagetools', 'create']
});
const buildx = {getCommand} as unknown as Buildx;
const execSpy = vi.spyOn(Exec, 'getExecOutput').mockResolvedValue({
exitCode: 0,
stdout: '',
stderr: ''
});
const result = await new ImageTools({buildx}).create({
sources: ['docker.io/library/alpine:latest'],
dryRun: true,
silent: true
});
expect(getCommand).toHaveBeenCalledWith(['imagetools', 'create', '--dry-run', 'docker.io/library/alpine:latest']);
expect(execSpy).toHaveBeenCalledWith('docker', ['buildx', 'imagetools', 'create'], {
ignoreReturnCode: true,
silent: true
});
expect(result).toBeUndefined();
});
it('passes annotations to imagetools create', async () => {
const getCommand = vi.fn().mockResolvedValue({
command: 'docker',
args: ['buildx', 'imagetools', 'create']
});
const buildx = {getCommand} as unknown as Buildx;
const execSpy = vi.spyOn(Exec, 'getExecOutput').mockResolvedValue({
exitCode: 0,
stdout: '',
stderr: ''
});
const result = await new ImageTools({buildx}).create({
sources: ['docker.io/library/alpine:latest'],
annotations: ['index:org.opencontainers.image.title=Alpine', 'manifest-descriptor:org.opencontainers.image.description=Base image'],
silent: true
});
expect(getCommand).toHaveBeenCalledWith([
'imagetools',
'create',
'--annotation',
'index:org.opencontainers.image.title=Alpine',
'--annotation',
'manifest-descriptor:org.opencontainers.image.description=Base image',
'--metadata-file',
metadataFile,
'docker.io/library/alpine:latest'
]);
expect(execSpy).toHaveBeenCalledWith('docker', ['buildx', 'imagetools', 'create'], {
ignoreReturnCode: true,
silent: true
});
expect(result).toBeUndefined();
});
it('skips command execution when skipExec is enabled', async () => {
const getCommand = vi.fn().mockResolvedValue({
command: 'docker',
args: ['buildx', 'imagetools', 'create']
});
const buildx = {getCommand} as unknown as Buildx;
const execSpy = vi.spyOn(Exec, 'getExecOutput').mockResolvedValue({
exitCode: 0,
stdout: '',
stderr: ''
});
const result = await new ImageTools({buildx}).create({
sources: ['docker.io/library/alpine:latest'],
skipExec: true
});
expect(getCommand).toHaveBeenCalledWith(['imagetools', 'create', '--metadata-file', metadataFile, 'docker.io/library/alpine:latest']);
expect(execSpy).not.toHaveBeenCalled();
expect(result).toBeUndefined();
});
});

View File

@@ -37,7 +37,7 @@ describe('download', () => {
['v0.10.5', true],
['latest', true]
])(
'acquires %p of buildx (standalone: %p)', async (version, standalone) => {
'acquires %o of buildx (standalone: %o)', async (version, standalone) => {
const install = new Install({standalone: standalone});
const toolPath = await install.download({version});
expect(fs.existsSync(toolPath)).toBe(true);
@@ -56,7 +56,7 @@ describe('download', () => {
['v0.9.0'],
['v0.10.5'],
])(
'acquires %p of buildx with cache', async (version) => {
'acquires %o of buildx with cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download({version});
expect(fs.existsSync(toolPath)).toBe(true);
@@ -67,7 +67,7 @@ describe('download', () => {
['v0.11.2'],
['v0.12.0'],
])(
'acquires %p of buildx without cache', async (version) => {
'acquires %o of buildx without cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download({version: version, ghaNoCache: true});
expect(fs.existsSync(toolPath)).toBe(true);

View File

@@ -101,7 +101,7 @@ describe('parseVersion', () => {
// prettier-ignore
test.each([
['Docker Compose version v2.31.0', '2.31.0'],
])('given %p', async (stdout, expected) => {
])('given %o', async (stdout, expected) => {
expect(Compose.parseVersion(stdout)).toEqual(expected);
});
});

View File

@@ -37,7 +37,7 @@ describe('download', () => {
['v2.32.4', true],
['latest', true]
])(
'acquires %p of compose (standalone: %p)', async (version, standalone) => {
'acquires %o of compose (standalone: %o)', async (version, standalone) => {
const install = new Install({standalone: standalone});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
@@ -56,7 +56,7 @@ describe('download', () => {
['v2.31.0'],
['v2.32.4'],
])(
'acquires %p of compose with cache', async (version) => {
'acquires %o of compose with cache', async (version) => {
const install = new Install({standalone: false});
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
@@ -67,7 +67,7 @@ describe('download', () => {
['v2.27.1'],
['v2.28.0'],
])(
'acquires %p of compose without cache', async (version) => {
'acquires %o 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);

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
import {describe, expect, vi, it, afterEach, beforeEach, test} from 'vitest';
import {describe, expect, it, afterEach} from 'vitest';
import fs from 'fs';
import os from 'os';
import path from 'path';
@@ -23,57 +23,35 @@ import * as rimraf from 'rimraf';
import {Context} from '../src/context.js';
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'context-'));
const tmpName = path.join(tmpDir, '.tmpname-vi');
vi.spyOn(Context, 'tmpDir').mockImplementation((): string => {
fs.mkdirSync(tmpDir, {recursive: true});
return tmpDir;
});
vi.spyOn(Context, 'tmpName').mockImplementation((): string => {
return tmpName;
});
afterEach(() => {
rimraf.sync(tmpDir);
fs.mkdirSync(tmpDir, {recursive: true});
});
describe('gitRef', () => {
it('returns refs/heads/master', async () => {
expect(Context.gitRef()).toEqual('refs/heads/master');
describe('tmpDir', () => {
it('returns an existing directory and keeps it stable', () => {
const dir = Context.tmpDir();
expect(fs.existsSync(dir)).toBe(true);
expect(fs.statSync(dir).isDirectory()).toBe(true);
expect(Context.tmpDir()).toEqual(dir);
});
});
describe('parseGitRef', () => {
const originalEnv = process.env;
beforeEach(() => {
vi.resetModules();
process.env = {
...originalEnv,
DOCKER_GIT_CONTEXT_PR_HEAD_REF: ''
};
describe('tmpName', () => {
it('returns a path for the provided tmpdir and template', () => {
const name = Context.tmpName({
tmpdir: tmpDir,
template: '.tmpname-XXXXXX'
});
expect(path.dirname(name)).toEqual(tmpDir);
expect(path.basename(name)).toMatch(/^\.tmpname-/);
expect(fs.existsSync(name)).toBe(false);
});
afterEach(() => {
process.env = originalEnv;
});
// prettier-ignore
test.each([
['refs/heads/master', '860c1904a1ce19322e91ac35af1ab07466440c37', false, '860c1904a1ce19322e91ac35af1ab07466440c37'],
['master', '860c1904a1ce19322e91ac35af1ab07466440c37', false, '860c1904a1ce19322e91ac35af1ab07466440c37'],
['refs/pull/15/merge', '860c1904a1ce19322e91ac35af1ab07466440c37', false, 'refs/pull/15/merge'],
['refs/heads/master', '', false, 'refs/heads/master'],
['master', '', false, 'master'],
['refs/tags/v1.0.0', '', false, 'refs/tags/v1.0.0'],
['refs/pull/15/merge', '', false, 'refs/pull/15/merge'],
['refs/pull/15/merge', '', true, 'refs/pull/15/head'],
])('given %p and %p, should return %p', async (ref: string, sha: string, prHeadRef: boolean, expected: string) => {
process.env.DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF = prHeadRef ? 'true' : '';
expect(Context.parseGitRef(ref, sha)).toEqual(expected);
});
});
describe('gitContext', () => {
it('returns refs/heads/master', async () => {
expect(Context.gitContext()).toEqual('https://github.com/docker/actions-toolkit.git#refs/heads/master');
it('returns different paths on consecutive calls', () => {
const first = Context.tmpName({tmpdir: tmpDir, template: '.tmpname-XXXXXX'});
const second = Context.tmpName({tmpdir: tmpDir, template: '.tmpname-XXXXXX'});
expect(first).not.toEqual(second);
});
});

View File

@@ -59,7 +59,7 @@ describe('versionSatisfies', () => {
['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) => {
])('given %o', async (version, range, expected) => {
const cosign = new Cosign();
expect(await cosign.versionSatisfies(range, version)).toBe(expected);
});
@@ -71,7 +71,7 @@ describe('parseCommandOutput', () => {
[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) => {
])('parsing %o', async (fixturePath: string) => {
const signResult = Cosign.parseCommandOutput(fs.readFileSync(fixturePath, 'utf-8'));
expect(signResult).toBeDefined();
expect(signResult.bundle).toBeDefined();
@@ -80,7 +80,7 @@ describe('parseCommandOutput', () => {
// prettier-ignore
test.each([
[path.join(fixturesDir, 'cosign', 'verify-output-err1.txt')],
])('parsing %p', async (fixturePath: string) => {
])('parsing %o', async (fixturePath: string) => {
const signResult = Cosign.parseCommandOutput(fs.readFileSync(fixturePath, 'utf-8'));
expect(signResult).toBeDefined();
expect(signResult.bundle).toBeUndefined();

View File

@@ -37,7 +37,7 @@ describe('download', () => {
['v3.0.1'],
['latest']
])(
'acquires %p of cosign', async (version) => {
'acquires %o of cosign', async (version) => {
const install = new Install();
const toolPath = await install.download({version});
expect(fs.existsSync(toolPath)).toBe(true);
@@ -51,7 +51,7 @@ describe('download', () => {
['v2.6.1'],
['v3.0.1'],
])(
'acquires %p of cosign with cache', async (version) => {
'acquires %o of cosign with cache', async (version) => {
const install = new Install();
const toolPath = await install.download({version});
expect(fs.existsSync(toolPath)).toBe(true);
@@ -62,7 +62,7 @@ describe('download', () => {
['v2.5.3'],
['v2.6.0'],
])(
'acquires %p of cosign without cache', async (version) => {
'acquires %o of cosign without cache', async (version) => {
const install = new Install();
const toolPath = await install.download({
version: version,

View File

@@ -60,7 +60,7 @@ describe('download', () => {
[image('27.3.1'), 'linux'],
[image('27.3.1'), 'win32'],
])(
'acquires %p of docker (%s)', async (source, platformOS) => {
'acquires %o of docker (%s)', async (source, platformOS) => {
mockPlatform(platformOS as NodeJS.Platform);
mockArch('x64');
const install = new Install({

View File

@@ -63,7 +63,7 @@ describe('releases', () => {
['.github/docker-releases.json'],
['.github/regclient-releases.json'],
['.github/undock-releases.json'],
])('returns %p', async (path: string) => {
])('returns %o', async (path: string) => {
const github = new GitHub();
const releases = await github.releases('App', {
owner: 'docker',

View File

@@ -56,7 +56,7 @@ describe('loadArchive', () => {
// prettier-ignore
test.each(fs.readdirSync(path.join(fixturesDir, 'oci-archive')).filter(file => {
return fs.statSync(path.join(path.join(fixturesDir, 'oci-archive'), file)).isFile();
}).map(filename => [filename]))('extracting %p', async (filename) => {
}).map(filename => [filename]))('extracting %o', async (filename) => {
const res = await OCI.loadArchive({
file: path.join(fixturesDir, 'oci-archive', filename)
});

View File

@@ -36,7 +36,7 @@ describe('download', () => {
['v0.8.2'],
['latest']
])(
'acquires %p of regclient', async (version) => {
'acquires %o of regclient', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
@@ -49,7 +49,7 @@ describe('download', () => {
// following versions are already cached to htc from previous test cases
['v0.8.2'],
])(
'acquires %p of regclient with cache', async (version) => {
'acquires %o of regclient with cache', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
@@ -59,7 +59,7 @@ describe('download', () => {
test.each([
['v0.8.1'],
])(
'acquires %p of regclient without cache', async (version) => {
'acquires %o of regclient without cache', async (version) => {
const install = new Install();
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);

View File

@@ -27,7 +27,7 @@ describe('manifestGet', () => {
test.each([
['moby/moby-bin:28.1.0-rc.2'],
['crazymax/diun:4.17.0'],
])('given %p', async image => {
])('given %o', async image => {
const regctl = new Regctl();
const manifest = await regctl.manifestGet({
image: image,
@@ -45,7 +45,7 @@ describe('blobGet', () => {
test.each([
['moby/moby-bin', 'sha256:234fccbd13fde0ba978a19f728cbdc67e29bc76247ac560822bb6ae5236c0bf0'],
['crazymax/diun', 'sha256:1e4881f66e0ec0f1710b837002107050bbbc0a231d8a42d7f422b56a139900bb'],
])('given %p', async (repo, digest) => {
])('given %o', async (repo, digest) => {
const regctl = new Regctl();
const blob = await regctl.blobGet({
repository: repo,
@@ -60,7 +60,7 @@ describe('image config', () => {
test.each([
['moby/moby-bin:28.1.0-rc.2'],
['crazymax/diun:4.17.0'],
])('given %p', async image => {
])('given %o', async image => {
const regctl = new Regctl();
const manifest = await regctl.manifestGet({
image: image,
@@ -115,7 +115,7 @@ describe('versionSatisfies', () => {
['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) => {
])('given %o', async (version, range, expected) => {
const regctl = new Regctl();
expect(await regctl.versionSatisfies(range, version)).toBe(expected);
});

View File

@@ -37,7 +37,7 @@ describe('download', () => {
['v0.7.0'],
['latest']
])(
'acquires %p of undock', async (version) => {
'acquires %o of undock', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
@@ -51,7 +51,7 @@ describe('download', () => {
['v0.4.0'],
['v0.7.0'],
])(
'acquires %p of undock with cache', async (version) => {
'acquires %o of undock with cache', async (version) => {
const install = new Install();
const toolPath = await install.download(version);
expect(fs.existsSync(toolPath)).toBe(true);
@@ -62,7 +62,7 @@ describe('download', () => {
['v0.5.0'],
['v0.6.0'],
])(
'acquires %p of undock without cache', async (version) => {
'acquires %o of undock without cache', async (version) => {
const install = new Install();
const toolPath = await install.download(version, true);
expect(fs.existsSync(toolPath)).toBe(true);

View File

@@ -76,7 +76,7 @@ describe('versionSatisfies', () => {
['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) => {
])('given %o', async (version, range, expected) => {
const undock = new Undock();
expect(await undock.versionSatisfies(range, version)).toBe(expected);
});

View File

@@ -87,6 +87,12 @@ describe('getInputList', () => {
expect(res).toEqual(['foo=bar', 'bar=qux']);
});
it('multiline with comment and no infix comment', async () => {
setInput('labels', '# ignore this\nfoo=bar\nbar=qux#baz');
const res = Util.getInputList('labels', {comment: '#', commentNoInfix: true});
expect(res).toEqual(['foo=bar', 'bar=qux#baz']);
});
it('different new lines and ignoring comma correctly', async () => {
setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir');
const res = Util.getInputList('cache-from', {ignoreComma: true});
@@ -247,7 +253,7 @@ describe('isValidURL', () => {
['git://github.com/user/repo.git', false],
['github.com/moby/buildkit.git#main', false],
['v0.4.1', false]
])('given %p', async (url, expected) => {
])('given %o', async (url, expected) => {
expect(Util.isValidURL(url)).toEqual(expected);
});
});
@@ -260,7 +266,7 @@ describe('isValidRef', () => {
['git://github.com/user/repo.git', true],
['github.com/moby/buildkit.git#main', true],
['v0.4.1', false]
])('given %p', async (url, expected) => {
])('given %o', async (url, expected) => {
expect(Util.isValidRef(url)).toEqual(expected);
});
});
@@ -278,7 +284,7 @@ describe('trimPrefix', () => {
['abcdabc', 'abc', 'dabc'],
['abcabc', 'abc', 'abc'],
['abcdabc', 'd', 'abcdabc']
])('given %p', async (str, prefix, expected) => {
])('given %o', async (str, prefix, expected) => {
expect(Util.trimPrefix(str, prefix)).toEqual(expected);
});
});
@@ -295,7 +301,7 @@ describe('trimSuffix', () => {
['abcdabc', 'abc', 'abcd'],
['abcabc', 'abc', 'abc'],
['abcdabc', 'd', 'abcdabc']
])('given %p', async (str, suffix, expected) => {
])('given %o', async (str, suffix, expected) => {
expect(Util.trimSuffix(str, suffix)).toEqual(expected);
});
});
@@ -309,6 +315,7 @@ describe('hash', () => {
// https://github.com/golang/go/blob/f6b93a4c358b28b350dd8fe1780c1f78e520c09c/src/strconv/atob_test.go#L36-L58
describe('parseBool', () => {
[
{input: undefined, expected: false, throwsError: false},
{input: '', expected: false, throwsError: true},
{input: 'asdf', expected: false, throwsError: true},
{input: '0', expected: false, throwsError: false},
@@ -336,6 +343,13 @@ describe('parseBool', () => {
});
});
describe('parseBoolOrDefault', () => {
it('returns default value when input is invalid', () => {
expect(Util.parseBoolOrDefault('asdf')).toBe(false);
expect(Util.parseBoolOrDefault('asdf', true)).toBe(true);
});
});
describe('formatFileSize', () => {
test('should return "0 Bytes" when given 0 bytes', () => {
expect(Util.formatFileSize(0)).toBe('0 Bytes');

View File

@@ -14,9 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARG NODE_VERSION=20
ARG NODE_VERSION=24
ARG DOCKER_VERSION=29.2
ARG BUILDX_VERSION=0.32.0-rc1
ARG BUILDX_VERSION=0.32.1
ARG COMPOSE_VERSION=2.39.1
ARG UNDOCK_VERSION=0.10.0
ARG REGCTL_VERSION=v0.8.2

View File

@@ -42,7 +42,7 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"@actions/artifact": "^6.2.0",
"@actions/artifact": "^6.2.1",
"@actions/cache": "^6.0.0",
"@actions/core": "^3.0.0",
"@actions/exec": "^3.0.0",
@@ -55,7 +55,7 @@
"@sigstore/tuf": "^4.0.1",
"@sigstore/verify": "^3.1.0",
"async-retry": "^1.3.3",
"csv-parse": "^6.1.0",
"csv-parse": "^6.2.0",
"gunzip-maybe": "^1.4.2",
"handlebars": "^4.7.8",
"he": "^1.2.0",
@@ -70,7 +70,7 @@
"@types/gunzip-maybe": "^1.4.3",
"@types/he": "^1.2.3",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.19.35",
"@types/node": "^24.11.0",
"@types/semver": "^7.7.1",
"@types/tar-stream": "^3.1.4",
"@types/tmp": "^0.2.6",

View File

@@ -44,6 +44,7 @@ export interface BakeCmdOpts {
sbom?: string;
source?: string;
targets?: Array<string>;
vars?: Array<string>;
githubToken?: string; // for auth with remote definitions on private repos
}
@@ -138,6 +139,11 @@ export class Bake {
args.push('--set', override);
}
}
if (cmdOpts.vars) {
for (const v of cmdOpts.vars) {
args.push('--var', v);
}
}
if (cmdOpts.allow) {
for (const allow of cmdOpts.allow) {
args.push('--allow', allow);

View File

@@ -17,6 +17,7 @@
import fs from 'fs';
import path from 'path';
import * as core from '@actions/core';
import * as github from '@actions/github';
import {parse} from 'csv-parse/sync';
import {Buildx} from './buildx.js';
@@ -24,7 +25,7 @@ import {Context} from '../context.js';
import {GitHub} from '../github/github.js';
import {Util} from '../util.js';
import {BuildMetadata} from '../types/buildx/build.js';
import {BuildMetadata, GitContextFormat} from '../types/buildx/build.js';
import {VertexWarning} from '../types/buildkit/client.js';
import {ProvenancePredicate} from '../types/intoto/slsa_provenance/v0.2/provenance.js';
@@ -37,6 +38,15 @@ export interface ResolveSecretsOpts {
redact?: boolean;
}
export interface GitContextOpts {
ref?: string;
checksum?: string;
subdir?: string;
keepGitDir?: boolean;
submodules?: boolean;
format?: GitContextFormat;
}
export class Build {
private readonly buildx: Buildx;
private readonly iidFilename: string;
@@ -48,6 +58,47 @@ export class Build {
this.metadataFilename = `build-metadata-${Util.generateRandomString()}.json`;
}
public async gitContext(opts?: GitContextOpts): Promise<string> {
const setPullRequestHeadRef = Util.parseBoolOrDefault(process.env.DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF);
const gitChecksum = opts?.checksum || github.context.sha;
let ref = opts?.ref || github.context.ref;
if (!ref.startsWith('refs/')) {
ref = `refs/heads/${ref}`;
} else if (ref.startsWith(`refs/pull/`) && setPullRequestHeadRef) {
ref = ref.replace(/\/merge$/g, '/head');
}
const baseURL = `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}.git`;
let format = opts?.format;
if (!format) {
const sendGitQueryAsInput = Util.parseBoolOrDefault(process.env.BUILDX_SEND_GIT_QUERY_AS_INPUT);
if (opts?.keepGitDir || typeof opts?.submodules !== 'undefined') {
format = 'query';
} else if (sendGitQueryAsInput && (await this.buildx.versionSatisfies('>=0.29.0'))) {
format = 'query';
} else {
format = 'fragment';
}
}
if (format === 'query') {
const query = [`ref=${ref}`];
if (gitChecksum) {
query.push(`checksum=${gitChecksum}`);
}
if (opts?.subdir && opts.subdir !== '.') {
query.push(`subdir=${opts.subdir}`);
}
if (typeof opts?.keepGitDir !== 'undefined') {
query.push(`keep-git-dir=${opts.keepGitDir}`);
}
if (typeof opts?.submodules !== 'undefined') {
query.push(`submodules=${opts.submodules}`);
}
return `${baseURL}?${query.join('&')}`;
}
const fragmentRef = gitChecksum && !ref.startsWith(`refs/pull/`) ? gitChecksum : ref;
return `${baseURL}#${fragmentRef}${opts?.subdir && opts.subdir !== '.' ? `:${opts.subdir}` : ''}`;
}
public getImageIDFilePath(): string {
return path.join(Context.tmpDir(), this.iidFilename);
}

View File

@@ -14,16 +14,12 @@
* limitations under the License.
*/
import {ChildProcessByStdio, spawn} from 'child_process';
import fs from 'fs';
import os from 'os';
import path from 'path';
import {Readable, Writable} from 'stream';
import * as core from '@actions/core';
import {Buildx} from './buildx.js';
import {Context} from '../context.js';
import {Docker} from '../docker/docker.js';
import {Exec} from '../exec.js';
import {GitHub} from '../github/github.js';
import {Util} from '../util.js';
@@ -74,6 +70,10 @@ export class History {
}
public async export(opts: ExportOpts): Promise<ExportResponse> {
if (!(await this.buildx.versionSatisfies('>=0.23.0'))) {
throw new Error('Buildx >= 0.23.0 is required to export a build record');
}
let builderName: string = '';
let nodeName: string = '';
const refs: Array<string> = [];
@@ -101,10 +101,6 @@ 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
@@ -162,143 +158,6 @@ export class History {
};
}
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);
const buildxInFifoPath = Context.tmpName({
template: 'buildx-in-XXXXXX.fifo',
tmpdir: Context.tmpDir()
});
await Exec.exec('mkfifo', [buildxInFifoPath]);
const buildxOutFifoPath = Context.tmpName({
template: 'buildx-out-XXXXXX.fifo',
tmpdir: Context.tmpDir()
});
await Exec.exec('mkfifo', [buildxOutFifoPath]);
const buildxDialStdioCmd = await this.buildx.getCommand(['--builder', builderName, 'dial-stdio']);
core.info(`[command]${buildxDialStdioCmd.command} ${buildxDialStdioCmd.args.join(' ')}`);
const buildxDialStdioProc = spawn(buildxDialStdioCmd.command, buildxDialStdioCmd.args, {
stdio: ['pipe', 'pipe', 'inherit'],
detached: true
});
let buildxDialStdioKilled = false;
fs.createReadStream(buildxInFifoPath).pipe(buildxDialStdioProc.stdin);
buildxDialStdioProc.stdout.pipe(fs.createWriteStream(buildxOutFifoPath));
buildxDialStdioProc.on('exit', (code, signal) => {
buildxDialStdioKilled = true;
if (signal) {
core.info(`Process "buildx dial-stdio" was killed with signal ${signal}`);
} else {
core.info(`Process "buildx dial-stdio" exited with code ${code}`);
}
});
const tmpDockerbuildFilename = path.join(outDir, 'rec.dockerbuild');
const summaryFilename = path.join(outDir, 'summary.json');
let dockerRunProc: ChildProcessByStdio<Writable, Readable, null> | undefined;
let dockerRunProcKilled = false;
await new Promise<void>((resolve, reject) => {
const ebargs: Array<string> = ['--ref-state-dir=/buildx-refs', `--node=${builderName}/${nodeName}`];
for (const ref of refs) {
ebargs.push(`--ref=${ref}`);
}
if (typeof process.getuid === 'function') {
ebargs.push(`--uid=${process.getuid()}`);
}
if (typeof process.getgid === 'function') {
ebargs.push(`--gid=${process.getgid()}`);
}
// prettier-ignore
const dockerRunArgs = [
'run', '--rm', '-i',
'-v', `${Buildx.refsDir}:/buildx-refs`,
'-v', `${outDir}:/out`,
image || process.env['DOCKER_BUILD_EXPORT_BUILD_IMAGE'] || 'docker.io/dockereng/export-build:latest',
...ebargs
]
core.info(`[command]docker ${dockerRunArgs.join(' ')}`);
dockerRunProc = spawn('docker', dockerRunArgs, {
stdio: ['pipe', 'pipe', 'inherit'],
env: {
...process.env,
DOCKER_CONTENT_TRUST: 'false'
}
});
fs.createReadStream(buildxOutFifoPath).pipe(dockerRunProc.stdin);
dockerRunProc.stdout.pipe(fs.createWriteStream(buildxInFifoPath));
dockerRunProc.on('close', code => {
if (code === 0) {
if (!fs.existsSync(tmpDockerbuildFilename)) {
reject(new Error(`Failed to export build record: ${tmpDockerbuildFilename} not found`));
} else {
resolve();
}
} else {
reject(new Error(`Process "docker run" closed with code ${code}`));
}
});
dockerRunProc.on('error', err => {
core.error(`Error executing "docker run": ${err}`);
reject(err);
});
dockerRunProc.on('exit', (code, signal) => {
dockerRunProcKilled = true;
if (signal) {
core.info(`Process "docker run" was killed with signal ${signal}`);
} else {
core.info(`Process "docker run" exited with code ${code}`);
}
});
})
.catch(err => {
throw err;
})
.finally(() => {
if (buildxDialStdioProc && !buildxDialStdioKilled) {
core.debug('Force terminating "buildx dial-stdio" process');
buildxDialStdioProc.kill('SIGKILL');
}
if (dockerRunProc && !dockerRunProcKilled) {
core.debug('Force terminating "docker run" process');
dockerRunProc.kill('SIGKILL');
}
});
const dockerbuildPath = path.join(outDir, `${History.exportFilename(refs)}.dockerbuild`);
fs.renameSync(tmpDockerbuildFilename, dockerbuildPath);
const dockerbuildStats = fs.statSync(dockerbuildPath);
core.info(`Parsing ${summaryFilename}`);
fs.statSync(summaryFilename);
const summaries = <Summaries>JSON.parse(fs.readFileSync(summaryFilename, {encoding: 'utf-8'}));
return {
dockerbuildFilename: dockerbuildPath,
dockerbuildSize: dockerbuildStats.size,
builderName: builderName,
nodeName: nodeName,
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) {

View File

@@ -14,12 +14,16 @@
* limitations under the License.
*/
import fs from 'fs';
import * as core from '@actions/core';
import {Buildx} from './buildx.js';
import {Context} from '../context.js';
import {Exec} from '../exec.js';
import {Manifest as ImageToolsManifest} from '../types/buildx/imagetools.js';
import {AttestationInspectOpts, CreateOpts, CreateResponse, CreateResult, InspectOpts, Manifest as ImageToolsManifest} from '../types/buildx/imagetools.js';
import {Image} from '../types/oci/config.js';
import {Descriptor, Platform} from '../types/oci/descriptor.js';
import {Descriptor} from '../types/oci/descriptor.js';
import {Digest} from '../types/oci/digest.js';
export interface ImageToolsOpts {
@@ -41,16 +45,12 @@ export class ImageTools {
return await this.getCommand(['inspect', ...args]);
}
public async inspectImage(name: string): Promise<Record<string, Image> | Image> {
const cmd = await this.getInspectCommand([name, '--format', '{{json .Image}}']);
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);
public async getCreateCommand(args: Array<string>) {
return await this.getCommand(['create', ...args]);
}
public async inspectImage(opts: InspectOpts): Promise<Record<string, Image> | Image> {
return await this.inspect(opts, '{{json .Image}}', parsedOutput => {
if (typeof parsedOutput === 'object' && !Array.isArray(parsedOutput) && parsedOutput !== null) {
if (Object.prototype.hasOwnProperty.call(parsedOutput, 'config')) {
return <Image>parsedOutput;
@@ -62,16 +62,8 @@ export class ImageTools {
});
}
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);
public async inspectManifest(opts: InspectOpts): Promise<ImageToolsManifest | Descriptor> {
return await this.inspect(opts, '{{json .Manifest}}', parsedOutput => {
if (typeof parsedOutput === 'object' && !Array.isArray(parsedOutput) && parsedOutput !== null) {
if (Object.prototype.hasOwnProperty.call(parsedOutput, 'manifests')) {
return <ImageToolsManifest>parsedOutput;
@@ -83,17 +75,18 @@ export class ImageTools {
});
}
public async attestationDescriptors(name: string, platform?: Platform): Promise<Array<Descriptor>> {
const manifest = await this.inspectManifest(name);
public async attestationDescriptors(opts: AttestationInspectOpts): Promise<Array<Descriptor>> {
const manifest = await this.inspectManifest(opts);
if (typeof manifest !== 'object' || manifest === null || !('manifests' in manifest) || !Array.isArray(manifest.manifests)) {
throw new Error(`No descriptor found for ${name}`);
throw new Error(`No descriptor found for ${opts.name}`);
}
const attestations = manifest.manifests.filter(m => m.annotations?.['vnd.docker.reference.type'] === 'attestation-manifest');
if (!platform) {
if (!opts.platform) {
return attestations;
}
const platform = opts.platform;
const manifestByDigest = new Map<string, Descriptor>();
for (const m of manifest.manifests) {
@@ -115,7 +108,126 @@ export class ImageTools {
});
}
public async attestationDigests(name: string, platform?: Platform): Promise<Array<Digest>> {
return (await this.attestationDescriptors(name, platform)).map(attestation => attestation.digest);
public async attestationDigests(opts: AttestationInspectOpts): Promise<Array<Digest>> {
return (await this.attestationDescriptors(opts)).map(attestation => attestation.digest);
}
public async create(opts: CreateOpts): Promise<CreateResult | undefined> {
const args: Array<string> = [];
const metadataFile = Context.tmpName({tmpdir: Context.tmpDir(), template: 'imagetools-metadata-XXXXXX'});
const fileSources: Array<string> = [];
const sources: Array<string> = [];
for (const source of opts.sources) {
if (source.startsWith('cwd://')) {
const fileSource = source.substring('cwd://'.length);
if (fileSource.length > 0) {
fileSources.push(fileSource);
}
continue;
}
sources.push(source);
}
if (opts.tags) {
for (const tag of opts.tags) {
args.push('--tag', tag);
}
}
if (opts.platforms) {
for (const platform of opts.platforms) {
args.push('--platform', platform);
}
}
if (opts.annotations) {
for (const annotation of opts.annotations) {
args.push('--annotation', annotation);
}
}
if (opts.dryRun) {
args.push('--dry-run');
} else {
args.push('--metadata-file', metadataFile);
}
for (const fileSource of fileSources) {
args.push('--file', fileSource);
}
for (const source of sources) {
args.push(source);
}
const cmd = await this.getCreateCommand(args);
if (opts.skipExec) {
core.info(`[command]${cmd.command} ${cmd.args.join(' ')}`);
core.info(`Skipped create command`);
return undefined;
}
return await Exec.getExecOutput(cmd.command, cmd.args, {
ignoreReturnCode: true,
silent: opts.silent
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
if (!opts.dryRun) {
if (!fs.existsSync(metadataFile)) {
return undefined;
}
const dt = fs.readFileSync(metadataFile, {encoding: 'utf-8'}).trim();
if (dt === '' || dt === 'null') {
return undefined;
}
const response = <CreateResponse>JSON.parse(dt);
const descriptor = response['containerimage.descriptor'];
if (!descriptor) {
return undefined;
}
return {
digest: response['containerimage.digest'] || descriptor.digest,
descriptor: descriptor,
imageNames: response['image.name'] ? response['image.name'].split(',').map(name => name.trim()) : []
};
}
});
}
private async inspect<T>(opts: InspectOpts, format: string, parser: (parsedOutput: unknown) => T): Promise<T> {
const cmd = await this.getInspectCommand([opts.name, '--format', format]);
if (!opts.retryOnManifestUnknown) {
return await this.execInspect(cmd.command, cmd.args, parser);
}
const retries = opts.retryLimit ?? 15;
let lastError: Error | undefined;
for (let attempt = 0; attempt < retries; attempt++) {
try {
return await this.execInspect(cmd.command, cmd.args, parser);
} catch (err) {
lastError = err as Error;
if (!ImageTools.isManifestUnknownError(lastError.message) || attempt === retries - 1) {
throw lastError;
}
core.info(`buildx imagetools inspect command failed with MANIFEST_UNKNOWN, retrying attempt ${attempt + 1}/${retries}...\n${lastError.message}`);
await new Promise(res => setTimeout(res, Math.pow(2, attempt) * 100));
}
}
throw lastError ?? new Error(`ImageTools inspect command failed for ${opts.name}`);
}
private async execInspect<T>(command: string, args: Array<string>, parser: (parsedOutput: unknown) => T): Promise<T> {
return await Exec.getExecOutput(command, args, {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
return parser(JSON.parse(res.stdout));
});
}
private static isManifestUnknownError(message: string): boolean {
return /(MANIFEST_UNKNOWN|manifest unknown|not found: not found)/i.test(message);
}
}

View File

@@ -18,9 +18,6 @@ import fs from 'fs';
import os from 'os';
import path from 'path';
import * as tmp from 'tmp';
import * as github from '@actions/github';
import {GitHub} from './github/github.js';
export class Context {
private static readonly _tmpDir = fs.mkdtempSync(path.join(Context.ensureDirExists(process.env.RUNNER_TEMP || os.tmpdir()), 'docker-actions-toolkit-'));
@@ -37,25 +34,4 @@ export class Context {
public static tmpName(options?: tmp.TmpNameOptions): string {
return tmp.tmpNameSync(options);
}
public static gitRef(): string {
return Context.parseGitRef(github.context.ref, github.context.sha);
}
public static parseGitRef(ref: string, sha: string): string {
const setPullRequestHeadRef: boolean = !!(process.env.DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF && process.env.DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF === 'true');
if (sha && ref && !ref.startsWith('refs/')) {
ref = `refs/heads/${ref}`;
}
if (sha && !ref.startsWith(`refs/pull/`)) {
ref = sha;
} else if (ref.startsWith(`refs/pull/`) && setPullRequestHeadRef) {
ref = ref.replace(/\/merge$/g, '/head');
}
return ref;
}
public static gitContext(): string {
return `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}.git#${Context.gitRef()}`;
}
}

View File

@@ -113,7 +113,11 @@ export class Sigstore {
}
for (const imageName of opts.imageNames) {
const attestationDigests = await this.imageTools.attestationDigests(`${imageName}@${opts.imageDigest}`);
const attestationDigests = await this.imageTools.attestationDigests({
name: `${imageName}@${opts.imageDigest}`,
retryOnManifestUnknown: opts.retryOnManifestUnknown,
retryLimit: opts.retryLimit
});
for (const attestationDigest of attestationDigests) {
const attestationRef = `${imageName}@${attestationDigest}`;
await core.group(`Signing attestation manifest ${attestationRef}`, async () => {
@@ -183,7 +187,12 @@ export class Sigstore {
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);
const attestationDigests = await this.imageTools.attestationDigests({
name: image,
platform: opts.platform,
retryOnManifestUnknown: opts.retryOnManifestUnknown,
retryLimit: opts.retryLimit
});
if (attestationDigests.length === 0) {
throw new Error(`No attestation manifests found for ${image}`);
}
@@ -237,7 +246,7 @@ export class Sigstore {
};
}
const retries = 15;
const retries = opts.retryLimit ?? 15;
let lastError: Error | undefined;
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
for (let attempt = 0; attempt < retries; attempt++) {

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
export type GitContextFormat = 'fragment' | 'query';
export type BuildMetadata = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;

View File

@@ -107,7 +107,6 @@ export interface ExportOpts {
refs: Array<string>;
noSummaries?: boolean;
image?: string;
useContainer?: boolean;
}
export interface ExportResponse {

View File

@@ -15,9 +15,19 @@
*/
import {Versioned} from '../oci/versioned.js';
import {Descriptor} from '../oci/descriptor.js';
import {Descriptor, Platform} from '../oci/descriptor.js';
import {Digest} from '../oci/digest.js';
export interface InspectOpts {
name: string;
retryOnManifestUnknown?: boolean;
retryLimit?: number;
}
export interface AttestationInspectOpts extends InspectOpts {
platform?: Platform;
}
// https://github.com/docker/buildx/blob/62857022a08552bee5cad0c3044a9a3b185f0b32/util/imagetools/printers.go#L109-L123
export interface Manifest extends Versioned {
mediaType?: string;
@@ -26,3 +36,26 @@ export interface Manifest extends Versioned {
manifests?: Descriptor[];
annotations?: Record<string, string>;
}
// https://docs.docker.com/reference/cli/docker/buildx/imagetools/create/#options
export interface CreateOpts {
sources: Array<string>;
tags?: Array<string>;
platforms?: Array<string>;
annotations?: Array<string>;
dryRun?: boolean;
silent?: boolean;
skipExec?: boolean;
}
export interface CreateResponse {
'containerimage.digest'?: Digest;
'containerimage.descriptor'?: Descriptor;
'image.name'?: string;
}
export interface CreateResult {
digest: Digest;
descriptor: Descriptor;
imageNames: Array<string>;
}

View File

@@ -40,6 +40,8 @@ export interface SignAttestationManifestsOpts {
imageNames: Array<string>;
imageDigest: string;
noTransparencyLog?: boolean;
retryOnManifestUnknown?: boolean;
retryLimit?: number;
}
export interface SignAttestationManifestsResult extends ParsedBundle {
@@ -51,6 +53,7 @@ export interface VerifySignedManifestsOpts {
platform?: Platform;
noTransparencyLog?: boolean;
retryOnManifestUnknown?: boolean;
retryLimit?: number;
}
export interface VerifySignedManifestsResult {

View File

@@ -24,6 +24,7 @@ import {parse} from 'csv-parse/sync';
export interface ListOpts {
ignoreComma?: boolean;
comment?: string;
commentNoInfix?: boolean;
quote?: string | boolean | Buffer | null;
}
@@ -42,6 +43,7 @@ export class Util {
columns: false,
relaxQuotes: true,
comment: opts?.comment,
comment_no_infix: opts?.commentNoInfix,
relaxColumnCount: true,
skipEmptyLines: true,
quote: opts?.quote
@@ -155,7 +157,10 @@ export class Util {
}
// https://github.com/golang/go/blob/f6b93a4c358b28b350dd8fe1780c1f78e520c09c/src/strconv/atob.go#L7-L18
public static parseBool(str: string): boolean {
public static parseBool(str: string | undefined): boolean {
if (str === undefined) {
return false;
}
switch (str) {
case '1':
case 't':
@@ -176,6 +181,14 @@ export class Util {
}
}
public static parseBoolOrDefault(str: string | undefined, defaultValue = false): boolean {
try {
return this.parseBool(str);
} catch {
return defaultValue;
}
}
public static formatFileSize(bytes: number): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;

View File

@@ -12,9 +12,9 @@ __metadata:
languageName: node
linkType: hard
"@actions/artifact@npm:^6.2.0":
version: 6.2.0
resolution: "@actions/artifact@npm:6.2.0"
"@actions/artifact@npm:^6.2.1":
version: 6.2.1
resolution: "@actions/artifact@npm:6.2.1"
dependencies:
"@actions/core": "npm:^3.0.0"
"@actions/github": "npm:^9.0.0"
@@ -30,7 +30,7 @@ __metadata:
archiver: "npm:^7.0.1"
jwt-decode: "npm:^4.0.0"
unzip-stream: "npm:^0.3.1"
checksum: 10/fa931b1222c0e08bca85d3cb18c2cd5ae912cce3f09ab3acd4ec3486e864337d65177089a14aef124d9696b9dd5309b273a9251e230172c79c2444af2c43443e
checksum: 10/1fad9b079ee2ab07f964b93bf7b4fc594d115199219baed74ac3bf2a8675e0b7ea57252eccbcdaaaa8fc8375742d23585cbd054f3b2d029c091817e0f257ce93
languageName: node
linkType: hard
@@ -370,7 +370,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@docker/actions-toolkit@workspace:."
dependencies:
"@actions/artifact": "npm:^6.2.0"
"@actions/artifact": "npm:^6.2.1"
"@actions/cache": "npm:^6.0.0"
"@actions/core": "npm:^3.0.0"
"@actions/exec": "npm:^3.0.0"
@@ -386,7 +386,7 @@ __metadata:
"@types/gunzip-maybe": "npm:^1.4.3"
"@types/he": "npm:^1.2.3"
"@types/js-yaml": "npm:^4.0.9"
"@types/node": "npm:^20.19.35"
"@types/node": "npm:^24.11.0"
"@types/semver": "npm:^7.7.1"
"@types/tar-stream": "npm:^3.1.4"
"@types/tmp": "npm:^0.2.6"
@@ -395,7 +395,7 @@ __metadata:
"@vitest/coverage-v8": "npm:^4.0.18"
"@vitest/eslint-plugin": "npm:^1.6.9"
async-retry: "npm:^1.3.3"
csv-parse: "npm:^6.1.0"
csv-parse: "npm:^6.2.0"
eslint: "npm:^9.39.3"
eslint-config-prettier: "npm:^10.1.8"
eslint-plugin-prettier: "npm:^5.5.5"
@@ -1368,12 +1368,12 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^20.19.35":
version: 20.19.35
resolution: "@types/node@npm:20.19.35"
"@types/node@npm:^24.11.0":
version: 24.11.0
resolution: "@types/node@npm:24.11.0"
dependencies:
undici-types: "npm:~6.21.0"
checksum: 10/f14fa74f9ae4d1109d8a8e3ec31b6518122b3d31c28fd5725cb3eef8ff64d7cf6f8da9c84c78b512e2968006ec325c82a413cc2062da7b3c3230c882e88babba
undici-types: "npm:~7.16.0"
checksum: 10/d2f4f898c6a0f14980e55c697904fb58681729fc46b4e264d5f64dc391b23da73c9b422cfffbca28c045e6e8eca72dab5f28ed633faa95398ef1528af5398382
languageName: node
linkType: hard
@@ -2178,10 +2178,10 @@ __metadata:
languageName: node
linkType: hard
"csv-parse@npm:^6.1.0":
version: 6.1.0
resolution: "csv-parse@npm:6.1.0"
checksum: 10/607d92611435fdfb7631242644a2582bfb218fad8c6c6d6416db31647c2e63a3110f16c9837de6baaa3edf318212765cfc6e72d672d99690fd7f565d6c93d6f4
"csv-parse@npm:^6.2.0":
version: 6.2.0
resolution: "csv-parse@npm:6.2.0"
checksum: 10/45d0659e11bf2126a2e9b63c2b4206ebaef6ffcaad9b0b98bf4863ad1d94656ad6e00c4cf87c6b0767b5edc1d1dd133d906f7181e689e62fd84b3a9947643eff
languageName: node
linkType: hard
@@ -2655,22 +2655,25 @@ __metadata:
languageName: node
linkType: hard
"fast-xml-builder@npm:^1.0.0":
version: 1.0.0
resolution: "fast-xml-builder@npm:1.0.0"
checksum: 10/06c04d80545e5c9f4d1d6cca00567b5cc09953a92c6328fa48cfb4d7f42630313b8c2bb62e9cb81accee7bb5e1c5312fcae06c3d20dbe52d969a5938233316da
"fast-xml-builder@npm:^1.1.4":
version: 1.1.4
resolution: "fast-xml-builder@npm:1.1.4"
dependencies:
path-expression-matcher: "npm:^1.1.3"
checksum: 10/32937866aaf5a90e69d1f4ee6e15e875248d5b5d2afd70277e9e8323074de4980cef24575a591b8e43c29f405d5f12377b3bad3842dc412b0c5c17a3eaee4b6b
languageName: node
linkType: hard
"fast-xml-parser@npm:^5.0.7":
version: 5.4.1
resolution: "fast-xml-parser@npm:5.4.1"
version: 5.5.6
resolution: "fast-xml-parser@npm:5.5.6"
dependencies:
fast-xml-builder: "npm:^1.0.0"
fast-xml-builder: "npm:^1.1.4"
path-expression-matcher: "npm:^1.1.3"
strnum: "npm:^2.1.2"
bin:
fxparser: src/cli/cli.js
checksum: 10/2b40067c3ad3542ca197d1353bcb0416cd5db20d5c66d74ac176b99af6ff9bd55a6182d36856a2fd477c95b8fc1f07405475f1662a31185480130ba7076c702a
checksum: 10/91a42a0cf99c83b0e721ceef9c189509e96c91c1875901c6ce6017f78ad25284f646a77a541e96ee45a15c2f13b7780d090c906c3ec3f262db03e7feb1e62315
languageName: node
linkType: hard
@@ -3897,6 +3900,13 @@ __metadata:
languageName: node
linkType: hard
"path-expression-matcher@npm:^1.1.3":
version: 1.1.3
resolution: "path-expression-matcher@npm:1.1.3"
checksum: 10/9a607d0bf9807cf86b0a29fb4263f0c00285c13bedafb6ad3efc8bc87ae878da2faf657a9138ac918726cb19f147235a0ca695aec3e4ea1ee04641b6520e6c9e
languageName: node
linkType: hard
"path-is-absolute@npm:^1.0.0":
version: 1.0.1
resolution: "path-is-absolute@npm:1.0.1"
@@ -4781,17 +4791,17 @@ __metadata:
languageName: node
linkType: hard
"undici-types@npm:~6.21.0":
version: 6.21.0
resolution: "undici-types@npm:6.21.0"
checksum: 10/ec8f41aa4359d50f9b59fa61fe3efce3477cc681908c8f84354d8567bb3701fafdddf36ef6bff307024d3feb42c837cf6f670314ba37fc8145e219560e473d14
"undici-types@npm:~7.16.0":
version: 7.16.0
resolution: "undici-types@npm:7.16.0"
checksum: 10/db43439f69c2d94cc29f75cbfe9de86df87061d6b0c577ebe9bb3255f49b22c50162a7d7eb413b0458b6510b8ca299ac7cff38c3a29fbd31af9f504bcf7fbc0d
languageName: node
linkType: hard
"undici@npm:^6.23.0":
version: 6.23.0
resolution: "undici@npm:6.23.0"
checksum: 10/56950995e7b628e62c996430445d17995ca9b70f6f2afe760a63da54205660d968bd08f0741b6f4fb008f40aa35c69cce979cd96ced399585d8c897a76a4f1d1
version: 6.24.1
resolution: "undici@npm:6.24.1"
checksum: 10/4f84e6045520eef9ba8eabb96360b50c759f59905c1703b12187c2dbcc6d1584c5d7ecddeb45b0ed6cac84ca2d132b21bfd8a38f77fa30378b1ac5d2ae390fd9
languageName: node
linkType: hard