mirror of https://github.com/actions/toolkit
327 lines
11 KiB
TypeScript
327 lines
11 KiB
TypeScript
import * as io from '../../io/src/io'
|
|
import * as path from 'path'
|
|
import {promises as fs} from 'fs'
|
|
import {
|
|
getUploadZipSpecification,
|
|
validateRootDirectory
|
|
} from '../src/internal/upload/upload-zip-specification'
|
|
import {noopLogs} from './common'
|
|
|
|
const root = path.join(__dirname, '_temp', 'upload-specification')
|
|
const goodItem1Path = path.join(
|
|
root,
|
|
'folder-a',
|
|
'folder-b',
|
|
'folder-c',
|
|
'good-item1.txt'
|
|
)
|
|
const goodItem2Path = path.join(root, 'folder-d', 'good-item2.txt')
|
|
const goodItem3Path = path.join(root, 'folder-d', 'good-item3.txt')
|
|
const goodItem4Path = path.join(root, 'folder-d', 'good-item4.txt')
|
|
const goodItem5Path = path.join(root, 'good-item5.txt')
|
|
const badItem1Path = path.join(
|
|
root,
|
|
'folder-a',
|
|
'folder-b',
|
|
'folder-c',
|
|
'bad-item1.txt'
|
|
)
|
|
const badItem2Path = path.join(root, 'folder-d', 'bad-item2.txt')
|
|
const badItem3Path = path.join(root, 'folder-f', 'bad-item3.txt')
|
|
const badItem4Path = path.join(root, 'folder-h', 'folder-i', 'bad-item4.txt')
|
|
const badItem5Path = path.join(root, 'folder-h', 'folder-i', 'bad-item5.txt')
|
|
const extraFileInFolderCPath = path.join(
|
|
root,
|
|
'folder-a',
|
|
'folder-b',
|
|
'folder-c',
|
|
'extra-file-in-folder-c.txt'
|
|
)
|
|
const amazingFileInFolderHPath = path.join(root, 'folder-h', 'amazing-item.txt')
|
|
|
|
const artifactFilesToUpload = [
|
|
goodItem1Path,
|
|
goodItem2Path,
|
|
goodItem3Path,
|
|
goodItem4Path,
|
|
goodItem5Path,
|
|
extraFileInFolderCPath,
|
|
amazingFileInFolderHPath
|
|
]
|
|
|
|
describe('Search', () => {
|
|
beforeAll(async () => {
|
|
noopLogs()
|
|
|
|
// clear temp directory
|
|
await io.rmRF(root)
|
|
await fs.mkdir(path.join(root, 'folder-a', 'folder-b', 'folder-c'), {
|
|
recursive: true
|
|
})
|
|
await fs.mkdir(path.join(root, 'folder-a', 'folder-b', 'folder-e'), {
|
|
recursive: true
|
|
})
|
|
await fs.mkdir(path.join(root, 'folder-d'), {
|
|
recursive: true
|
|
})
|
|
await fs.mkdir(path.join(root, 'folder-f'), {
|
|
recursive: true
|
|
})
|
|
await fs.mkdir(path.join(root, 'folder-g'), {
|
|
recursive: true
|
|
})
|
|
await fs.mkdir(path.join(root, 'folder-h', 'folder-i'), {
|
|
recursive: true
|
|
})
|
|
|
|
await fs.writeFile(goodItem1Path, 'good item1 file')
|
|
await fs.writeFile(goodItem2Path, 'good item2 file')
|
|
await fs.writeFile(goodItem3Path, 'good item3 file')
|
|
await fs.writeFile(goodItem4Path, 'good item4 file')
|
|
await fs.writeFile(goodItem5Path, 'good item5 file')
|
|
|
|
await fs.writeFile(badItem1Path, 'bad item1 file')
|
|
await fs.writeFile(badItem2Path, 'bad item2 file')
|
|
await fs.writeFile(badItem3Path, 'bad item3 file')
|
|
await fs.writeFile(badItem4Path, 'bad item4 file')
|
|
await fs.writeFile(badItem5Path, 'bad item5 file')
|
|
|
|
await fs.writeFile(extraFileInFolderCPath, 'extra file')
|
|
|
|
await fs.writeFile(amazingFileInFolderHPath, 'amazing file')
|
|
/*
|
|
Directory structure of files that get created:
|
|
root/
|
|
folder-a/
|
|
folder-b/
|
|
folder-c/
|
|
good-item1.txt
|
|
bad-item1.txt
|
|
extra-file-in-folder-c.txt
|
|
folder-e/
|
|
folder-d/
|
|
good-item2.txt
|
|
good-item3.txt
|
|
good-item4.txt
|
|
bad-item2.txt
|
|
folder-f/
|
|
bad-item3.txt
|
|
folder-g/
|
|
folder-h/
|
|
amazing-item.txt
|
|
folder-i/
|
|
bad-item4.txt
|
|
bad-item5.txt
|
|
good-item5.txt
|
|
*/
|
|
})
|
|
|
|
it('Upload Specification - Fail non-existent rootDirectory', async () => {
|
|
const invalidRootDirectory = path.join(
|
|
__dirname,
|
|
'_temp',
|
|
'upload-specification-invalid'
|
|
)
|
|
expect(() => {
|
|
validateRootDirectory(invalidRootDirectory)
|
|
}).toThrow(
|
|
`The provided rootDirectory ${invalidRootDirectory} does not exist`
|
|
)
|
|
})
|
|
|
|
it('Upload Specification - Fail invalid rootDirectory', async () => {
|
|
expect(() => {
|
|
validateRootDirectory(goodItem1Path)
|
|
}).toThrow(
|
|
`The provided rootDirectory ${goodItem1Path} is not a valid directory`
|
|
)
|
|
})
|
|
|
|
it('Upload Specification - File does not exist', async () => {
|
|
const fakeFilePath = path.join(
|
|
'folder-a',
|
|
'folder-b',
|
|
'non-existent-file.txt'
|
|
)
|
|
expect(() => {
|
|
getUploadZipSpecification([fakeFilePath], root)
|
|
}).toThrow(`File ${fakeFilePath} does not exist`)
|
|
})
|
|
|
|
it('Upload Specification - Non parent directory', async () => {
|
|
const folderADirectory = path.join(root, 'folder-a')
|
|
const artifactFiles = [
|
|
goodItem1Path,
|
|
badItem1Path,
|
|
extraFileInFolderCPath,
|
|
goodItem5Path
|
|
]
|
|
expect(() => {
|
|
getUploadZipSpecification(artifactFiles, folderADirectory)
|
|
}).toThrow(
|
|
`The rootDirectory: ${folderADirectory} is not a parent directory of the file: ${goodItem5Path}`
|
|
)
|
|
})
|
|
|
|
it('Upload Specification - Success', async () => {
|
|
const specifications = getUploadZipSpecification(
|
|
artifactFilesToUpload,
|
|
root
|
|
)
|
|
expect(specifications.length).toEqual(7)
|
|
|
|
const absolutePaths = specifications.map(item => item.sourcePath)
|
|
expect(absolutePaths).toContain(goodItem1Path)
|
|
expect(absolutePaths).toContain(goodItem2Path)
|
|
expect(absolutePaths).toContain(goodItem3Path)
|
|
expect(absolutePaths).toContain(goodItem4Path)
|
|
expect(absolutePaths).toContain(goodItem5Path)
|
|
expect(absolutePaths).toContain(extraFileInFolderCPath)
|
|
expect(absolutePaths).toContain(amazingFileInFolderHPath)
|
|
|
|
for (const specification of specifications) {
|
|
if (specification.sourcePath === goodItem1Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-a', 'folder-b', 'folder-c', 'good-item1.txt')
|
|
)
|
|
} else if (specification.sourcePath === goodItem2Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-d', 'good-item2.txt')
|
|
)
|
|
} else if (specification.sourcePath === goodItem3Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-d', 'good-item3.txt')
|
|
)
|
|
} else if (specification.sourcePath === goodItem4Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-d', 'good-item4.txt')
|
|
)
|
|
} else if (specification.sourcePath === goodItem5Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/good-item5.txt')
|
|
)
|
|
} else if (specification.sourcePath === extraFileInFolderCPath) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join(
|
|
'/folder-a',
|
|
'folder-b',
|
|
'folder-c',
|
|
'extra-file-in-folder-c.txt'
|
|
)
|
|
)
|
|
} else if (specification.sourcePath === amazingFileInFolderHPath) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-h', 'amazing-item.txt')
|
|
)
|
|
} else {
|
|
throw new Error(
|
|
'Invalid specification found. This should never be reached'
|
|
)
|
|
}
|
|
}
|
|
})
|
|
|
|
it('Upload Specification - Success with extra slash', async () => {
|
|
const rootWithSlash = `${root}/`
|
|
const specifications = getUploadZipSpecification(
|
|
artifactFilesToUpload,
|
|
rootWithSlash
|
|
)
|
|
expect(specifications.length).toEqual(7)
|
|
|
|
const absolutePaths = specifications.map(item => item.sourcePath)
|
|
expect(absolutePaths).toContain(goodItem1Path)
|
|
expect(absolutePaths).toContain(goodItem2Path)
|
|
expect(absolutePaths).toContain(goodItem3Path)
|
|
expect(absolutePaths).toContain(goodItem4Path)
|
|
expect(absolutePaths).toContain(goodItem5Path)
|
|
expect(absolutePaths).toContain(extraFileInFolderCPath)
|
|
expect(absolutePaths).toContain(amazingFileInFolderHPath)
|
|
|
|
for (const specification of specifications) {
|
|
if (specification.sourcePath === goodItem1Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-a', 'folder-b', 'folder-c', 'good-item1.txt')
|
|
)
|
|
} else if (specification.sourcePath === goodItem2Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-d', 'good-item2.txt')
|
|
)
|
|
} else if (specification.sourcePath === goodItem3Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-d', 'good-item3.txt')
|
|
)
|
|
} else if (specification.sourcePath === goodItem4Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-d', 'good-item4.txt')
|
|
)
|
|
} else if (specification.sourcePath === goodItem5Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/good-item5.txt')
|
|
)
|
|
} else if (specification.sourcePath === extraFileInFolderCPath) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join(
|
|
'/folder-a',
|
|
'folder-b',
|
|
'folder-c',
|
|
'extra-file-in-folder-c.txt'
|
|
)
|
|
)
|
|
} else if (specification.sourcePath === amazingFileInFolderHPath) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-h', 'amazing-item.txt')
|
|
)
|
|
} else {
|
|
throw new Error(
|
|
'Invalid specification found. This should never be reached'
|
|
)
|
|
}
|
|
}
|
|
})
|
|
|
|
it('Upload Specification - Empty Directories are included', async () => {
|
|
const folderEPath = path.join(root, 'folder-a', 'folder-b', 'folder-e')
|
|
const filesWithDirectory = [goodItem1Path, folderEPath]
|
|
const specifications = getUploadZipSpecification(filesWithDirectory, root)
|
|
expect(specifications.length).toEqual(2)
|
|
const absolutePaths = specifications.map(item => item.sourcePath)
|
|
expect(absolutePaths).toContain(goodItem1Path)
|
|
expect(absolutePaths).toContain(null)
|
|
|
|
for (const specification of specifications) {
|
|
if (specification.sourcePath === goodItem1Path) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-a', 'folder-b', 'folder-c', 'good-item1.txt')
|
|
)
|
|
} else if (specification.sourcePath === null) {
|
|
expect(specification.destinationPath).toEqual(
|
|
path.join('/folder-a', 'folder-b', 'folder-e')
|
|
)
|
|
} else {
|
|
throw new Error(
|
|
'Invalid specification found. This should never be reached'
|
|
)
|
|
}
|
|
}
|
|
})
|
|
|
|
it('Upload Specification - Includes symlinks', async () => {
|
|
const targetPath = path.join(root, 'link-dir', 'symlink-me.txt')
|
|
await fs.mkdir(path.dirname(targetPath), {recursive: true})
|
|
await fs.writeFile(targetPath, 'symlink file content')
|
|
|
|
const uploadPath = path.join(root, 'upload-dir', 'symlink.txt')
|
|
await fs.mkdir(path.dirname(uploadPath), {recursive: true})
|
|
await fs.symlink(targetPath, uploadPath, 'file')
|
|
|
|
const specifications = getUploadZipSpecification([uploadPath], root)
|
|
expect(specifications.length).toEqual(1)
|
|
expect(specifications[0].sourcePath).toEqual(uploadPath)
|
|
expect(specifications[0].destinationPath).toEqual(
|
|
path.join('/upload-dir', 'symlink.txt')
|
|
)
|
|
expect(specifications[0].stats.isSymbolicLink()).toBe(true)
|
|
})
|
|
})
|