Files
release-action/src/ArtifactUploader.ts
2025-02-17 16:15:54 -05:00

65 lines
2.5 KiB
TypeScript

import * as core from "@actions/core"
import { Artifact } from "./Artifact"
import { Releases } from "./Releases"
export interface ArtifactUploader {
uploadArtifacts(artifacts: Artifact[], releaseId: number, uploadUrl: string): Promise<void>
}
export class GithubArtifactUploader implements ArtifactUploader {
constructor(
private releases: Releases,
private replacesExistingArtifacts: boolean = true,
private throwsUploadErrors: boolean = false
) {}
async uploadArtifacts(artifacts: Artifact[], releaseId: number, uploadUrl: string): Promise<void> {
if (this.replacesExistingArtifacts) {
await this.deleteUpdatedArtifacts(artifacts, releaseId)
}
for (const artifact of artifacts) {
await this.uploadArtifact(artifact, releaseId, uploadUrl)
}
}
private async uploadArtifact(artifact: Artifact, releaseId: number, uploadUrl: string, retry = 3) {
try {
core.debug(`Uploading artifact ${artifact.name}...`)
await this.releases.uploadArtifact(
uploadUrl,
artifact.contentLength,
artifact.contentType,
artifact.readFile(),
artifact.name,
releaseId
)
} catch (error: any) {
if (error.status >= 500 && retry > 0) {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}. Retrying...`)
await this.uploadArtifact(artifact, releaseId, uploadUrl, retry - 1)
} else {
if (this.throwsUploadErrors) {
throw Error(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
} else {
core.warning(`Failed to upload artifact ${artifact.name}. ${error.message}.`)
}
}
}
}
private async deleteUpdatedArtifacts(artifacts: Artifact[], releaseId: number): Promise<void> {
const releaseAssets = await this.releases.listArtifactsForRelease(releaseId)
const assetByName: Record<string, { id: number; name: string }> = {}
releaseAssets.forEach((asset) => {
assetByName[asset.name] = asset
})
for (const artifact of artifacts) {
const asset = assetByName[artifact.name]
if (asset) {
core.debug(`Deleting existing artifact ${artifact.name}...`)
await this.releases.deleteArtifact(asset.id)
}
}
}
}