upload attestation and referrer index before artifact

This avoids race conditions when the artifact is read but its attestation doesn't exist
This commit is contained in:
Conor Sloan
2024-08-22 16:10:09 +01:00
parent 1f725c56d6
commit c11354f432
3 changed files with 154 additions and 143 deletions
+131 -120
View File
@@ -207,6 +207,112 @@ describe('run', () => {
expect(setFailedMock).toHaveBeenCalledWith('Something went wrong')
})
it('fails if creating attestation fails', async () => {
resolvePublishActionOptionsMock.mockReturnValue(baseOptions())
ensureCorrectShaCheckedOutMock.mockImplementation(() => {})
createTempDirMock.mockImplementation(() => {
return 'stagingOrArchivesDir'
})
stageActionFilesMock.mockImplementation(() => {})
calculateManifestDigestMock.mockImplementation(() => {
return 'sha256:my-test-digest'
})
createArchivesMock.mockImplementation(() => {
return {
zipFile: {
path: 'test',
size: 5,
sha256: '123'
},
tarFile: {
path: 'test2',
size: 52,
sha256: '1234'
}
}
})
publishOCIArtifactMock.mockImplementation(() => {
return {
packageURL: 'https://ghcr.io/v2/test-org/test-repo:1.2.3',
publishedDigest: 'sha256:my-test-digest'
}
})
generateAttestationMock.mockImplementation(async () => {
throw new Error('Something went wrong')
})
// Run the action
await main.run()
// Check the results
expect(setFailedMock).toHaveBeenCalledWith('Something went wrong')
})
it('fails if uploading attestation to GHCR fails', async () => {
resolvePublishActionOptionsMock.mockReturnValue(baseOptions())
ensureCorrectShaCheckedOutMock.mockImplementation(() => {})
createTempDirMock.mockImplementation(() => {
return 'stagingOrArchivesDir'
})
stageActionFilesMock.mockImplementation(() => {})
createArchivesMock.mockImplementation(() => {
return {
zipFile: {
path: 'test',
size: 5,
sha256: '123'
},
tarFile: {
path: 'test2',
size: 52,
sha256: '1234'
}
}
})
calculateManifestDigestMock.mockImplementation(() => {
return 'sha256:my-test-digest'
})
generateAttestationMock.mockImplementation(async options => {
expect(options).toHaveProperty('skipWrite', true)
return {
attestationID: 'test-attestation-id',
certificate: 'test',
bundle: {
mediaType: 'application/vnd.cncf.notary.v2+jwt',
verificationMaterial: {
publicKey: {
hint: 'test-hint'
}
}
}
}
})
attachArtifactToImageMock.mockImplementation(() => {
throw new Error('Something went wrong')
})
// Run the action
await main.run()
// Check the results
expect(setFailedMock).toHaveBeenCalledWith('Something went wrong')
})
it('fails if publishing OCI artifact fails', async () => {
resolvePublishActionOptionsMock.mockReturnValue(baseOptions())
@@ -254,6 +360,15 @@ describe('run', () => {
}
})
attachArtifactToImageMock.mockImplementation(() => {
return {
digest: 'sha256:my-test-attestation-digest',
urls: [
'ghcr.io/v2/test-org/test-package/manifests/sha256:my-test-attestation-digest'
]
}
})
publishOCIArtifactMock.mockImplementation(() => {
throw new Error('Something went wrong')
})
@@ -312,6 +427,15 @@ describe('run', () => {
}
})
attachArtifactToImageMock.mockImplementation(() => {
return {
digest: 'sha256:some-other-digest',
urls: [
'ghcr.io/v2/test-org/test-package/manifests/sha256:some-other-digest'
]
}
})
publishOCIArtifactMock.mockImplementation(() => {
return {
packageURL: 'https://ghcr.io/v2/test-org/test-repo:1.2.3',
@@ -328,119 +452,6 @@ describe('run', () => {
)
})
it('fails if uploading attestation to GHCR fails', async () => {
resolvePublishActionOptionsMock.mockReturnValue(baseOptions())
ensureCorrectShaCheckedOutMock.mockImplementation(() => {})
createTempDirMock.mockImplementation(() => {
return 'stagingOrArchivesDir'
})
stageActionFilesMock.mockImplementation(() => {})
createArchivesMock.mockImplementation(() => {
return {
zipFile: {
path: 'test',
size: 5,
sha256: '123'
},
tarFile: {
path: 'test2',
size: 52,
sha256: '1234'
}
}
})
calculateManifestDigestMock.mockImplementation(() => {
return 'sha256:my-test-digest'
})
publishOCIArtifactMock.mockImplementation(() => {
return {
packageURL: 'https://ghcr.io/v2/test-org/test-repo:1.2.3',
publishedDigest: 'sha256:my-test-digest'
}
})
generateAttestationMock.mockImplementation(async options => {
expect(options).toHaveProperty('skipWrite', true)
return {
attestationID: 'test-attestation-id',
certificate: 'test',
bundle: {
mediaType: 'application/vnd.cncf.notary.v2+jwt',
verificationMaterial: {
publicKey: {
hint: 'test-hint'
}
}
}
}
})
attachArtifactToImageMock.mockImplementation(() => {
throw new Error('Something went wrong')
})
// Run the action
await main.run()
// Check the results
expect(setFailedMock).toHaveBeenCalledWith('Something went wrong')
})
it('fails if creating attestation fails', async () => {
resolvePublishActionOptionsMock.mockReturnValue(baseOptions())
ensureCorrectShaCheckedOutMock.mockImplementation(() => {})
createTempDirMock.mockImplementation(() => {
return 'stagingOrArchivesDir'
})
stageActionFilesMock.mockImplementation(() => {})
calculateManifestDigestMock.mockImplementation(() => {
return 'sha256:my-test-digest'
})
createArchivesMock.mockImplementation(() => {
return {
zipFile: {
path: 'test',
size: 5,
sha256: '123'
},
tarFile: {
path: 'test2',
size: 52,
sha256: '1234'
}
}
})
publishOCIArtifactMock.mockImplementation(() => {
return {
packageURL: 'https://ghcr.io/v2/test-org/test-repo:1.2.3',
publishedDigest: 'sha256:my-test-digest'
}
})
generateAttestationMock.mockImplementation(async () => {
throw new Error('Something went wrong')
})
// Run the action
await main.run()
// Check the results
expect(setFailedMock).toHaveBeenCalledWith('Something went wrong')
})
it('uploads the artifact, returns package metadata from GHCR, and skips writing attestation in enterprise', async () => {
const options = baseOptions()
options.isEnterprise = true
@@ -535,13 +546,6 @@ describe('run', () => {
return 'sha256:my-test-digest'
})
publishOCIArtifactMock.mockImplementation(() => {
return {
packageURL: 'https://ghcr.io/v2/test-org/test-repo:1.2.3',
publishedDigest: 'sha256:my-test-digest'
}
})
generateAttestationMock.mockImplementation(async options => {
expect(options).toHaveProperty('skipWrite', true)
@@ -568,6 +572,13 @@ describe('run', () => {
}
})
publishOCIArtifactMock.mockImplementation(() => {
return {
packageURL: 'https://ghcr.io/v2/test-org/test-repo:1.2.3',
publishedDigest: 'sha256:my-test-digest'
}
})
// Run the action
await main.run()