Merge pull request #2196 from actions/update-attest-storage-record-params
Refactor attest package createStorageRecord function params
This commit is contained in:
+30
-34
@@ -189,7 +189,7 @@ async function run() {
|
|||||||
// repository write permissions.
|
// repository write permissions.
|
||||||
const ghToken = core.getInput('gh-token');
|
const ghToken = core.getInput('gh-token');
|
||||||
|
|
||||||
const record = await createStorageRecord({
|
const record = await createStorageRecord(
|
||||||
artifactOptions: {
|
artifactOptions: {
|
||||||
name: 'my-artifact-name',
|
name: 'my-artifact-name',
|
||||||
digest: { 'sha256': '36ab4667...'},
|
digest: { 'sha256': '36ab4667...'},
|
||||||
@@ -199,7 +199,7 @@ async function run() {
|
|||||||
registryUrl: "https://my-fave-pkg-registry.com"
|
registryUrl: "https://my-fave-pkg-registry.com"
|
||||||
},
|
},
|
||||||
token: ghToken
|
token: ghToken
|
||||||
});
|
);
|
||||||
|
|
||||||
console.log(record);
|
console.log(record);
|
||||||
}
|
}
|
||||||
@@ -210,39 +210,35 @@ run();
|
|||||||
The `createStorageRecord` function supports the following options:
|
The `createStorageRecord` function supports the following options:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
export type StorageRecordOptions = {
|
// Artifact details to associate the record with
|
||||||
// Includes details about the attested artifact
|
export type ArtifactOptions = {
|
||||||
artifactOptions: {
|
// The name of the artifact
|
||||||
// The name of the artifact
|
name: string
|
||||||
name: string
|
// The digest of the artifact
|
||||||
// The digest of the artifact
|
digest: string
|
||||||
digest: string
|
// The version of the artifact
|
||||||
// The version of the artifact
|
version?: string
|
||||||
version?: string
|
// The status of the artifact
|
||||||
// The status of the artifact
|
status?: string
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 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.
|
||||||
|
retryAttempts?: number
|
||||||
|
// HTTP headers to include in request to Artifact Metadata API.
|
||||||
|
headers?: RequestHeaders
|
||||||
```
|
```
|
||||||
|
|
||||||
## Sigstore Instance
|
## Sigstore Instance
|
||||||
|
|||||||
@@ -6,17 +6,13 @@ describe('createStorageRecord', () => {
|
|||||||
const token = 'token'
|
const token = 'token'
|
||||||
const headers = {'X-GitHub-Foo': 'true'}
|
const headers = {'X-GitHub-Foo': 'true'}
|
||||||
|
|
||||||
const options = {
|
const artifactOptions = {
|
||||||
artifactOptions: {
|
name: 'my-lib',
|
||||||
name: 'my-lib',
|
version: '1.0.0',
|
||||||
version: '1.0.0',
|
digest: `sha256:${'a'.repeat(64)}`
|
||||||
digest: `sha256:${'a'.repeat(64)}`
|
}
|
||||||
},
|
const packageRegistryOptions = {
|
||||||
packageRegistryOptions: {
|
registryUrl: 'https://my-registry.org'
|
||||||
registryUrl: 'https://my-registry.org'
|
|
||||||
},
|
|
||||||
token,
|
|
||||||
writeOptions: {headers}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const mockAgent = new MockAgent()
|
const mockAgent = new MockAgent()
|
||||||
@@ -52,7 +48,15 @@ describe('createStorageRecord', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('persists the storage record', async () => {
|
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 +80,13 @@ describe('createStorageRecord', () => {
|
|||||||
|
|
||||||
it('throws an error', async () => {
|
it('throws an error', async () => {
|
||||||
await expect(
|
await expect(
|
||||||
createStorageRecord({
|
createStorageRecord(
|
||||||
...options,
|
artifactOptions,
|
||||||
writeOptions: {retry: 0}
|
packageRegistryOptions,
|
||||||
})
|
token,
|
||||||
|
0,
|
||||||
|
headers
|
||||||
|
)
|
||||||
).rejects.toThrow(/oops/)
|
).rejects.toThrow(/oops/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -94,8 +101,8 @@ describe('createStorageRecord', () => {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {authorization: `token ${token}`},
|
headers: {authorization: `token ${token}`},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
...options.artifactOptions,
|
...artifactOptions,
|
||||||
registry_url: options.packageRegistryOptions.registryUrl
|
registry_url: packageRegistryOptions.registryUrl
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.reply(500, 'oops')
|
.reply(500, 'oops')
|
||||||
@@ -107,8 +114,8 @@ describe('createStorageRecord', () => {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {authorization: `token ${token}`},
|
headers: {authorization: `token ${token}`},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
...options.artifactOptions,
|
...artifactOptions,
|
||||||
registry_url: options.packageRegistryOptions.registryUrl
|
registry_url: packageRegistryOptions.registryUrl
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.reply(200, {storage_records: [{id: 123}, {id: 456}]})
|
.reply(200, {storage_records: [{id: 123}, {id: 456}]})
|
||||||
@@ -117,10 +124,13 @@ describe('createStorageRecord', () => {
|
|||||||
|
|
||||||
it('persists the storage record', async () => {
|
it('persists the storage record', async () => {
|
||||||
await expect(
|
await expect(
|
||||||
createStorageRecord({
|
createStorageRecord(
|
||||||
...options,
|
artifactOptions,
|
||||||
writeOptions: {}
|
packageRegistryOptions,
|
||||||
})
|
token,
|
||||||
|
undefined,
|
||||||
|
headers
|
||||||
|
)
|
||||||
).resolves.toEqual([123, 456])
|
).resolves.toEqual([123, 456])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,57 +9,54 @@ const DEFAULT_RETRY_COUNT = 5
|
|||||||
/**
|
/**
|
||||||
* Options for creating a storage record for an attested artifact.
|
* Options for creating a storage record for an attested artifact.
|
||||||
*/
|
*/
|
||||||
export type StorageRecordOptions = {
|
export type ArtifactOptions = {
|
||||||
// Includes details about the attested artifact
|
// Includes details about the attested artifact
|
||||||
artifactOptions: {
|
// The name of the artifact
|
||||||
// The name of the artifact
|
name: string
|
||||||
name: string
|
// The digest of the artifact
|
||||||
// The digest of the artifact
|
digest: string
|
||||||
digest: string
|
// The version of the artifact
|
||||||
// The version of the artifact
|
version?: string
|
||||||
version?: string
|
// The status of the artifact
|
||||||
// The status of the artifact
|
status?: string
|
||||||
status?: string
|
}
|
||||||
}
|
// Includes details about the package registry the artifact was published to
|
||||||
// Includes details about the package registry the artifact was published to
|
export type PackageRegistryOptions = {
|
||||||
packageRegistryOptions: {
|
// The URL of the package registry
|
||||||
// The URL of the package registry
|
registryUrl: string
|
||||||
registryUrl: string
|
// The URL of the artifact in the package registry
|
||||||
// The URL of the artifact in the package registry
|
artifactUrl?: string
|
||||||
artifactUrl?: string
|
// The package registry repository the artifact was published to.
|
||||||
// The package registry repository the artifact was published to.
|
repo?: string
|
||||||
repo?: string
|
// The path of the artifact in the package registry repository.
|
||||||
// The path of the artifact in the package registry repository.
|
path?: string
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a storage record on behalf of an artifact that has been attested
|
* 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 retryAttempts - 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.
|
* @returns The ID of the storage record.
|
||||||
* @throws Error if the storage record fails to persist.
|
* @throws Error if the storage record fails to persist.
|
||||||
*/
|
*/
|
||||||
export async function createStorageRecord(
|
export async function createStorageRecord(
|
||||||
options: StorageRecordOptions
|
artifactOptions: ArtifactOptions,
|
||||||
|
packageRegistryOptions: PackageRegistryOptions,
|
||||||
|
token: string,
|
||||||
|
retryAttempts?: number,
|
||||||
|
headers?: RequestHeaders
|
||||||
): Promise<number[]> {
|
): Promise<number[]> {
|
||||||
const retries = options.writeOptions.retry ?? DEFAULT_RETRY_COUNT
|
const retries = retryAttempts ?? DEFAULT_RETRY_COUNT
|
||||||
const octokit = github.getOctokit(options.token, {retry: {retries}}, retry)
|
const octokit = github.getOctokit(token, {retry: {retries}}, retry)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await octokit.request(CREATE_STORAGE_RECORD_REQUEST, {
|
const response = await octokit.request(CREATE_STORAGE_RECORD_REQUEST, {
|
||||||
owner: github.context.repo.owner,
|
owner: github.context.repo.owner,
|
||||||
headers: options.writeOptions.headers,
|
headers,
|
||||||
...buildRequestParams(options)
|
...buildRequestParams(artifactOptions, packageRegistryOptions)
|
||||||
})
|
})
|
||||||
|
|
||||||
const data =
|
const data =
|
||||||
@@ -75,11 +72,12 @@ export async function createStorageRecord(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildRequestParams(
|
function buildRequestParams(
|
||||||
options: StorageRecordOptions
|
artifactOptions: ArtifactOptions,
|
||||||
|
packageRegistryOptions: PackageRegistryOptions
|
||||||
): Record<string, unknown> {
|
): Record<string, unknown> {
|
||||||
const {registryUrl, artifactUrl, ...rest} = options.packageRegistryOptions
|
const {registryUrl, artifactUrl, ...rest} = packageRegistryOptions
|
||||||
return {
|
return {
|
||||||
...options.artifactOptions,
|
...artifactOptions,
|
||||||
registry_url: registryUrl,
|
registry_url: registryUrl,
|
||||||
artifact_url: artifactUrl,
|
artifact_url: artifactUrl,
|
||||||
...rest
|
...rest
|
||||||
|
|||||||
Reference in New Issue
Block a user