From bacb5b323b6fdda6fb3dff332f8a01991a045831 Mon Sep 17 00:00:00 2001 From: charlie4284 Date: Tue, 26 Mar 2024 21:41:22 +0900 Subject: [PATCH] retry upload artifact --- dist/merge/index.js | 49 ++++++++++++++++------ dist/upload/index.js | 70 ++++++++++++++++--------------- src/shared/upload-artifact.ts | 77 +++++++++++++++++++++++++++-------- src/upload/upload-artifact.ts | 26 ++---------- 4 files changed, 139 insertions(+), 83 deletions(-) diff --git a/dist/merge/index.js b/dist/merge/index.js index 64b7b97..51dc340 100644 --- a/dist/merge/index.js +++ b/dist/merge/index.js @@ -129842,23 +129842,48 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.uploadArtifact = void 0; const core = __importStar(__nccwpck_require__(42186)); const github = __importStar(__nccwpck_require__(95438)); -const artifact_1 = __importDefault(__nccwpck_require__(79450)); -function uploadArtifact(artifactName, filesToUpload, rootDirectory, options) { +const artifact_1 = __importStar(__nccwpck_require__(79450)); +function deleteArtifactIfExists(artifactName) { return __awaiter(this, void 0, void 0, function* () { - const uploadResponse = yield artifact_1.default.uploadArtifact(artifactName, filesToUpload, rootDirectory, options); - core.info(`Artifact ${artifactName} has been successfully uploaded! Final size is ${uploadResponse.size} bytes. Artifact ID is ${uploadResponse.id}`); - core.setOutput('artifact-id', uploadResponse.id); - const repository = github.context.repo; - const artifactURL = `${github.context.serverUrl}/${repository.owner}/${repository.repo}/actions/runs/${github.context.runId}/artifacts/${uploadResponse.id}`; - core.info(`Artifact download URL: ${artifactURL}`); - core.setOutput('artifact-url', artifactURL); + try { + yield artifact_1.default.deleteArtifact(artifactName); + } + catch (error) { + if (error instanceof artifact_1.ArtifactNotFoundError) { + core.debug(`Skipping deletion of '${artifactName}', it does not exist`); + return; + } + // Best effort, we don't want to fail the action if this fails + core.debug(`Unable to delete artifact: ${error.message}`); + } + }); +} +function uploadArtifact(artifactName, filesToUpload, rootDirectory, options, overwrite = false, retryAttempts = 3) { + return __awaiter(this, void 0, void 0, function* () { + try { + if (overwrite) { + yield deleteArtifactIfExists(artifactName); + } + const uploadResponse = yield artifact_1.default.uploadArtifact(artifactName, filesToUpload, rootDirectory, options); + core.info(`Artifact ${artifactName} has been successfully uploaded! Final size is ${uploadResponse.size} bytes. Artifact ID is ${uploadResponse.id}`); + core.setOutput('artifact-id', uploadResponse.id); + const repository = github.context.repo; + const artifactURL = `${github.context.serverUrl}/${repository.owner}/${repository.repo}/actions/runs/${github.context.runId}/artifacts/${uploadResponse.id}`; + core.info(`Artifact download URL: ${artifactURL}`); + core.setOutput('artifact-url', artifactURL); + } + catch (error) { + if (error instanceof artifact_1.InvalidResponseError && + error.message.includes('Conflict: an artifact with this name already exists on the workflow run') && + overwrite && + retryAttempts) { + uploadArtifact(artifactName, filesToUpload, rootDirectory, options, overwrite, retryAttempts - 1); + } + } }); } exports.uploadArtifact = uploadArtifact; diff --git a/dist/upload/index.js b/dist/upload/index.js index 3b3b208..43aa58e 100644 --- a/dist/upload/index.js +++ b/dist/upload/index.js @@ -129600,23 +129600,48 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.uploadArtifact = void 0; const core = __importStar(__nccwpck_require__(42186)); const github = __importStar(__nccwpck_require__(95438)); -const artifact_1 = __importDefault(__nccwpck_require__(79450)); -function uploadArtifact(artifactName, filesToUpload, rootDirectory, options) { +const artifact_1 = __importStar(__nccwpck_require__(79450)); +function deleteArtifactIfExists(artifactName) { return __awaiter(this, void 0, void 0, function* () { - const uploadResponse = yield artifact_1.default.uploadArtifact(artifactName, filesToUpload, rootDirectory, options); - core.info(`Artifact ${artifactName} has been successfully uploaded! Final size is ${uploadResponse.size} bytes. Artifact ID is ${uploadResponse.id}`); - core.setOutput('artifact-id', uploadResponse.id); - const repository = github.context.repo; - const artifactURL = `${github.context.serverUrl}/${repository.owner}/${repository.repo}/actions/runs/${github.context.runId}/artifacts/${uploadResponse.id}`; - core.info(`Artifact download URL: ${artifactURL}`); - core.setOutput('artifact-url', artifactURL); + try { + yield artifact_1.default.deleteArtifact(artifactName); + } + catch (error) { + if (error instanceof artifact_1.ArtifactNotFoundError) { + core.debug(`Skipping deletion of '${artifactName}', it does not exist`); + return; + } + // Best effort, we don't want to fail the action if this fails + core.debug(`Unable to delete artifact: ${error.message}`); + } + }); +} +function uploadArtifact(artifactName, filesToUpload, rootDirectory, options, overwrite = false, retryAttempts = 3) { + return __awaiter(this, void 0, void 0, function* () { + try { + if (overwrite) { + yield deleteArtifactIfExists(artifactName); + } + const uploadResponse = yield artifact_1.default.uploadArtifact(artifactName, filesToUpload, rootDirectory, options); + core.info(`Artifact ${artifactName} has been successfully uploaded! Final size is ${uploadResponse.size} bytes. Artifact ID is ${uploadResponse.id}`); + core.setOutput('artifact-id', uploadResponse.id); + const repository = github.context.repo; + const artifactURL = `${github.context.serverUrl}/${repository.owner}/${repository.repo}/actions/runs/${github.context.runId}/artifacts/${uploadResponse.id}`; + core.info(`Artifact download URL: ${artifactURL}`); + core.setOutput('artifact-url', artifactURL); + } + catch (error) { + if (error instanceof artifact_1.InvalidResponseError && + error.message.includes('Conflict: an artifact with this name already exists on the workflow run') && + overwrite && + retryAttempts) { + uploadArtifact(artifactName, filesToUpload, rootDirectory, options, overwrite, retryAttempts - 1); + } + } }); } exports.uploadArtifact = uploadArtifact; @@ -129812,26 +129837,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge Object.defineProperty(exports, "__esModule", ({ value: true })); exports.run = void 0; const core = __importStar(__nccwpck_require__(42186)); -const artifact_1 = __importStar(__nccwpck_require__(79450)); const search_1 = __nccwpck_require__(8725); const input_helper_1 = __nccwpck_require__(67022); const constants_1 = __nccwpck_require__(86154); const upload_artifact_1 = __nccwpck_require__(56680); -function deleteArtifactIfExists(artifactName) { - return __awaiter(this, void 0, void 0, function* () { - try { - yield artifact_1.default.deleteArtifact(artifactName); - } - catch (error) { - if (error instanceof artifact_1.ArtifactNotFoundError) { - core.debug(`Skipping deletion of '${artifactName}', it does not exist`); - return; - } - // Best effort, we don't want to fail the action if this fails - core.debug(`Unable to delete artifact: ${error.message}`); - } - }); -} function run() { return __awaiter(this, void 0, void 0, function* () { const inputs = (0, input_helper_1.getInputs)(); @@ -129857,9 +129866,6 @@ function run() { const s = searchResult.filesToUpload.length === 1 ? '' : 's'; core.info(`With the provided path, there will be ${searchResult.filesToUpload.length} file${s} uploaded`); core.debug(`Root artifact directory is ${searchResult.rootDirectory}`); - if (inputs.overwrite) { - yield deleteArtifactIfExists(inputs.artifactName); - } const options = {}; if (inputs.retentionDays) { options.retentionDays = inputs.retentionDays; @@ -129867,7 +129873,7 @@ function run() { if (typeof inputs.compressionLevel !== 'undefined') { options.compressionLevel = inputs.compressionLevel; } - yield (0, upload_artifact_1.uploadArtifact)(inputs.artifactName, searchResult.filesToUpload, searchResult.rootDirectory, options); + yield (0, upload_artifact_1.uploadArtifact)(inputs.artifactName, searchResult.filesToUpload, searchResult.rootDirectory, options, inputs.overwrite); } }); } diff --git a/src/shared/upload-artifact.ts b/src/shared/upload-artifact.ts index e8ece24..ad9704f 100644 --- a/src/shared/upload-artifact.ts +++ b/src/shared/upload-artifact.ts @@ -1,28 +1,73 @@ import * as core from '@actions/core' import * as github from '@actions/github' -import artifact, {UploadArtifactOptions} from '@actions/artifact' +import artifact, { + UploadArtifactOptions, + ArtifactNotFoundError, + InvalidResponseError +} from '@actions/artifact' +import {UploadInputs} from '../upload/upload-inputs' +import {MergeInputs} from '../merge/merge-inputs' + +async function deleteArtifactIfExists(artifactName: string): Promise { + try { + await artifact.deleteArtifact(artifactName) + } catch (error) { + if (error instanceof ArtifactNotFoundError) { + core.debug(`Skipping deletion of '${artifactName}', it does not exist`) + return + } + + // Best effort, we don't want to fail the action if this fails + core.debug(`Unable to delete artifact: ${(error as Error).message}`) + } +} export async function uploadArtifact( artifactName: string, filesToUpload: string[], rootDirectory: string, - options: UploadArtifactOptions + options: UploadArtifactOptions, + overwrite: boolean = false, + retryAttempts: number = 3 ) { - const uploadResponse = await artifact.uploadArtifact( - artifactName, - filesToUpload, - rootDirectory, - options - ) + try { + if (overwrite) { + await deleteArtifactIfExists(artifactName) + } + const uploadResponse = await artifact.uploadArtifact( + artifactName, + filesToUpload, + rootDirectory, + options + ) - core.info( - `Artifact ${artifactName} has been successfully uploaded! Final size is ${uploadResponse.size} bytes. Artifact ID is ${uploadResponse.id}` - ) - core.setOutput('artifact-id', uploadResponse.id) + core.info( + `Artifact ${artifactName} has been successfully uploaded! Final size is ${uploadResponse.size} bytes. Artifact ID is ${uploadResponse.id}` + ) + core.setOutput('artifact-id', uploadResponse.id) - const repository = github.context.repo - const artifactURL = `${github.context.serverUrl}/${repository.owner}/${repository.repo}/actions/runs/${github.context.runId}/artifacts/${uploadResponse.id}` + const repository = github.context.repo + const artifactURL = `${github.context.serverUrl}/${repository.owner}/${repository.repo}/actions/runs/${github.context.runId}/artifacts/${uploadResponse.id}` - core.info(`Artifact download URL: ${artifactURL}`) - core.setOutput('artifact-url', artifactURL) + core.info(`Artifact download URL: ${artifactURL}`) + core.setOutput('artifact-url', artifactURL) + } catch (error) { + if ( + error instanceof InvalidResponseError && + error.message.includes( + 'Conflict: an artifact with this name already exists on the workflow run' + ) && + overwrite && + retryAttempts + ) { + uploadArtifact( + artifactName, + filesToUpload, + rootDirectory, + options, + overwrite, + retryAttempts - 1 + ) + } + } } diff --git a/src/upload/upload-artifact.ts b/src/upload/upload-artifact.ts index 8c77543..59f1f71 100644 --- a/src/upload/upload-artifact.ts +++ b/src/upload/upload-artifact.ts @@ -1,27 +1,10 @@ import * as core from '@actions/core' -import artifact, { - UploadArtifactOptions, - ArtifactNotFoundError -} from '@actions/artifact' +import {UploadArtifactOptions} from '@actions/artifact' import {findFilesToUpload} from '../shared/search' import {getInputs} from './input-helper' import {NoFileOptions} from './constants' import {uploadArtifact} from '../shared/upload-artifact' -async function deleteArtifactIfExists(artifactName: string): Promise { - try { - await artifact.deleteArtifact(artifactName) - } catch (error) { - if (error instanceof ArtifactNotFoundError) { - core.debug(`Skipping deletion of '${artifactName}', it does not exist`) - return - } - - // Best effort, we don't want to fail the action if this fails - core.debug(`Unable to delete artifact: ${(error as Error).message}`) - } -} - export async function run(): Promise { const inputs = getInputs() const searchResult = await findFilesToUpload(inputs.searchPath) @@ -54,10 +37,6 @@ export async function run(): Promise { ) core.debug(`Root artifact directory is ${searchResult.rootDirectory}`) - if (inputs.overwrite) { - await deleteArtifactIfExists(inputs.artifactName) - } - const options: UploadArtifactOptions = {} if (inputs.retentionDays) { options.retentionDays = inputs.retentionDays @@ -71,7 +50,8 @@ export async function run(): Promise { inputs.artifactName, searchResult.filesToUpload, searchResult.rootDirectory, - options + options, + inputs.overwrite ) } }