176 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			176 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | import * as core from '@actions/core' | ||
|  | import artifact from '@actions/artifact' | ||
|  | import {run} from '../src/merge/merge-artifacts' | ||
|  | 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.Name]: '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) | ||
|  |     } | ||
|  |   }) | ||
|  | }) |