fix up ghcr client tests and remove config from action package layers

This commit is contained in:
Conor Sloan
2024-08-23 10:56:04 +01:00
parent e53d6ca2a2
commit e308348d01
7 changed files with 482 additions and 547 deletions
File diff suppressed because it is too large Load Diff
+2 -5
View File
@@ -495,7 +495,7 @@ describe('run', () => {
expect(blobs.has('123')).toBeTruthy()
expect(blobs.has('1234')).toBeTruthy()
expect(manifest.mediaType).toBe(ociContainer.imageManifestMediaType)
expect(manifest.layers.length).toBe(3)
expect(manifest.layers.length).toBe(2)
expect(manifest.annotations['com.github.package.type']).toBe(
ociContainer.actionPackageAnnotationValue
)
@@ -585,7 +585,6 @@ describe('run', () => {
uploadOCIImageManifestMock.mockImplementation(
(token, registry, repository, manifest, blobs, tag) => {
let expectedBlobKeys: string[] = []
let expectedLayers = 0
let expectedAnnotationValue = ''
let expectedTagValue: string | undefined = undefined
let returnValue = ''
@@ -599,13 +598,11 @@ describe('run', () => {
)
expectedBlobKeys = [sigStoreLayer.digest, ociContainer.emptyConfigSha]
expectedLayers = 1
returnValue = 'sha256:attestation-digest'
} else {
expectedAnnotationValue = ociContainer.actionPackageAnnotationValue
expectedTagValue = '1.2.3'
expectedBlobKeys = ['123', '1234', ociContainer.emptyConfigSha]
expectedLayers = 3
returnValue = 'sha256:my-test-digest'
}
@@ -617,7 +614,7 @@ describe('run', () => {
expectedAnnotationValue
)
expect(tag).toBe(expectedTagValue)
expect(manifest.layers.length).toBe(expectedLayers)
expect(manifest.layers.length).toBe(expectedBlobKeys.length - 1) // Minus config layer
expect(blobs.size).toBe(expectedBlobKeys.length)
for (const expectedBlobKey of expectedBlobKeys) {
expect(blobs.has(expectedBlobKey)).toBeTruthy()
+2 -7
View File
@@ -16,7 +16,7 @@ describe('sha256Digest', () => {
const { manifest } = testActionPackageManifest()
const digest = sha256Digest(manifest)
const expectedDigest =
'sha256:dd8537ef913cf87e25064a074973ed2c62699f1dbd74d0dd78e85d394a5758b5'
'sha256:1af9bf993bf068a51fbb54822471ab7507b07c553bcac09a7c91328740d8ed69'
expect(digest).toEqual(expectedDigest)
})
@@ -26,7 +26,7 @@ describe('size', () => {
it('returns the total size of the provided manifest', () => {
const { manifest } = testActionPackageManifest()
const size = sizeInBytes(manifest)
expect(size).toBe(1133)
expect(size).toBe(991)
})
})
@@ -44,11 +44,6 @@ describe('createActionPackageManifest', () => {
"digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"
},
"layers":[
{
"mediaType":"application/vnd.oci.empty.v1+json",
"size":2,
"digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"
},
{
"mediaType":"application/vnd.github.actions.package.layer.v1.tar+gzip",
"size":${tarFile.size},
+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="116" height="20" role="img" aria-label="Coverage: 77.28%"><title>Coverage: 77.28%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="116" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="63" height="20" fill="#555"/><rect x="63" width="53" height="20" fill="#e05d44"/><rect width="116" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">Coverage</text><text x="325" y="140" transform="scale(.1)" fill="#fff" textLength="530">Coverage</text><text aria-hidden="true" x="885" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">77.28%</text><text x="885" y="140" transform="scale(.1)" fill="#fff" textLength="430">77.28%</text></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="116" height="20" role="img" aria-label="Coverage: 95.01%"><title>Coverage: 95.01%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="116" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="63" height="20" fill="#555"/><rect x="63" width="53" height="20" fill="#4c1"/><rect width="116" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">Coverage</text><text x="325" y="140" transform="scale(.1)" fill="#fff" textLength="530">Coverage</text><text aria-hidden="true" x="885" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">95.01%</text><text x="885" y="140" transform="scale(.1)" fill="#fff" textLength="430">95.01%</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Generated Vendored
+8 -5
View File
@@ -106682,7 +106682,9 @@ async function uploadOCIImageManifest(token, registry, repository, manifest, blo
else {
core.info(`Uploading manifest ${manifestSHA} to ${repository}.`);
}
const layerUploads = manifest.layers.map(async (layer) => {
// We must also upload the config layer
const layersToUpload = manifest.layers.concat(manifest.config);
const layerUploads = layersToUpload.map(async (layer) => {
const blob = blobs.get(layer.digest);
if (!blob) {
throw new Error(`Blob for layer ${layer.digest} not found`);
@@ -107022,6 +107024,7 @@ exports.createSigstoreAttestationManifest = createSigstoreAttestationManifest;
exports.createReferrerTagManifest = createReferrerTagManifest;
exports.sha256Digest = sha256Digest;
exports.sizeInBytes = sizeInBytes;
exports.createEmptyConfigLayer = createEmptyConfigLayer;
const crypto = __importStar(__nccwpck_require__(6113));
exports.imageIndexMediaType = 'application/vnd.oci.image.index.v1+json';
exports.imageManifestMediaType = 'application/vnd.oci.image.manifest.v1+json';
@@ -107037,7 +107040,7 @@ exports.emptyConfigSize = 2;
exports.emptyConfigSha = 'sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a';
// Given a name and archive metadata, creates a manifest in the format expected by GHCR for an Actions Package.
function createActionPackageManifest(tarFile, zipFile, repository, repoId, ownerId, sourceCommit, version, created = new Date()) {
const configLayer = createConfigLayer();
const configLayer = createEmptyConfigLayer();
const sanitizedRepo = sanitizeRepository(repository);
const tarLayer = createTarLayer(tarFile, sanitizedRepo, version);
const zipLayer = createZipLayer(zipFile, sanitizedRepo, version);
@@ -107046,7 +107049,7 @@ function createActionPackageManifest(tarFile, zipFile, repository, repoId, owner
mediaType: exports.imageManifestMediaType,
artifactType: exports.actionsPackageMediaType,
config: configLayer,
layers: [configLayer, tarLayer, zipLayer],
layers: [tarLayer, zipLayer],
annotations: {
'org.opencontainers.image.created': created.toISOString(),
'action.tar.gz.digest': tarFile.sha256,
@@ -107061,7 +107064,7 @@ function createActionPackageManifest(tarFile, zipFile, repository, repoId, owner
return manifest;
}
function createSigstoreAttestationManifest(bundleSize, bundleDigest, subjectSize, subjectDigest, created = new Date()) {
const configLayer = createConfigLayer();
const configLayer = createEmptyConfigLayer();
const sigstoreAttestationLayer = {
mediaType: exports.sigstoreBundleMediaType,
size: bundleSize,
@@ -107127,7 +107130,7 @@ function sizeInBytes(manifest) {
const data = JSON.stringify(manifest);
return Buffer.byteLength(data, 'utf8');
}
function createConfigLayer() {
function createEmptyConfigLayer() {
const configLayer = {
mediaType: exports.ociEmptyMediaType,
size: exports.emptyConfigSize,
+4 -1
View File
@@ -20,7 +20,10 @@ export async function uploadOCIImageManifest(
core.info(`Uploading manifest ${manifestSHA} to ${repository}.`)
}
const layerUploads: Promise<void>[] = manifest.layers.map(async layer => {
// We must also upload the config layer
const layersToUpload = manifest.layers.concat(manifest.config)
const layerUploads: Promise<void>[] = layersToUpload.map(async layer => {
const blob = blobs.get(layer.digest)
if (!blob) {
throw new Error(`Blob for layer ${layer.digest} not found`)
+4 -4
View File
@@ -60,7 +60,7 @@ export function createActionPackageManifest(
version: string,
created: Date = new Date()
): OCIImageManifest {
const configLayer = createConfigLayer()
const configLayer = createEmptyConfigLayer()
const sanitizedRepo = sanitizeRepository(repository)
const tarLayer = createTarLayer(tarFile, sanitizedRepo, version)
const zipLayer = createZipLayer(zipFile, sanitizedRepo, version)
@@ -70,7 +70,7 @@ export function createActionPackageManifest(
mediaType: imageManifestMediaType,
artifactType: actionsPackageMediaType,
config: configLayer,
layers: [configLayer, tarLayer, zipLayer],
layers: [tarLayer, zipLayer],
annotations: {
'org.opencontainers.image.created': created.toISOString(),
'action.tar.gz.digest': tarFile.sha256,
@@ -93,7 +93,7 @@ export function createSigstoreAttestationManifest(
subjectDigest: string,
created: Date = new Date()
): OCIImageManifest {
const configLayer = createConfigLayer()
const configLayer = createEmptyConfigLayer()
const sigstoreAttestationLayer: Descriptor = {
mediaType: sigstoreBundleMediaType,
@@ -178,7 +178,7 @@ export function sizeInBytes(
return Buffer.byteLength(data, 'utf8')
}
function createConfigLayer(): Descriptor {
export function createEmptyConfigLayer(): Descriptor {
const configLayer: Descriptor = {
mediaType: ociEmptyMediaType,
size: emptyConfigSize,