diff --git a/packages/attest/README.md b/packages/attest/README.md index 49903437..12e75306 100644 --- a/packages/attest/README.md +++ b/packages/attest/README.md @@ -189,7 +189,7 @@ async function run() { // repository write permissions. const ghToken = core.getInput('gh-token'); - const record = await createStorageRecord({ + const record = await createStorageRecord( artifactOptions: { name: 'my-artifact-name', digest: { 'sha256': '36ab4667...'}, @@ -199,7 +199,7 @@ async function run() { registryUrl: "https://my-fave-pkg-registry.com" }, token: ghToken - }); + ); console.log(record); } @@ -210,39 +210,35 @@ run(); The `createStorageRecord` function supports the following options: ```typescript -export type StorageRecordOptions = { - // Includes details about the attested artifact - artifactOptions: { - // The name of the artifact - name: string - // The digest of the artifact - digest: string - // The version of the artifact - version?: string - // The status of the artifact - status?: string - }, - // Includes details about the package registry the artifact was published to - packageRegistryOptions: { - // The URL of the package registry - registryUrl: string - // The URL of the artifact in the package registry - artifactUrl?: string - // The package registry repository the artifact was published to. - repo?: string - // The path of the artifact in the package registry repository. - path?: string - }, - // GitHub token for writing attestations. - token: string - // Optional parameters for the write operation. - writeOptions: { - // The number of times to retry the request. - retry?: number - // HTTP headers to include in request to Artifact Metadata API. - headers?: RequestHeaders - } +// Artifact details to associate the record with +export type ArtifactOptions = { + // The name of the artifact + name: string + // The digest of the artifact + digest: string + // The version of the artifact + version?: string + // The status of the artifact + status?: string } +// Includes details about the package registry the artifact was published to +export type PackageRegistryOptions = { + // The URL of the package registry + registryUrl: string + // The URL of the artifact in the package registry + artifactUrl?: string + // The package registry repository the artifact was published to. + repo?: string + // The path of the artifact in the package registry repository. + path?: string +} +// GitHub token for writing attestations. +token: string +// Optional parameters for the write operation. +// The number of times to retry the request. +cusomtRetry?: number +// HTTP headers to include in request to Artifact Metadata API. +headers?: RequestHeaders ``` ## Sigstore Instance diff --git a/packages/attest/__tests__/artifactMetadata.test.ts b/packages/attest/__tests__/artifactMetadata.test.ts index c447ba55..b3f781c6 100644 --- a/packages/attest/__tests__/artifactMetadata.test.ts +++ b/packages/attest/__tests__/artifactMetadata.test.ts @@ -6,17 +6,13 @@ describe('createStorageRecord', () => { const token = 'token' const headers = {'X-GitHub-Foo': 'true'} - const options = { - artifactOptions: { - name: 'my-lib', - version: '1.0.0', - digest: `sha256:${'a'.repeat(64)}` - }, - packageRegistryOptions: { - registryUrl: 'https://my-registry.org' - }, - token, - writeOptions: {headers} + const artifactOptions = { + name: 'my-lib', + version: '1.0.0', + digest: `sha256:${'a'.repeat(64)}` + } + const packageRegistryOptions = { + registryUrl: 'https://my-registry.org' } const mockAgent = new MockAgent() @@ -52,7 +48,7 @@ describe('createStorageRecord', () => { }) it('persists the storage record', async () => { - await expect(createStorageRecord(options)).resolves.toEqual([123, 456]) + await expect(createStorageRecord(artifactOptions, packageRegistryOptions, token, undefined, headers)).resolves.toEqual([123, 456]) }) }) @@ -76,10 +72,13 @@ describe('createStorageRecord', () => { it('throws an error', async () => { await expect( - createStorageRecord({ - ...options, - writeOptions: {retry: 0} - }) + createStorageRecord( + artifactOptions, + packageRegistryOptions, + token, + 0, + headers + ) ).rejects.toThrow(/oops/) }) }) @@ -94,8 +93,8 @@ describe('createStorageRecord', () => { method: 'POST', headers: {authorization: `token ${token}`}, body: JSON.stringify({ - ...options.artifactOptions, - registry_url: options.packageRegistryOptions.registryUrl + ...artifactOptions, + registry_url: packageRegistryOptions.registryUrl }) }) .reply(500, 'oops') @@ -107,8 +106,8 @@ describe('createStorageRecord', () => { method: 'POST', headers: {authorization: `token ${token}`}, body: JSON.stringify({ - ...options.artifactOptions, - registry_url: options.packageRegistryOptions.registryUrl + ...artifactOptions, + registry_url: packageRegistryOptions.registryUrl }) }) .reply(200, {storage_records: [{id: 123}, {id: 456}]}) @@ -117,10 +116,13 @@ describe('createStorageRecord', () => { it('persists the storage record', async () => { await expect( - createStorageRecord({ - ...options, - writeOptions: {} - }) + createStorageRecord( + artifactOptions, + packageRegistryOptions, + token, + undefined, + headers + ) ).resolves.toEqual([123, 456]) }) }) diff --git a/packages/attest/src/artifactMetadata.ts b/packages/attest/src/artifactMetadata.ts index 6a5c514f..e7e5a5bc 100644 --- a/packages/attest/src/artifactMetadata.ts +++ b/packages/attest/src/artifactMetadata.ts @@ -9,57 +9,54 @@ const DEFAULT_RETRY_COUNT = 5 /** * Options for creating a storage record for an attested artifact. */ -export type StorageRecordOptions = { +export type ArtifactOptions = { // Includes details about the attested artifact - artifactOptions: { - // The name of the artifact - name: string - // The digest of the artifact - digest: string - // The version of the artifact - version?: string - // The status of the artifact - status?: string - } + // The name of the artifact + name: string + // The digest of the artifact + digest: string + // The version of the artifact + version?: string + // The status of the artifact + status?: string +} // Includes details about the package registry the artifact was published to - packageRegistryOptions: { - // The URL of the package registry - registryUrl: string - // The URL of the artifact in the package registry - artifactUrl?: string - // The package registry repository the artifact was published to. - repo?: string - // The path of the artifact in the package registry repository. - path?: string - } - // GitHub token for writing attestations. - token: string - // Optional parameters for the write operation. - writeOptions: { - // The number of times to retry the request. - retry?: number - // HTTP headers to include in request to Artifact Metadata API. - headers?: RequestHeaders - } +export type PackageRegistryOptions = { + // The URL of the package registry + registryUrl: string + // The URL of the artifact in the package registry + artifactUrl?: string + // The package registry repository the artifact was published to. + repo?: string + // The path of the artifact in the package registry repository. + path?: string } /** * Writes a storage record on behalf of an artifact that has been attested - * @param StorageRecordOptions - parameters for the storage record API request. + * @param artifactOptions - parameters for the storage record API request. + * @param packageRegistryOptions - parameters for the package registry API request. + * @param token - GitHub token used to authenticate the request. + * @param retry - The number of retries to attempt if the request fails. + * @param headers - Additional headers to include in the request. + * * @returns The ID of the storage record. * @throws Error if the storage record fails to persist. */ export async function createStorageRecord( - options: StorageRecordOptions + artifactOptions: ArtifactOptions, + packageRegistryOptions: PackageRegistryOptions, + token: string, + customRetry?: number, + headers?: RequestHeaders ): Promise { - const retries = options.writeOptions.retry ?? DEFAULT_RETRY_COUNT - const octokit = github.getOctokit(options.token, {retry: {retries}}, retry) - + const retries = customRetry ?? DEFAULT_RETRY_COUNT + const octokit = github.getOctokit(token, {retry: {retries}}, retry) try { const response = await octokit.request(CREATE_STORAGE_RECORD_REQUEST, { owner: github.context.repo.owner, - headers: options.writeOptions.headers, - ...buildRequestParams(options) + headers: headers, + ...buildRequestParams(artifactOptions, packageRegistryOptions) }) const data = @@ -75,11 +72,12 @@ export async function createStorageRecord( } function buildRequestParams( - options: StorageRecordOptions + artifactOptions: ArtifactOptions, + packageRegistryOptions: PackageRegistryOptions ): Record { - const {registryUrl, artifactUrl, ...rest} = options.packageRegistryOptions + const {registryUrl, artifactUrl, ...rest} = packageRegistryOptions return { - ...options.artifactOptions, + ...artifactOptions, registry_url: registryUrl, artifact_url: artifactUrl, ...rest