Artifact upload: support uploading single un-zipped files (#2256)
* Artifact upload: support uploading single un-zipped files * Fix linters * Fix lint again * Fix tests * Check for 0 sized artifact lists * Add some more stream tests and handle an upload failure gracefully * Add CI tests for non-zipped artifacts * Add an html report to test rendering in the browser * Fix linting issue * Artifact: bump the version and add release notes * Fix Windows tests * Fix linting * stream: switch the error details to error type * Refactor the validation logic in `uploadArtifact` a bit * Added more details about how the name parameter is handled
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import * as stream from 'stream'
|
||||
import * as fs from 'fs'
|
||||
import {realpath} from 'fs/promises'
|
||||
import * as core from '@actions/core'
|
||||
import {getUploadChunkSize} from '../shared/config.js'
|
||||
|
||||
// Custom stream transformer so we can set the highWaterMark property
|
||||
// See https://github.com/nodejs/node/issues/8855
|
||||
export class WaterMarkedUploadStream extends stream.Transform {
|
||||
constructor(bufferSize: number) {
|
||||
super({
|
||||
highWaterMark: bufferSize
|
||||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
_transform(chunk: any, enc: any, cb: any): void {
|
||||
cb(null, chunk)
|
||||
}
|
||||
}
|
||||
|
||||
export async function createRawFileUploadStream(
|
||||
filePath: string
|
||||
): Promise<WaterMarkedUploadStream> {
|
||||
core.debug(`Creating raw file upload stream for: ${filePath}`)
|
||||
|
||||
const bufferSize = getUploadChunkSize()
|
||||
const uploadStream = new WaterMarkedUploadStream(bufferSize)
|
||||
|
||||
// Check if symlink and resolve the source path
|
||||
let sourcePath = filePath
|
||||
const stats = await fs.promises.lstat(filePath)
|
||||
if (stats.isSymbolicLink()) {
|
||||
sourcePath = await realpath(filePath)
|
||||
}
|
||||
|
||||
// Create a read stream from the file and pipe it to the upload stream
|
||||
const fileStream = fs.createReadStream(sourcePath, {
|
||||
highWaterMark: bufferSize
|
||||
})
|
||||
|
||||
fileStream.on('error', error => {
|
||||
core.error('An error has occurred while reading the file for upload')
|
||||
core.error(String(error))
|
||||
uploadStream.destroy(
|
||||
new Error('An error has occurred during file read for the artifact')
|
||||
)
|
||||
})
|
||||
|
||||
fileStream.pipe(uploadStream)
|
||||
|
||||
return uploadStream
|
||||
}
|
||||
Reference in New Issue
Block a user