when only one artifact-id is given, use getArtifact and check the resulting id returned

This commit is contained in:
GrantBirki 2025-04-17 11:48:44 -07:00
parent 42aef06f22
commit ec378bcca1
No known key found for this signature in database
GPG Key ID: 65497A530F6F9405
2 changed files with 199 additions and 8 deletions

View File

@ -25,6 +25,8 @@ const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
[Inputs.Repository]: 'owner/some-repository', [Inputs.Repository]: 'owner/some-repository',
[Inputs.RunID]: 'some-run-id', [Inputs.RunID]: 'some-run-id',
[Inputs.Pattern]: 'some-pattern', [Inputs.Pattern]: 'some-pattern',
[Inputs.MergeMultiple]: false,
[Inputs.ArtifactIds]: '',
...overrides ...overrides
} }
@ -221,4 +223,164 @@ describe('download', () => {
expect.stringContaining('digest validation failed') expect.stringContaining('digest validation failed')
) )
}) })
test('throws error when both name and artifact-ids are provided', async () => {
mockInputs({
[Inputs.Name]: 'artifact-name',
[Inputs.ArtifactIds]: '123'
})
await expect(run()).rejects.toThrow(
"Inputs 'name' and 'artifact-ids' cannot be used together. Please specify only one."
)
})
test('throws error when artifact-ids is empty', async () => {
mockInputs({
[Inputs.Name]: '',
[Inputs.ArtifactIds]: ' , '
})
await expect(run()).rejects.toThrow(
"No valid artifact IDs provided in 'artifact-ids' input"
)
})
test('throws error when artifact-id is not a number', async () => {
mockInputs({
[Inputs.Name]: '',
[Inputs.ArtifactIds]: '123,abc,456'
})
await expect(run()).rejects.toThrow(
"Invalid artifact ID: 'abc'. Must be a number."
)
})
test('downloads a single artifact by ID', async () => {
const mockArtifact = {
id: 123,
name: 'artifact-by-id',
size: 1024,
digest: 'def456'
}
mockInputs({
[Inputs.Name]: '',
[Inputs.ArtifactIds]: '123'
})
jest
.spyOn(artifact, 'getArtifact')
.mockImplementation(() => Promise.resolve({artifact: mockArtifact}))
await run()
expect(core.debug).toHaveBeenCalledWith(
'Only one artifact ID provided. Fetching latest artifact by its name and checking the ID'
)
expect(artifact.getArtifact).toHaveBeenCalled()
expect(artifact.downloadArtifact).toHaveBeenCalledWith(
mockArtifact.id,
expect.objectContaining({
expectedHash: mockArtifact.digest
})
)
expect(artifact.listArtifacts).not.toHaveBeenCalled()
expect(core.info).toHaveBeenCalledWith('Total of 1 artifact(s) downloaded')
})
test('throws error when single artifact ID is not found', async () => {
mockInputs({
[Inputs.Name]: '',
[Inputs.ArtifactIds]: '999'
})
jest.spyOn(artifact, 'getArtifact').mockImplementation(() => {
return Promise.resolve({artifact: null} as any)
})
await expect(run()).rejects.toThrow(
"Artifact with ID '999' not found. Please check the ID."
)
})
test('downloads multiple artifacts by IDs', async () => {
const mockArtifacts = [
{id: 123, name: 'artifact1', size: 1024, digest: 'abc123'},
{id: 456, name: 'artifact2', size: 2048, digest: 'def456'},
{id: 789, name: 'artifact3', size: 3072, digest: 'ghi789'}
]
mockInputs({
[Inputs.Name]: '',
[Inputs.ArtifactIds]: '123, 456'
})
jest
.spyOn(artifact, 'listArtifacts')
.mockImplementation(() => Promise.resolve({artifacts: mockArtifacts}))
await run()
expect(core.info).toHaveBeenCalledWith(
'Multiple artifact IDs provided. Fetching all artifacts to filter by ID'
)
expect(artifact.getArtifact).not.toHaveBeenCalled()
expect(artifact.listArtifacts).toHaveBeenCalled()
expect(artifact.downloadArtifact).toHaveBeenCalledTimes(2)
expect(artifact.downloadArtifact).toHaveBeenCalledWith(
123,
expect.anything()
)
expect(artifact.downloadArtifact).toHaveBeenCalledWith(
456,
expect.anything()
)
})
test('warns when some artifact IDs are not found', async () => {
const mockArtifacts = [
{id: 123, name: 'artifact1', size: 1024, digest: 'abc123'}
]
mockInputs({
[Inputs.Name]: '',
[Inputs.ArtifactIds]: '123, 456, 789'
})
jest
.spyOn(artifact, 'listArtifacts')
.mockImplementation(() => Promise.resolve({artifacts: mockArtifacts}))
await run()
expect(core.warning).toHaveBeenCalledWith(
'Could not find the following artifact IDs: 456, 789'
)
expect(artifact.downloadArtifact).toHaveBeenCalledTimes(1)
expect(artifact.downloadArtifact).toHaveBeenCalledWith(
123,
expect.anything()
)
})
test('throws error when none of the provided artifact IDs are found', async () => {
const mockArtifacts = [
{id: 999, name: 'other-artifact', size: 1024, digest: 'xyz999'}
]
mockInputs({
[Inputs.Name]: '',
[Inputs.ArtifactIds]: '123, 456'
})
jest
.spyOn(artifact, 'listArtifacts')
.mockImplementation(() => Promise.resolve({artifacts: mockArtifacts}))
await expect(run()).rejects.toThrow(
'None of the provided artifact IDs were found'
)
})
}) })

View File

@ -109,15 +109,44 @@ export async function run(): Promise<void> {
return numericId return numericId
}) })
// We need to fetch all artifacts to get metadata for the specified IDs // if the length of artifactIds exactly 1 fetch the latest artifact by its name and check the ID
const listArtifactResponse = await artifactClient.listArtifacts({ if (artifactIds.length === 1) {
latest: true, core.debug(
...options `Only one artifact ID provided. Fetching latest artifact by its name and checking the ID`
}) )
const getArtifactResponse = await artifactClient.getArtifact(
inputs.name,
{...options}
)
artifacts = listArtifactResponse.artifacts.filter(artifact => if (!getArtifactResponse || !getArtifactResponse.artifact) {
artifactIds.includes(artifact.id) throw new Error(
) `Artifact with ID '${artifactIds[0]}' not found. Please check the ID.`
)
}
const artifact = getArtifactResponse.artifact
core.debug(
`Found artifact by ID '${artifact.name}' (ID: ${artifact.id}, Size: ${artifact.size})`
)
artifacts = [artifact]
} else {
core.info(
`Multiple artifact IDs provided. Fetching all artifacts to filter by ID`
)
// We need to fetch all artifacts to get metadata for the specified IDs
const listArtifactResponse = await artifactClient.listArtifacts({
latest: true,
...options
})
artifacts = listArtifactResponse.artifacts.filter(artifact =>
artifactIds.includes(artifact.id)
)
}
if (artifacts.length === 0) { if (artifacts.length === 0) {
throw new Error(`None of the provided artifact IDs were found`) throw new Error(`None of the provided artifact IDs were found`)