Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9505deb078 | ||
|
|
af784a2022 | ||
|
|
afcc1c08a8 | ||
|
|
af0890ba7a | ||
|
|
c4109c3fc2 | ||
|
|
e314ca9bb5 | ||
|
|
29efe4d6a8 | ||
|
|
aacbc67b8d | ||
|
|
d71b84aad5 | ||
|
|
ea05649ce1 | ||
|
|
012ae0603d | ||
|
|
6194cf96c1 | ||
|
|
e804b694a2 | ||
|
|
d2a882884d | ||
|
|
d820ad4123 | ||
|
|
a5d905690f | ||
|
|
6233293ae6 | ||
|
|
9d10fe0e06 | ||
|
|
a8dc8088d4 | ||
|
|
4bc2c14908 | ||
|
|
ad2312d5f1 | ||
|
|
21e2b75b0b |
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -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
|
||||
|
||||
@@ -60,7 +60,11 @@ describe('gitContext', () => {
|
||||
|
||||
type GitContextTestCase = {
|
||||
ref: string;
|
||||
checksum?: string;
|
||||
subdir?: string;
|
||||
attrs?: Record<string, string>;
|
||||
format: GitContextFormat | undefined;
|
||||
|
||||
prHeadRef: boolean;
|
||||
sendGitQueryAsInput: boolean;
|
||||
buildxQuerySupport: boolean;
|
||||
@@ -79,28 +83,57 @@ describe('gitContext', () => {
|
||||
[{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, attrs: {}}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
|
||||
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe'}}, 'https://github.com/docker/actions-toolkit.git#cafebabe'],
|
||||
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {subdir: 'subdir'}}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37:subdir'],
|
||||
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {ref: 'refs/tags/v1.0.0'}}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
|
||||
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'keep-git-dir': '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, attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true'],
|
||||
[{ref: 'refs/heads/master', checksum: undefined, format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe', 'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=cafebabe&keep-git-dir=true'],
|
||||
[{ref: 'refs/heads/master', format: undefined, prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {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, attrs: {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', checksum: undefined, format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {ref: 'refs/tags/v1.0.0', checksum: 'cafebabe', subdir: 'subdir', submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=cafebabe&subdir=subdir&submodules=false'],
|
||||
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, subdir: 'subdir', attrs: {'keep-git-dir': '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, attrs: {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, attrs: {submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&submodules=false'],
|
||||
[{ref: 'refs/heads/master', format: 'query', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'keep-git-dir': 'true', submodules: 'false'}}, 'https://github.com/docker/actions-toolkit.git?ref=refs/heads/master&checksum=860c1904a1ce19322e91ac35af1ab07466440c37&keep-git-dir=true&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', checksum: undefined, format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {checksum: 'cafebabe', subdir: 'subdir', ref: 'refs/tags/v1.0.0'}}, 'https://github.com/docker/actions-toolkit.git#cafebabe:subdir'],
|
||||
[{ref: 'refs/heads/master', format: 'fragment', prHeadRef: false, sendGitQueryAsInput: false, buildxQuerySupport: true, attrs: {'keep-git-dir': 'true'}}, 'https://github.com/docker/actions-toolkit.git#860c1904a1ce19322e91ac35af1ab07466440c37'],
|
||||
[{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} = input;
|
||||
const {ref, checksum, format, prHeadRef, sendGitQueryAsInput, buildxQuerySupport, subdir, attrs} = 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, '860c1904a1ce19322e91ac35af1ab07466440c37', format)).toEqual(expected);
|
||||
expect(
|
||||
await build.gitContext({
|
||||
ref,
|
||||
...('checksum' in input ? {checksum} : {checksum: '860c1904a1ce19322e91ac35af1ab07466440c37'}),
|
||||
format,
|
||||
subdir,
|
||||
attrs
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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,11 @@ 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']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {afterEach, describe, expect, it, vi} from 'vitest';
|
||||
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
@@ -38,10 +38,133 @@ vi.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||
});
|
||||
|
||||
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({
|
||||
|
||||
@@ -51,11 +51,11 @@
|
||||
"@actions/io": "^3.0.2",
|
||||
"@actions/tool-cache": "^4.0.0",
|
||||
"@sigstore/bundle": "^4.0.0",
|
||||
"@sigstore/sign": "^4.1.0",
|
||||
"@sigstore/tuf": "^4.0.1",
|
||||
"@sigstore/sign": "^4.1.1",
|
||||
"@sigstore/tuf": "^4.0.2",
|
||||
"@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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -38,6 +38,14 @@ export interface ResolveSecretsOpts {
|
||||
redact?: boolean;
|
||||
}
|
||||
|
||||
export interface GitContextOpts {
|
||||
ref?: string;
|
||||
checksum?: string;
|
||||
subdir?: string;
|
||||
attrs?: Record<string, string>;
|
||||
format?: GitContextFormat;
|
||||
}
|
||||
|
||||
export class Build {
|
||||
private readonly buildx: Buildx;
|
||||
private readonly iidFilename: string;
|
||||
@@ -49,31 +57,52 @@ export class Build {
|
||||
this.metadataFilename = `build-metadata-${Util.generateRandomString()}.json`;
|
||||
}
|
||||
|
||||
public async gitContext(ref?: string, sha?: string, format?: GitContextFormat): Promise<string> {
|
||||
public async gitContext(opts?: GitContextOpts): Promise<string> {
|
||||
const gitContextCommonAttrs = new Set(['ref', 'checksum', 'subdir']);
|
||||
const setPullRequestHeadRef = Util.parseBoolOrDefault(process.env.DOCKER_DEFAULT_GIT_CONTEXT_PR_HEAD_REF);
|
||||
ref = ref || github.context.ref;
|
||||
sha = sha || github.context.sha;
|
||||
const commonAttrs = {
|
||||
ref: opts?.attrs?.ref,
|
||||
checksum: opts?.attrs?.checksum,
|
||||
subdir: opts?.attrs?.subdir
|
||||
};
|
||||
|
||||
const gitChecksum = opts?.checksum || commonAttrs.checksum || github.context.sha;
|
||||
let ref = opts?.ref || commonAttrs.ref || github.context.ref;
|
||||
const subdir = opts?.subdir || commonAttrs.subdir;
|
||||
const attrs = Object.entries(opts?.attrs || {}).filter(([name]) => !gitContextCommonAttrs.has(name));
|
||||
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 (sendGitQueryAsInput && (await this.buildx.versionSatisfies('>=0.29.0'))) {
|
||||
if (attrs.length > 0) {
|
||||
format = 'query';
|
||||
} else if (sendGitQueryAsInput && (await this.buildx.versionSatisfies('>=0.29.0'))) {
|
||||
format = 'query';
|
||||
} else {
|
||||
format = 'fragment';
|
||||
}
|
||||
}
|
||||
if (format === 'query') {
|
||||
return `${baseURL}?ref=${ref}${sha ? `&checksum=${sha}` : ''}`;
|
||||
const query = [`ref=${ref}`];
|
||||
if (gitChecksum) {
|
||||
query.push(`checksum=${gitChecksum}`);
|
||||
}
|
||||
if (subdir && subdir !== '.') {
|
||||
query.push(`subdir=${subdir}`);
|
||||
}
|
||||
for (const [name, value] of attrs) {
|
||||
query.push(`${name}=${value}`);
|
||||
}
|
||||
return `${baseURL}?${query.join('&')}`;
|
||||
}
|
||||
if (sha && !ref.startsWith(`refs/pull/`)) {
|
||||
return `${baseURL}#${sha}`;
|
||||
}
|
||||
return `${baseURL}#${ref}`;
|
||||
const fragmentRef = gitChecksum && !ref.startsWith(`refs/pull/`) ? gitChecksum : ref;
|
||||
return `${baseURL}#${fragmentRef}${subdir && subdir !== '.' ? `:${subdir}` : ''}`;
|
||||
}
|
||||
|
||||
public getImageIDFilePath(): string {
|
||||
|
||||
@@ -21,9 +21,9 @@ import {Buildx} from './buildx.js';
|
||||
import {Context} from '../context.js';
|
||||
import {Exec} from '../exec.js';
|
||||
|
||||
import {CreateOpts, CreateResponse, CreateResult, 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 {
|
||||
@@ -49,16 +49,8 @@ export class ImageTools {
|
||||
return await this.getCommand(['create', ...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 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;
|
||||
@@ -70,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;
|
||||
@@ -91,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) {
|
||||
@@ -123,8 +108,8 @@ 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> {
|
||||
@@ -205,4 +190,44 @@ export class ImageTools {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
111
yarn.lock
111
yarn.lock
@@ -380,8 +380,8 @@ __metadata:
|
||||
"@actions/tool-cache": "npm:^4.0.0"
|
||||
"@eslint/js": "npm:^9.39.3"
|
||||
"@sigstore/bundle": "npm:^4.0.0"
|
||||
"@sigstore/sign": "npm:^4.1.0"
|
||||
"@sigstore/tuf": "npm:^4.0.1"
|
||||
"@sigstore/sign": "npm:^4.1.1"
|
||||
"@sigstore/tuf": "npm:^4.0.2"
|
||||
"@sigstore/verify": "npm:^3.1.0"
|
||||
"@types/gunzip-maybe": "npm:^1.4.3"
|
||||
"@types/he": "npm:^1.2.3"
|
||||
@@ -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"
|
||||
@@ -696,6 +696,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@gar/promise-retry@npm:^1.0.0, @gar/promise-retry@npm:^1.0.2":
|
||||
version: 1.0.3
|
||||
resolution: "@gar/promise-retry@npm:1.0.3"
|
||||
checksum: 10/0d13ea3bb1025755e055648f6e290d2a7e0c87affaf552218f09f66b3fcd9ea9d5c9cc5fe2aa6e285e1530437768e40f9448fe9a86f4f3417b216dcf488d3d1a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@gar/promisify@npm:^1.1.3":
|
||||
version: 1.1.3
|
||||
resolution: "@gar/promisify@npm:1.1.3"
|
||||
@@ -837,6 +844,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@npmcli/redact@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@npmcli/redact@npm:4.0.0"
|
||||
checksum: 10/5d52df2b5267f4369c97a2b2f7c427e3d7aa4b6a83e7a1b522e196f6e9d50024c620bd0cb2052067c74d1aaa0c330d9bc04e1d335bfb46180e705bb33423e74c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@octokit/auth-token@npm:^6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "@octokit/auth-token@npm:6.0.0"
|
||||
@@ -1234,6 +1248,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sigstore/core@npm:^3.2.0":
|
||||
version: 3.2.0
|
||||
resolution: "@sigstore/core@npm:3.2.0"
|
||||
checksum: 10/2425d20297d57a5f5a62f0e6c2f4280818015ea00b3defebdac63f13c7d01db988602c316c16e374ba091c3649dd9a22ae8c9ba3ac165f736b0503164c5da5f5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sigstore/protobuf-specs@npm:^0.5.0":
|
||||
version: 0.5.0
|
||||
resolution: "@sigstore/protobuf-specs@npm:0.5.0"
|
||||
@@ -1241,27 +1262,27 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sigstore/sign@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "@sigstore/sign@npm:4.1.0"
|
||||
"@sigstore/sign@npm:^4.1.1":
|
||||
version: 4.1.1
|
||||
resolution: "@sigstore/sign@npm:4.1.1"
|
||||
dependencies:
|
||||
"@gar/promise-retry": "npm:^1.0.2"
|
||||
"@sigstore/bundle": "npm:^4.0.0"
|
||||
"@sigstore/core": "npm:^3.1.0"
|
||||
"@sigstore/core": "npm:^3.2.0"
|
||||
"@sigstore/protobuf-specs": "npm:^0.5.0"
|
||||
make-fetch-happen: "npm:^15.0.3"
|
||||
make-fetch-happen: "npm:^15.0.4"
|
||||
proc-log: "npm:^6.1.0"
|
||||
promise-retry: "npm:^2.0.1"
|
||||
checksum: 10/e5441d4cacf0f203f329e96bb7a3ca77682cfdf90d6448ad368344056fd8d55c01742e2b636545d55364490a87988f767f2b23168b2d9cc52ef3d8fe9e9496aa
|
||||
checksum: 10/c9424813ed83ae26111dd3a190dbfd776901cfc245ebb9aa68e133a7ffcbf8fc053f01d999a451e44805a291921ba4d2dfe80e3fd41b20cd5becd26aae5f5e7c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sigstore/tuf@npm:^4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "@sigstore/tuf@npm:4.0.1"
|
||||
"@sigstore/tuf@npm:^4.0.2":
|
||||
version: 4.0.2
|
||||
resolution: "@sigstore/tuf@npm:4.0.2"
|
||||
dependencies:
|
||||
"@sigstore/protobuf-specs": "npm:^0.5.0"
|
||||
tuf-js: "npm:^4.1.0"
|
||||
checksum: 10/1a9725aa95eba55badf24442fe8a71c6d68f8b7d17a6b2a5e4b5590117f0181881b3485cfa57ea375b7c3a38421dbffdfcbe86e6623d903e17e3a8359837e268
|
||||
checksum: 10/14882b8e71be4185ec417744b97a47392a50da00aafd4207a46bb74b40aa019ebf22d928052fd2d31a8da0da1efe7ebebac5a70898b31a74239a1ada997be754
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2178,10 +2199,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 +2676,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
|
||||
|
||||
@@ -3457,7 +3481,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"make-fetch-happen@npm:^15.0.1, make-fetch-happen@npm:^15.0.3":
|
||||
"make-fetch-happen@npm:^15.0.1":
|
||||
version: 15.0.3
|
||||
resolution: "make-fetch-happen@npm:15.0.3"
|
||||
dependencies:
|
||||
@@ -3476,6 +3500,26 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"make-fetch-happen@npm:^15.0.4":
|
||||
version: 15.0.5
|
||||
resolution: "make-fetch-happen@npm:15.0.5"
|
||||
dependencies:
|
||||
"@gar/promise-retry": "npm:^1.0.0"
|
||||
"@npmcli/agent": "npm:^4.0.0"
|
||||
"@npmcli/redact": "npm:^4.0.0"
|
||||
cacache: "npm:^20.0.1"
|
||||
http-cache-semantics: "npm:^4.1.1"
|
||||
minipass: "npm:^7.0.2"
|
||||
minipass-fetch: "npm:^5.0.0"
|
||||
minipass-flush: "npm:^1.0.5"
|
||||
minipass-pipeline: "npm:^1.2.4"
|
||||
negotiator: "npm:^1.0.0"
|
||||
proc-log: "npm:^6.0.0"
|
||||
ssri: "npm:^13.0.0"
|
||||
checksum: 10/d2649effb06c00cb2b266057cb1c8c1e99cfc8d1378e7d9c26cc8f00be41bc63d59b77a5576ed28f8105acc57fb16220b64217f8d3a6a066a594c004aa163afa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:^10.0.3":
|
||||
version: 10.0.3
|
||||
resolution: "minimatch@npm:10.0.3"
|
||||
@@ -3897,6 +3941,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"
|
||||
@@ -4789,9 +4840,9 @@ __metadata:
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user