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 { 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) // } // // ) }