2023-08-04 09:53:42 -04:00
|
|
|
import * as core from '@actions/core'
|
2023-08-17 14:40:33 -04:00
|
|
|
import {UploadOptions, UploadResponse} from '../shared/interfaces'
|
2023-08-09 17:50:46 -07:00
|
|
|
import {getExpiration} from './retention'
|
2023-08-04 09:53:42 -04:00
|
|
|
import {validateArtifactName} from './path-and-artifact-name-validation'
|
2023-08-09 11:26:33 -07:00
|
|
|
import {createArtifactTwirpClient} from '../shared/artifact-twirp-client'
|
2023-08-04 09:53:42 -04:00
|
|
|
import {
|
|
|
|
|
UploadZipSpecification,
|
|
|
|
|
getUploadZipSpecification,
|
|
|
|
|
validateRootDirectory
|
|
|
|
|
} from './upload-zip-specification'
|
2023-08-09 13:12:30 -07:00
|
|
|
import {getBackendIdsFromToken} from '../shared/util'
|
2023-08-10 15:28:41 -04:00
|
|
|
import {uploadZipToBlobStorage} from './blob-upload'
|
|
|
|
|
import {createZipUploadStream} from './zip'
|
2023-08-15 13:39:57 -04:00
|
|
|
import {
|
|
|
|
|
CreateArtifactRequest,
|
|
|
|
|
FinalizeArtifactRequest,
|
|
|
|
|
StringValue
|
|
|
|
|
} from '../../generated'
|
2023-08-03 13:34:41 -04:00
|
|
|
|
|
|
|
|
export async function uploadArtifact(
|
|
|
|
|
name: string,
|
2023-08-04 09:53:42 -04:00
|
|
|
files: string[],
|
|
|
|
|
rootDirectory: string,
|
2023-08-09 12:08:43 -07:00
|
|
|
options?: UploadOptions | undefined
|
2023-08-03 13:34:41 -04:00
|
|
|
): Promise<UploadResponse> {
|
2023-08-09 12:08:43 -07:00
|
|
|
validateArtifactName(name)
|
|
|
|
|
validateRootDirectory(rootDirectory)
|
2023-08-04 09:53:42 -04:00
|
|
|
|
|
|
|
|
const zipSpecification: UploadZipSpecification[] = getUploadZipSpecification(
|
|
|
|
|
files,
|
|
|
|
|
rootDirectory
|
|
|
|
|
)
|
|
|
|
|
if (zipSpecification.length === 0) {
|
|
|
|
|
core.warning(`No files were found to upload`)
|
|
|
|
|
return {
|
|
|
|
|
success: false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-20 16:46:08 +00:00
|
|
|
const zipUploadStream = await createZipUploadStream(
|
|
|
|
|
zipSpecification,
|
|
|
|
|
options?.compressionLevel
|
|
|
|
|
)
|
2023-08-10 15:28:41 -04:00
|
|
|
|
2023-08-09 11:26:33 -07:00
|
|
|
// get the IDs needed for the artifact creation
|
2023-08-09 12:08:43 -07:00
|
|
|
const backendIds = getBackendIdsFromToken()
|
2023-08-09 11:26:33 -07:00
|
|
|
if (!backendIds.workflowRunBackendId || !backendIds.workflowJobRunBackendId) {
|
2023-08-15 13:39:57 -04:00
|
|
|
core.warning(
|
|
|
|
|
`Failed to get the necessary backend ids which are required to create the artifact`
|
|
|
|
|
)
|
2023-08-09 11:26:33 -07:00
|
|
|
return {
|
|
|
|
|
success: false
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-09 17:42:14 -07:00
|
|
|
core.debug(`Workflow Run Backend ID: ${backendIds.workflowRunBackendId}`)
|
|
|
|
|
core.debug(
|
|
|
|
|
`Workflow Job Run Backend ID: ${backendIds.workflowJobRunBackendId}`
|
|
|
|
|
)
|
2023-08-09 11:26:33 -07:00
|
|
|
|
|
|
|
|
// create the artifact client
|
|
|
|
|
const artifactClient = createArtifactTwirpClient('upload')
|
|
|
|
|
|
|
|
|
|
// create the artifact
|
|
|
|
|
const createArtifactReq: CreateArtifactRequest = {
|
|
|
|
|
workflowRunBackendId: backendIds.workflowRunBackendId,
|
|
|
|
|
workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
|
2023-08-22 10:06:40 -07:00
|
|
|
name,
|
2023-08-09 11:26:33 -07:00
|
|
|
version: 4
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if there is a retention period, add it to the request
|
|
|
|
|
const expiresAt = getExpiration(options?.retentionDays)
|
|
|
|
|
if (expiresAt) {
|
|
|
|
|
createArtifactReq.expiresAt = expiresAt
|
|
|
|
|
}
|
2023-08-09 12:08:43 -07:00
|
|
|
|
2023-09-08 14:29:27 +00:00
|
|
|
const createArtifactResp =
|
|
|
|
|
await artifactClient.CreateArtifact(createArtifactReq)
|
2023-08-09 12:08:43 -07:00
|
|
|
if (!createArtifactResp.ok) {
|
2023-08-09 11:26:33 -07:00
|
|
|
core.warning(`Failed to create artifact`)
|
|
|
|
|
return {
|
|
|
|
|
success: false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 15:28:41 -04:00
|
|
|
// Upload zip to blob storage
|
2023-08-15 13:39:57 -04:00
|
|
|
const uploadResult = await uploadZipToBlobStorage(
|
|
|
|
|
createArtifactResp.signedUploadUrl,
|
|
|
|
|
zipUploadStream
|
|
|
|
|
)
|
2023-08-10 15:28:41 -04:00
|
|
|
if (uploadResult.isSuccess === false) {
|
|
|
|
|
return {
|
|
|
|
|
success: false
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-03 13:34:41 -04:00
|
|
|
|
2023-08-09 11:26:33 -07:00
|
|
|
// finalize the artifact
|
2023-08-15 13:39:57 -04:00
|
|
|
const finalizeArtifactReq: FinalizeArtifactRequest = {
|
2023-08-09 12:09:17 -07:00
|
|
|
workflowRunBackendId: backendIds.workflowRunBackendId,
|
|
|
|
|
workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
|
2023-08-22 10:06:40 -07:00
|
|
|
name,
|
2023-08-23 07:28:17 -07:00
|
|
|
size: uploadResult.uploadSize ? uploadResult.uploadSize.toString() : '0'
|
2023-08-15 13:39:57 -04:00
|
|
|
}
|
|
|
|
|
|
2023-10-16 16:20:24 +00:00
|
|
|
if (uploadResult.sha256Hash) {
|
2023-08-15 13:39:57 -04:00
|
|
|
finalizeArtifactReq.hash = StringValue.create({
|
2023-10-16 16:20:24 +00:00
|
|
|
value: `sha256:${uploadResult.sha256Hash}`
|
2023-08-15 13:39:57 -04:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
core.info(`Finalizing artifact upload`)
|
|
|
|
|
|
2023-09-08 14:29:27 +00:00
|
|
|
const finalizeArtifactResp =
|
|
|
|
|
await artifactClient.FinalizeArtifact(finalizeArtifactReq)
|
2023-08-09 12:08:43 -07:00
|
|
|
if (!finalizeArtifactResp.ok) {
|
2023-08-09 11:26:33 -07:00
|
|
|
core.warning(`Failed to finalize artifact`)
|
|
|
|
|
return {
|
|
|
|
|
success: false
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-09 12:08:43 -07:00
|
|
|
|
2023-08-15 13:39:57 -04:00
|
|
|
const artifactId = BigInt(finalizeArtifactResp.artifactId)
|
|
|
|
|
core.info(
|
|
|
|
|
`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`
|
|
|
|
|
)
|
|
|
|
|
|
2023-08-10 15:28:41 -04:00
|
|
|
return {
|
2023-08-04 09:53:42 -04:00
|
|
|
success: true,
|
2023-08-10 15:28:41 -04:00
|
|
|
size: uploadResult.uploadSize,
|
2023-08-15 13:39:57 -04:00
|
|
|
id: Number(artifactId)
|
2023-08-03 13:34:41 -04:00
|
|
|
}
|
|
|
|
|
}
|