1
0
Fork 0
toolkit/packages/artifact/src/internal/upload/upload-artifact.ts

158 lines
4.8 KiB
TypeScript

import * as core from '@actions/core'
import {
UploadArtifactOptions,
UploadArtifactResponse
} from '../shared/interfaces'
import {getExpiration} from './retention'
import {validateArtifactName} from './path-and-artifact-name-validation'
import {internalArtifactTwirpClient} from '../shared/artifact-twirp-client'
import {
UploadZipSpecification,
getUploadZipSpecification,
validateRootDirectory
} from './upload-zip-specification'
import {getBackendIdsFromToken} from '../shared/util'
import {uploadZipToBlobStorage} from './blob-upload'
import {createZipUploadStream} from './zip'
import {
CreateArtifactRequest,
FinalizeArtifactRequest,
StringValue
} from '../../generated'
import {FilesNotFoundError, InvalidResponseError} from '../shared/errors'
export async function uploadArtifact(
name: string,
files: string[],
rootDirectory: string,
options?: UploadArtifactOptions | undefined
): Promise<UploadArtifactResponse> {
validateArtifactName(name)
validateRootDirectory(rootDirectory)
const zipSpecification: UploadZipSpecification[] = getUploadZipSpecification(
files,
rootDirectory
)
if (zipSpecification.length === 0) {
throw new FilesNotFoundError(
zipSpecification.flatMap(s => (s.sourcePath ? [s.sourcePath] : []))
)
}
// get the IDs needed for the artifact creation
const backendIds = getBackendIdsFromToken()
// create the artifact client
const artifactClient = internalArtifactTwirpClient()
// create the artifact
const createArtifactReq: CreateArtifactRequest = {
workflowRunBackendId: backendIds.workflowRunBackendId,
workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
name,
version: 4
}
// if there is a retention period, add it to the request
const expiresAt = getExpiration(options?.retentionDays)
if (expiresAt) {
createArtifactReq.expiresAt = expiresAt
}
const createArtifactResp =
await artifactClient.CreateArtifact(createArtifactReq)
if (!createArtifactResp.ok) {
throw new InvalidResponseError(
'CreateArtifact: response from backend was not ok'
)
}
return createZipUploadStream(zipSpecification, options?.compressionLevel)
.then(async zipUploadStream => {
core.info(`starting upload to blob here`)
core.info(`zipuploadstream looks like this: ${zipUploadStream}`)
return uploadZipToBlobStorage(
createArtifactResp.signedUploadUrl,
zipUploadStream
)
})
.then(async uploadResult => {
const finalizeArtifactReq: FinalizeArtifactRequest = {
workflowRunBackendId: backendIds.workflowRunBackendId,
workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
name,
size: uploadResult.uploadSize ? uploadResult.uploadSize.toString() : '0'
}
if (uploadResult.sha256Hash) {
finalizeArtifactReq.hash = StringValue.create({
value: `sha256:${uploadResult.sha256Hash}`
})
}
core.info(`Finalizing artifact upload`)
const finalizeArtifactResp =
await artifactClient.FinalizeArtifact(finalizeArtifactReq)
return {finalizeArtifactResp, uploadResult}
})
.then(({finalizeArtifactResp, uploadResult}) => {
if (!finalizeArtifactResp.ok) {
throw new InvalidResponseError(
'FinalizeArtifact: response from backend was not ok'
)
}
const artifactId = BigInt(finalizeArtifactResp.artifactId)
core.info(
`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`
)
return {
size: uploadResult.uploadSize,
id: Number(artifactId)
}
})
// // Upload zip to blob storage
// const uploadResult = await uploadZipToBlobStorage(
// createArtifactResp.signedUploadUrl,
// zipUploadStream
// )
// finalize the artifact
// const finalizeArtifactReq: FinalizeArtifactRequest = {
// workflowRunBackendId: backendIds.workflowRunBackendId,
// workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
// name,
// size: uploadResult.uploadSize ? uploadResult.uploadSize.toString() : '0'
// }
// if (uploadResult.sha256Hash) {
// finalizeArtifactReq.hash = StringValue.create({
// value: `sha256:${uploadResult.sha256Hash}`
// })
// }
//
// core.info(`Finalizing artifact upload`)
// const finalizeArtifactResp =
// await artifactClient.FinalizeArtifact(finalizeArtifactReq)
// if (!finalizeArtifactResp.ok) {
// throw new InvalidResponseError(
// 'FinalizeArtifact: response from backend was not ok'
// )
// }
// const artifactId = BigInt(finalizeArtifactResp.artifactId)
// core.info(
// `Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`
// )
// if (core.isDebug()) {
// setTimeout(function () {
// core.debug('Processes keeping upload stream running:')
// whyIsNodeRunning()
// }, 500)
// }
//
// )
}