mirror of https://github.com/actions/toolkit
Include fs stats and mode in zip archive
parent
eb1cb3649c
commit
cce93c0202
|
@ -31,15 +31,18 @@ describe('upload-artifact', () => {
|
|||
.mockReturnValue([
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file1.txt',
|
||||
destinationPath: 'file1.txt'
|
||||
destinationPath: 'file1.txt',
|
||||
stats: new fs.Stats()
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file2.txt',
|
||||
destinationPath: 'file2.txt'
|
||||
destinationPath: 'file2.txt',
|
||||
stats: new fs.Stats()
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/dir/file3.txt',
|
||||
destinationPath: 'dir/file3.txt'
|
||||
destinationPath: 'dir/file3.txt',
|
||||
stats: new fs.Stats()
|
||||
}
|
||||
])
|
||||
|
||||
|
@ -139,15 +142,18 @@ describe('upload-artifact', () => {
|
|||
.mockReturnValue([
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file1.txt',
|
||||
destinationPath: 'file1.txt'
|
||||
destinationPath: 'file1.txt',
|
||||
stats: new fs.Stats()
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file2.txt',
|
||||
destinationPath: 'file2.txt'
|
||||
destinationPath: 'file2.txt',
|
||||
stats: new fs.Stats()
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/dir/file3.txt',
|
||||
destinationPath: 'dir/file3.txt'
|
||||
destinationPath: 'dir/file3.txt',
|
||||
stats: new fs.Stats()
|
||||
}
|
||||
])
|
||||
|
||||
|
@ -178,15 +184,18 @@ describe('upload-artifact', () => {
|
|||
.mockReturnValue([
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file1.txt',
|
||||
destinationPath: 'file1.txt'
|
||||
destinationPath: 'file1.txt',
|
||||
stats: fs.Stats.prototype
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file2.txt',
|
||||
destinationPath: 'file2.txt'
|
||||
destinationPath: 'file2.txt',
|
||||
stats: fs.Stats.prototype
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/dir/file3.txt',
|
||||
destinationPath: 'dir/file3.txt'
|
||||
destinationPath: 'dir/file3.txt',
|
||||
stats: fs.Stats.prototype
|
||||
}
|
||||
])
|
||||
|
||||
|
@ -233,15 +242,18 @@ describe('upload-artifact', () => {
|
|||
.mockReturnValue([
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file1.txt',
|
||||
destinationPath: 'file1.txt'
|
||||
destinationPath: 'file1.txt',
|
||||
stats: new fs.Stats()
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file2.txt',
|
||||
destinationPath: 'file2.txt'
|
||||
destinationPath: 'file2.txt',
|
||||
stats: new fs.Stats()
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/dir/file3.txt',
|
||||
destinationPath: 'dir/file3.txt'
|
||||
destinationPath: 'dir/file3.txt',
|
||||
stats: new fs.Stats()
|
||||
}
|
||||
])
|
||||
|
||||
|
@ -296,15 +308,18 @@ describe('upload-artifact', () => {
|
|||
.mockReturnValue([
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file1.txt',
|
||||
destinationPath: 'file1.txt'
|
||||
destinationPath: 'file1.txt',
|
||||
stats: new fs.Stats()
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/file2.txt',
|
||||
destinationPath: 'file2.txt'
|
||||
destinationPath: 'file2.txt',
|
||||
stats: new fs.Stats()
|
||||
},
|
||||
{
|
||||
sourcePath: '/home/user/files/plz-upload/dir/file3.txt',
|
||||
destinationPath: 'dir/file3.txt'
|
||||
destinationPath: 'dir/file3.txt',
|
||||
stats: new fs.Stats()
|
||||
}
|
||||
])
|
||||
|
||||
|
|
|
@ -5,14 +5,19 @@ import {validateFilePath} from './path-and-artifact-name-validation'
|
|||
|
||||
export interface UploadZipSpecification {
|
||||
/**
|
||||
* An absolute source path that points to a file that will be added to a zip. Null if creating a new directory
|
||||
* An absolute source path that points to a file or directory that will be added to a zip
|
||||
*/
|
||||
sourcePath: string | null
|
||||
sourcePath: string
|
||||
|
||||
/**
|
||||
* The destination path in a zip for a file
|
||||
*/
|
||||
destinationPath: string
|
||||
|
||||
/**
|
||||
* Metadata (permissions, creation time, etc) about the file
|
||||
*/
|
||||
stats: fs.Stats
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,37 +80,28 @@ export function getUploadZipSpecification(
|
|||
- file3.txt
|
||||
*/
|
||||
for (let file of filesToZip) {
|
||||
if (!fs.existsSync(file)) {
|
||||
const stats = fs.statSync(file, {throwIfNoEntry: false});
|
||||
if (!stats) {
|
||||
throw new Error(`File ${file} does not exist`)
|
||||
}
|
||||
if (!fs.statSync(file).isDirectory()) {
|
||||
// Normalize and resolve, this allows for either absolute or relative paths to be used
|
||||
file = normalize(file)
|
||||
file = resolve(file)
|
||||
if (!file.startsWith(rootDirectory)) {
|
||||
throw new Error(
|
||||
`The rootDirectory: ${rootDirectory} is not a parent directory of the file: ${file}`
|
||||
)
|
||||
}
|
||||
|
||||
// Check for forbidden characters in file paths that may cause ambiguous behavior if downloaded on different file systems
|
||||
const uploadPath = file.replace(rootDirectory, '')
|
||||
validateFilePath(uploadPath)
|
||||
|
||||
specification.push({
|
||||
sourcePath: file,
|
||||
destinationPath: uploadPath
|
||||
})
|
||||
} else {
|
||||
// Empty directory
|
||||
const directoryPath = file.replace(rootDirectory, '')
|
||||
validateFilePath(directoryPath)
|
||||
|
||||
specification.push({
|
||||
sourcePath: null,
|
||||
destinationPath: directoryPath
|
||||
})
|
||||
// Normalize and resolve, this allows for either absolute or relative paths to be used
|
||||
file = normalize(file)
|
||||
file = resolve(file)
|
||||
if (!file.startsWith(rootDirectory)) {
|
||||
throw new Error(
|
||||
`The rootDirectory: ${rootDirectory} is not a parent directory of the file: ${file}`
|
||||
)
|
||||
}
|
||||
|
||||
// Check for forbidden characters in file paths that may cause ambiguous behavior if downloaded on different file systems
|
||||
const destinationPath = file.replace(rootDirectory, '')
|
||||
validateFilePath(destinationPath)
|
||||
|
||||
specification.push({
|
||||
sourcePath: file,
|
||||
destinationPath,
|
||||
stats
|
||||
})
|
||||
}
|
||||
return specification
|
||||
}
|
||||
|
|
|
@ -42,14 +42,20 @@ export async function createZipUploadStream(
|
|||
zip.on('end', zipEndCallback)
|
||||
|
||||
for (const file of uploadSpecification) {
|
||||
if (file.sourcePath !== null) {
|
||||
if (!file.stats.isDirectory()) {
|
||||
// Add a normal file to the zip
|
||||
zip.append(createReadStream(file.sourcePath), {
|
||||
name: file.destinationPath
|
||||
name: file.destinationPath,
|
||||
stats: file.stats,
|
||||
mode: file.stats.mode
|
||||
})
|
||||
} else {
|
||||
// Add a directory to the zip
|
||||
zip.append('', {name: file.destinationPath})
|
||||
zip.append('', {
|
||||
name: file.destinationPath,
|
||||
stats: file.stats,
|
||||
mode: file.stats.mode
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue