mirror of
https://github.com/actions/upload-artifact.git
synced 2024-11-24 20:22:09 +00:00
92b91569e6
This commit implements a new boolean input to the action, `follow-symlinks`. This option configures whether the glob expansion will follow any symlinks it finds when determining the set of of files to be archived into the artifact. The default value of the option, which preserves the existing behaviour, is `true`. When set to true, symbolic links will be be followed and expanded If `false`, symbolic links will be included in the archived artifact verbatim. Users may wish to set this option to false if their artifact contains internally-referencing symlinks which would result in significant bloat (and semantic change!) in the source files when the artifact is created. Resolves: actions#93.
375 lines
13 KiB
TypeScript
375 lines
13 KiB
TypeScript
import * as core from '@actions/core'
|
|
import * as path from 'path'
|
|
import * as io from '@actions/io'
|
|
import {promises as fs} from 'fs'
|
|
import {findFilesToUpload, getDefaultGlobOptions} from '../src/search'
|
|
|
|
const root = path.join(__dirname, '_temp', 'search')
|
|
const searchItem1Path = path.join(
|
|
root,
|
|
'folder-a',
|
|
'folder-b',
|
|
'folder-c',
|
|
'search-item1.txt'
|
|
)
|
|
const searchItem2Path = path.join(root, 'folder-d', 'search-item2.txt')
|
|
const searchItem3Path = path.join(root, 'folder-d', 'search-item3.txt')
|
|
const searchItem4Path = path.join(root, 'folder-d', 'search-item4.txt')
|
|
const searchItem5Path = path.join(root, 'search-item5.txt')
|
|
const extraSearchItem1Path = path.join(
|
|
root,
|
|
'folder-a',
|
|
'folder-b',
|
|
'folder-c',
|
|
'extraSearch-item1.txt'
|
|
)
|
|
const extraSearchItem2Path = path.join(
|
|
root,
|
|
'folder-d',
|
|
'extraSearch-item2.txt'
|
|
)
|
|
const extraSearchItem3Path = path.join(
|
|
root,
|
|
'folder-f',
|
|
'extraSearch-item3.txt'
|
|
)
|
|
const extraSearchItem4Path = path.join(
|
|
root,
|
|
'folder-h',
|
|
'folder-i',
|
|
'extraSearch-item4.txt'
|
|
)
|
|
const extraSearchItem5Path = path.join(
|
|
root,
|
|
'folder-h',
|
|
'folder-i',
|
|
'extraSearch-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 lonelyFilePath = path.join(
|
|
root,
|
|
'folder-h',
|
|
'folder-j',
|
|
'folder-k',
|
|
'lonely-file.txt'
|
|
)
|
|
|
|
describe('Search', () => {
|
|
beforeAll(async () => {
|
|
// mock all output so that there is less noise when running tests
|
|
jest.spyOn(console, 'log').mockImplementation(() => {})
|
|
jest.spyOn(core, 'debug').mockImplementation(() => {})
|
|
jest.spyOn(core, 'info').mockImplementation(() => {})
|
|
jest.spyOn(core, 'warning').mockImplementation(() => {})
|
|
|
|
// 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.mkdir(path.join(root, 'folder-h', 'folder-j', 'folder-k'), {
|
|
recursive: true
|
|
})
|
|
|
|
await fs.writeFile(searchItem1Path, 'search item1 file')
|
|
await fs.writeFile(searchItem2Path, 'search item2 file')
|
|
await fs.writeFile(searchItem3Path, 'search item3 file')
|
|
await fs.writeFile(searchItem4Path, 'search item4 file')
|
|
await fs.writeFile(searchItem5Path, 'search item5 file')
|
|
|
|
await fs.writeFile(extraSearchItem1Path, 'extraSearch item1 file')
|
|
await fs.writeFile(extraSearchItem2Path, 'extraSearch item2 file')
|
|
await fs.writeFile(extraSearchItem3Path, 'extraSearch item3 file')
|
|
await fs.writeFile(extraSearchItem4Path, 'extraSearch item4 file')
|
|
await fs.writeFile(extraSearchItem5Path, 'extraSearch item5 file')
|
|
|
|
await fs.writeFile(extraFileInFolderCPath, 'extra file')
|
|
|
|
await fs.writeFile(amazingFileInFolderHPath, 'amazing file')
|
|
|
|
await fs.writeFile(lonelyFilePath, 'all by itself')
|
|
|
|
await fs.symlink(
|
|
path.join(root, 'folder-d'),
|
|
path.join(root, 'symlink-to-folder-d')
|
|
)
|
|
|
|
/*
|
|
Directory structure of files that get created:
|
|
root/
|
|
folder-a/
|
|
folder-b/
|
|
folder-c/
|
|
search-item1.txt
|
|
extraSearch-item1.txt
|
|
extra-file-in-folder-c.txt
|
|
folder-e/
|
|
folder-d/
|
|
search-item2.txt
|
|
search-item3.txt
|
|
search-item4.txt
|
|
extraSearch-item2.txt
|
|
folder-f/
|
|
extraSearch-item3.txt
|
|
folder-g/
|
|
folder-h/
|
|
amazing-item.txt
|
|
folder-i/
|
|
extraSearch-item4.txt
|
|
extraSearch-item5.txt
|
|
folder-j/
|
|
folder-k/
|
|
lonely-file.txt
|
|
symlink-to-folder-d/ -> ./folder-d/
|
|
search-item5.txt
|
|
*/
|
|
})
|
|
|
|
it('Single file search - Absolute Path', async () => {
|
|
const searchResult = await findFilesToUpload(extraFileInFolderCPath)
|
|
expect(searchResult.filesToUpload.length).toEqual(1)
|
|
expect(searchResult.filesToUpload[0]).toEqual(extraFileInFolderCPath)
|
|
expect(searchResult.rootDirectory).toEqual(
|
|
path.join(root, 'folder-a', 'folder-b', 'folder-c')
|
|
)
|
|
})
|
|
|
|
it('Single file search - Relative Path', async () => {
|
|
const relativePath = path.join(
|
|
'__tests__',
|
|
'_temp',
|
|
'search',
|
|
'folder-a',
|
|
'folder-b',
|
|
'folder-c',
|
|
'search-item1.txt'
|
|
)
|
|
|
|
const searchResult = await findFilesToUpload(relativePath)
|
|
expect(searchResult.filesToUpload.length).toEqual(1)
|
|
expect(searchResult.filesToUpload[0]).toEqual(searchItem1Path)
|
|
expect(searchResult.rootDirectory).toEqual(
|
|
path.join(root, 'folder-a', 'folder-b', 'folder-c')
|
|
)
|
|
})
|
|
|
|
it('Single file using wildcard', async () => {
|
|
const expectedRoot = path.join(root, 'folder-h')
|
|
const searchPath = path.join(root, 'folder-h', '**/*lonely*')
|
|
const searchResult = await findFilesToUpload(searchPath)
|
|
expect(searchResult.filesToUpload.length).toEqual(1)
|
|
expect(searchResult.filesToUpload[0]).toEqual(lonelyFilePath)
|
|
expect(searchResult.rootDirectory).toEqual(expectedRoot)
|
|
})
|
|
|
|
it('Single file using directory', async () => {
|
|
const searchPath = path.join(root, 'folder-h', 'folder-j')
|
|
const searchResult = await findFilesToUpload(searchPath)
|
|
expect(searchResult.filesToUpload.length).toEqual(1)
|
|
expect(searchResult.filesToUpload[0]).toEqual(lonelyFilePath)
|
|
expect(searchResult.rootDirectory).toEqual(searchPath)
|
|
})
|
|
|
|
it('Directory search - Absolute Path', async () => {
|
|
const searchPath = path.join(root, 'folder-h')
|
|
const searchResult = await findFilesToUpload(searchPath)
|
|
expect(searchResult.filesToUpload.length).toEqual(4)
|
|
|
|
expect(
|
|
searchResult.filesToUpload.includes(amazingFileInFolderHPath)
|
|
).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
|
|
|
|
expect(searchResult.rootDirectory).toEqual(searchPath)
|
|
})
|
|
|
|
it('Directory search - Relative Path', async () => {
|
|
const searchPath = path.join('__tests__', '_temp', 'search', 'folder-h')
|
|
const expectedRootDirectory = path.join(root, 'folder-h')
|
|
const searchResult = await findFilesToUpload(searchPath)
|
|
expect(searchResult.filesToUpload.length).toEqual(4)
|
|
|
|
expect(
|
|
searchResult.filesToUpload.includes(amazingFileInFolderHPath)
|
|
).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
|
|
|
|
expect(searchResult.rootDirectory).toEqual(expectedRootDirectory)
|
|
})
|
|
|
|
it('Wildcard search - Absolute Path', async () => {
|
|
const searchPath = path.join(root, '**/*[Ss]earch*')
|
|
const searchResult = await findFilesToUpload(searchPath)
|
|
// folder-d items included twice because symlink is followed by default
|
|
expect(searchResult.filesToUpload.length).toEqual(14)
|
|
|
|
expect(searchResult.filesToUpload.includes(searchItem1Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem2Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem3Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem4Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem5Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem1Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem2Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem3Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
|
|
true
|
|
)
|
|
|
|
expect(searchResult.rootDirectory).toEqual(root)
|
|
})
|
|
|
|
it('Wildcard search - Relative Path', async () => {
|
|
const searchPath = path.join(
|
|
'__tests__',
|
|
'_temp',
|
|
'search',
|
|
'**/*[Ss]earch*'
|
|
)
|
|
const searchResult = await findFilesToUpload(searchPath)
|
|
// folder-d items included twice because symlink is followed by default
|
|
expect(searchResult.filesToUpload.length).toEqual(14)
|
|
|
|
expect(searchResult.filesToUpload.includes(searchItem1Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem2Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem3Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem4Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem5Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem1Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem2Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem3Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
|
|
true
|
|
)
|
|
|
|
expect(searchResult.rootDirectory).toEqual(root)
|
|
})
|
|
|
|
it('Multi path search - root directory', async () => {
|
|
const searchPath1 = path.join(root, 'folder-a')
|
|
const searchPath2 = path.join(root, 'folder-d')
|
|
|
|
const searchPaths = searchPath1 + '\n' + searchPath2
|
|
const searchResult = await findFilesToUpload(searchPaths)
|
|
|
|
expect(searchResult.rootDirectory).toEqual(root)
|
|
expect(searchResult.filesToUpload.length).toEqual(7)
|
|
expect(searchResult.filesToUpload.includes(searchItem1Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem2Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem3Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem4Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem1Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem2Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraFileInFolderCPath)).toEqual(
|
|
true
|
|
)
|
|
})
|
|
|
|
it('Multi path search - with exclude character', async () => {
|
|
const searchPath1 = path.join(root, 'folder-a')
|
|
const searchPath2 = path.join(root, 'folder-d')
|
|
const searchPath3 = path.join(root, 'folder-a', 'folder-b', '**/extra*.txt')
|
|
|
|
// negating the third search path
|
|
const searchPaths = searchPath1 + '\n' + searchPath2 + '\n!' + searchPath3
|
|
const searchResult = await findFilesToUpload(searchPaths)
|
|
|
|
expect(searchResult.rootDirectory).toEqual(root)
|
|
expect(searchResult.filesToUpload.length).toEqual(5)
|
|
expect(searchResult.filesToUpload.includes(searchItem1Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem2Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem3Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(searchItem4Path)).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem2Path)).toEqual(
|
|
true
|
|
)
|
|
})
|
|
|
|
it('Multi path search - non root directory', async () => {
|
|
const searchPath1 = path.join(root, 'folder-h', 'folder-i')
|
|
const searchPath2 = path.join(root, 'folder-h', 'folder-j', 'folder-k')
|
|
const searchPath3 = amazingFileInFolderHPath
|
|
|
|
const searchPaths = [searchPath1, searchPath2, searchPath3].join('\n')
|
|
const searchResult = await findFilesToUpload(searchPaths)
|
|
|
|
expect(searchResult.rootDirectory).toEqual(path.join(root, 'folder-h'))
|
|
expect(searchResult.filesToUpload.length).toEqual(4)
|
|
expect(
|
|
searchResult.filesToUpload.includes(amazingFileInFolderHPath)
|
|
).toEqual(true)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem4Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(extraSearchItem5Path)).toEqual(
|
|
true
|
|
)
|
|
expect(searchResult.filesToUpload.includes(lonelyFilePath)).toEqual(true)
|
|
})
|
|
|
|
it('Declines to follow symlinks when requested', async () => {
|
|
const searchPath = path.join(root, 'symlink-to-folder-d')
|
|
const globOptions = {
|
|
...getDefaultGlobOptions(),
|
|
followSymbolicLinks: false
|
|
}
|
|
|
|
const searchResult = await findFilesToUpload(searchPath, globOptions)
|
|
expect(searchResult.filesToUpload.length).toEqual(1)
|
|
})
|
|
})
|