| 
									
										
										
										
											2024-01-22 21:46:12 -05:00
										 |  |  | import * as path from 'path' | 
					
						
							|  |  |  | import {mkdtemp, rm} from 'fs/promises' | 
					
						
							|  |  |  | import * as core from '@actions/core' | 
					
						
							|  |  |  | import {Minimatch} from 'minimatch' | 
					
						
							|  |  |  | import artifactClient, {UploadArtifactOptions} from '@actions/artifact' | 
					
						
							|  |  |  | import {getInputs} from './input-helper' | 
					
						
							|  |  |  | import {uploadArtifact} from '../shared/upload-artifact' | 
					
						
							|  |  |  | import {findFilesToUpload} from '../shared/search' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const PARALLEL_DOWNLOADS = 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const chunk = <T>(arr: T[], n: number): T[][] => | 
					
						
							|  |  |  |   arr.reduce((acc, cur, i) => { | 
					
						
							|  |  |  |     const index = Math.floor(i / n) | 
					
						
							|  |  |  |     acc[index] = [...(acc[index] || []), cur] | 
					
						
							|  |  |  |     return acc | 
					
						
							|  |  |  |   }, [] as T[][]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export async function run(): Promise<void> { | 
					
						
							|  |  |  |   const inputs = getInputs() | 
					
						
							|  |  |  |   const tmpDir = await mkdtemp('merge-artifact') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const listArtifactResponse = await artifactClient.listArtifacts({ | 
					
						
							|  |  |  |     latest: true | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  |   const matcher = new Minimatch(inputs.pattern) | 
					
						
							|  |  |  |   const artifacts = listArtifactResponse.artifacts.filter(artifact => | 
					
						
							|  |  |  |     matcher.match(artifact.name) | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  |   core.debug( | 
					
						
							|  |  |  |     `Filtered from ${listArtifactResponse.artifacts.length} to ${artifacts.length} artifacts` | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (artifacts.length === 0) { | 
					
						
							|  |  |  |     throw new Error(`No artifacts found matching pattern '${inputs.pattern}'`) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   core.info(`Preparing to download the following artifacts:`) | 
					
						
							|  |  |  |   artifacts.forEach(artifact => { | 
					
						
							|  |  |  |     core.info(`- ${artifact.name} (ID: ${artifact.id}, Size: ${artifact.size})`) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const downloadPromises = artifacts.map(artifact => | 
					
						
							|  |  |  |     artifactClient.downloadArtifact(artifact.id, { | 
					
						
							|  |  |  |       path: inputs.separateDirectories | 
					
						
							|  |  |  |         ? path.join(tmpDir, artifact.name) | 
					
						
							|  |  |  |         : tmpDir | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const chunkedPromises = chunk(downloadPromises, PARALLEL_DOWNLOADS) | 
					
						
							|  |  |  |   for (const chunk of chunkedPromises) { | 
					
						
							|  |  |  |     await Promise.all(chunk) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const options: UploadArtifactOptions = {} | 
					
						
							|  |  |  |   if (inputs.retentionDays) { | 
					
						
							|  |  |  |     options.retentionDays = inputs.retentionDays | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (typeof inputs.compressionLevel !== 'undefined') { | 
					
						
							|  |  |  |     options.compressionLevel = inputs.compressionLevel | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 16:22:09 -04:00
										 |  |  |   const searchResult = await findFilesToUpload(tmpDir, inputs.includeHiddenFiles) | 
					
						
							| 
									
										
										
										
											2024-01-22 21:46:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await uploadArtifact( | 
					
						
							|  |  |  |     inputs.name, | 
					
						
							|  |  |  |     searchResult.filesToUpload, | 
					
						
							|  |  |  |     searchResult.rootDirectory, | 
					
						
							|  |  |  |     options | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   core.info( | 
					
						
							|  |  |  |     `The ${artifacts.length} artifact(s) have been successfully merged!` | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (inputs.deleteMerged) { | 
					
						
							|  |  |  |     const deletePromises = artifacts.map(artifact => | 
					
						
							|  |  |  |       artifactClient.deleteArtifact(artifact.name) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await Promise.all(deletePromises) | 
					
						
							|  |  |  |     core.info(`The ${artifacts.length} artifact(s) have been deleted`) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     await rm(tmpDir, {recursive: true}) | 
					
						
							|  |  |  |   } catch (error) { | 
					
						
							|  |  |  |     core.warning( | 
					
						
							|  |  |  |       `Unable to remove temporary directory: ${(error as Error).message}` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |