mirror of
https://github.com/actions/upload-artifact
synced 2024-12-22 14:32:44 +00:00
add tests for merge artifact
This commit is contained in:
parent
fd1ae7b288
commit
d5febab9d6
2 changed files with 245 additions and 78 deletions
175
__tests__/merge.test.ts
Normal file
175
__tests__/merge.test.ts
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import artifact from '@actions/artifact'
|
||||||
|
import {run} from '../src/merge/merge-artifact'
|
||||||
|
import {Inputs} from '../src/merge/constants'
|
||||||
|
import * as search from '../src/shared/search'
|
||||||
|
|
||||||
|
const fixtures = {
|
||||||
|
artifactName: 'my-merged-artifact',
|
||||||
|
tmpDirectory: '/tmp/merge-artifact',
|
||||||
|
filesToUpload: [
|
||||||
|
'/some/artifact/path/file-a.txt',
|
||||||
|
'/some/artifact/path/file-b.txt',
|
||||||
|
'/some/artifact/path/file-c.txt'
|
||||||
|
],
|
||||||
|
artifacts: [
|
||||||
|
{
|
||||||
|
name: 'my-artifact-a',
|
||||||
|
id: 1,
|
||||||
|
size: 100,
|
||||||
|
createdAt: new Date('2024-01-01T00:00:00Z')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'my-artifact-b',
|
||||||
|
id: 2,
|
||||||
|
size: 100,
|
||||||
|
createdAt: new Date('2024-01-01T00:00:00Z')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'my-artifact-c',
|
||||||
|
id: 3,
|
||||||
|
size: 100,
|
||||||
|
createdAt: new Date('2024-01-01T00:00:00Z')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
jest.mock('@actions/github', () => ({
|
||||||
|
context: {
|
||||||
|
repo: {
|
||||||
|
owner: 'actions',
|
||||||
|
repo: 'toolkit'
|
||||||
|
},
|
||||||
|
runId: 123,
|
||||||
|
serverUrl: 'https://github.com'
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
jest.mock('@actions/core')
|
||||||
|
|
||||||
|
jest.mock('fs/promises', () => ({
|
||||||
|
mkdtemp: jest.fn().mockResolvedValue('/tmp/merge-artifact'),
|
||||||
|
rm: jest.fn().mockResolvedValue(undefined)
|
||||||
|
}))
|
||||||
|
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
|
||||||
|
const inputs = {
|
||||||
|
[Inputs.Into]: 'my-merged-artifact',
|
||||||
|
[Inputs.Pattern]: '*',
|
||||||
|
[Inputs.SeparateDirectories]: false,
|
||||||
|
[Inputs.RetentionDays]: 0,
|
||||||
|
[Inputs.CompressionLevel]: 6,
|
||||||
|
[Inputs.DeleteMerged]: false,
|
||||||
|
...overrides
|
||||||
|
}
|
||||||
|
|
||||||
|
;(core.getInput as jest.Mock).mockImplementation((name: string) => {
|
||||||
|
return inputs[name]
|
||||||
|
})
|
||||||
|
;(core.getBooleanInput as jest.Mock).mockImplementation((name: string) => {
|
||||||
|
return inputs[name]
|
||||||
|
})
|
||||||
|
|
||||||
|
return inputs
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('merge', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockInputs()
|
||||||
|
|
||||||
|
jest
|
||||||
|
.spyOn(artifact, 'listArtifacts')
|
||||||
|
.mockResolvedValue({artifacts: fixtures.artifacts})
|
||||||
|
|
||||||
|
jest.spyOn(artifact, 'downloadArtifact').mockResolvedValue({
|
||||||
|
downloadPath: fixtures.tmpDirectory
|
||||||
|
})
|
||||||
|
|
||||||
|
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
|
||||||
|
filesToUpload: fixtures.filesToUpload,
|
||||||
|
rootDirectory: fixtures.tmpDirectory
|
||||||
|
})
|
||||||
|
|
||||||
|
jest.spyOn(artifact, 'uploadArtifact').mockResolvedValue({
|
||||||
|
size: 123,
|
||||||
|
id: 1337
|
||||||
|
})
|
||||||
|
|
||||||
|
jest
|
||||||
|
.spyOn(artifact, 'deleteArtifact')
|
||||||
|
.mockImplementation(async artifactName => {
|
||||||
|
const artifact = fixtures.artifacts.find(a => a.name === artifactName)
|
||||||
|
if (!artifact) throw new Error(`Artifact ${artifactName} not found`)
|
||||||
|
return {id: artifact.id}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('merges artifacts', async () => {
|
||||||
|
await run()
|
||||||
|
|
||||||
|
for (const a of fixtures.artifacts) {
|
||||||
|
expect(artifact.downloadArtifact).toHaveBeenCalledWith(a.id, {
|
||||||
|
path: fixtures.tmpDirectory
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
||||||
|
fixtures.artifactName,
|
||||||
|
fixtures.filesToUpload,
|
||||||
|
fixtures.tmpDirectory,
|
||||||
|
{compressionLevel: 6}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('fails if no artifacts found', async () => {
|
||||||
|
mockInputs({[Inputs.Pattern]: 'this-does-not-match'})
|
||||||
|
|
||||||
|
expect(run()).rejects.toThrow()
|
||||||
|
|
||||||
|
expect(artifact.uploadArtifact).not.toBeCalled()
|
||||||
|
expect(artifact.downloadArtifact).not.toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('supports custom compression level', async () => {
|
||||||
|
mockInputs({
|
||||||
|
[Inputs.CompressionLevel]: 2
|
||||||
|
})
|
||||||
|
|
||||||
|
await run()
|
||||||
|
|
||||||
|
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
||||||
|
fixtures.artifactName,
|
||||||
|
fixtures.filesToUpload,
|
||||||
|
fixtures.tmpDirectory,
|
||||||
|
{compressionLevel: 2}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('supports custom retention days', async () => {
|
||||||
|
mockInputs({
|
||||||
|
[Inputs.RetentionDays]: 7
|
||||||
|
})
|
||||||
|
|
||||||
|
await run()
|
||||||
|
|
||||||
|
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
|
||||||
|
fixtures.artifactName,
|
||||||
|
fixtures.filesToUpload,
|
||||||
|
fixtures.tmpDirectory,
|
||||||
|
{retentionDays: 7, compressionLevel: 6}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('supports deleting artifacts after merge', async () => {
|
||||||
|
mockInputs({
|
||||||
|
[Inputs.DeleteMerged]: true
|
||||||
|
})
|
||||||
|
|
||||||
|
await run()
|
||||||
|
|
||||||
|
for (const a of fixtures.artifacts) {
|
||||||
|
expect(artifact.deleteArtifact).toHaveBeenCalledWith(a.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
|
@ -17,7 +17,6 @@ export const chunk = <T>(arr: T[], n: number): T[][] =>
|
||||||
}, [] as T[][])
|
}, [] as T[][])
|
||||||
|
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
try {
|
|
||||||
const inputs = getInputs()
|
const inputs = getInputs()
|
||||||
const tmpDir = await mkdtemp('merge-artifact')
|
const tmpDir = await mkdtemp('merge-artifact')
|
||||||
|
|
||||||
|
@ -38,9 +37,7 @@ export async function run(): Promise<void> {
|
||||||
|
|
||||||
core.info(`Preparing to download the following artifacts:`)
|
core.info(`Preparing to download the following artifacts:`)
|
||||||
artifacts.forEach(artifact => {
|
artifacts.forEach(artifact => {
|
||||||
core.info(
|
core.info(`- ${artifact.name} (ID: ${artifact.id}, Size: ${artifact.size})`)
|
||||||
`- ${artifact.name} (ID: ${artifact.id}, Size: ${artifact.size})`
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const downloadPromises = artifacts.map(artifact =>
|
const downloadPromises = artifacts.map(artifact =>
|
||||||
|
@ -93,9 +90,4 @@ export async function run(): Promise<void> {
|
||||||
`Unable to remove temporary directory: ${(error as Error).message}`
|
`Unable to remove temporary directory: ${(error as Error).message}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
core.setFailed((error as Error).message)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run()
|
|
||||||
|
|
Loading…
Reference in a new issue