-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@actions/artifact package #304
Merged
Merged
Changes from 41 commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
3a20113
Initial commit for @actions/artifact
776270f
Alphabetize imports
f3ac746
Fix majority of lint errors
bd38a3f
Fix all lint errors
b2d67bb
Various fixes due to PR feedback
029f2a4
Add tests for search
4fda766
Rename test file
e025ef0
Test improvements
11c006c
Misc formatting fixes
4431cd8
Tests for artifactName
konradpabjan 7cf5770
Misc improvements
konradpabjan b56cdb0
Hopefully fix failing tests
konradpabjan 6b04ca5
🤞 this works
konradpabjan e12553e
Hmmm
konradpabjan 83c8848
Really weird...
konradpabjan b6f59a0
Update tests for util.ts
konradpabjan c6d23c0
Succesfull http mocking along with more tests
konradpabjan da72c73
Spelling fixes and misc updates
206233a
Logic for fast failing in the event a chunk fails
e6f5591
Tests for artifact uploads
7f48237
Minor fixes
ddfdb57
PR Feedback
0768705
Format fix
31ff9e6
Fixes error with unbound methods being used in tests
konradpabjan c5216d2
.
konradpabjan a375c57
Remove directory deletion after tests finish
konradpabjan c71237b
Remove project GUID from API call
0cc46af
Misc Improvements
6f6aac1
Code cleanup
cd5d31a
Extra debug
09b1c39
Move glob search out of the package
049110f
Code cleanup
abd642c
Rename some thing and cleanup
813bcf1
Rename uploadInfo to uploadResponse
c8d2dd1
Misc Improvements
1dd4152
Format Fix
1fa883d
Test Improvements
7c6e6ac
Updates to continueOnError
6b6a5e0
Extra test
4ac6ef6
Normalize and Resolve all paths
d01f0f3
Change console.log to warning
7917754
Update upload-response.ts
konradpabjan 21ce5cb
PR feedback
konradpabjan 78605ae
Merge branch 'konradpabjan/actions/artifact' of https://github.com/ac…
konradpabjan fcec6a7
Update upload-http-client.ts
konradpabjan 5288533
Silence output when running tests and rename files with internal
konradpabjan 8a1220b
Use Factory to create ArtifactClient
konradpabjan 332dfce
Merge branch 'konradpabjan/actions/artifact' of https://github.com/ac…
konradpabjan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Empty file.
340 changes: 340 additions & 0 deletions
340
packages/artifact/__tests__/upload-specification.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,340 @@ | ||
import * as io from '../../io/src/io' | ||
import * as path from 'path' | ||
import {promises as fs} from 'fs' | ||
import {getUploadSpecification} from '../src/upload-specification' | ||
|
||
const artifactName = 'my-artifact' | ||
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 () => { | ||
// 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(() => { | ||
getUploadSpecification( | ||
artifactName, | ||
invalidRootDirectory, | ||
artifactFilesToUpload | ||
) | ||
}).toThrow(`Provided rootDirectory ${invalidRootDirectory} does not exist`) | ||
}) | ||
|
||
it('Upload Specification - Fail invalid rootDirectory', async () => { | ||
expect(() => { | ||
getUploadSpecification(artifactName, goodItem1Path, artifactFilesToUpload) | ||
}).toThrow( | ||
`Provided rootDirectory ${goodItem1Path} is not a valid directory` | ||
) | ||
}) | ||
|
||
it('Upload Specification - File does not exist', async () => { | ||
const fakeFilePath = path.join( | ||
artifactName, | ||
'folder-a', | ||
'folder-b', | ||
'non-existent-file.txt' | ||
) | ||
expect(() => { | ||
getUploadSpecification(artifactName, root, [fakeFilePath]) | ||
}).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(() => { | ||
getUploadSpecification(artifactName, folderADirectory, artifactFiles) | ||
}).toThrow( | ||
`The rootDirectory: ${folderADirectory} is not a parent directory of the file: ${goodItem5Path}` | ||
) | ||
}) | ||
|
||
it('Upload Specification - Success', async () => { | ||
const specifications = getUploadSpecification( | ||
artifactName, | ||
root, | ||
artifactFilesToUpload | ||
) | ||
expect(specifications.length).toEqual(7) | ||
|
||
const absolutePaths = specifications.map(item => item.absoluteFilePath) | ||
expect(absolutePaths.includes(goodItem1Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem2Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem3Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem4Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem5Path)).toEqual(true) | ||
expect(absolutePaths.includes(extraFileInFolderCPath)).toEqual(true) | ||
expect(absolutePaths.includes(amazingFileInFolderHPath)).toEqual(true) | ||
|
||
for (const specification of specifications) { | ||
if (specification.absoluteFilePath === goodItem1Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join( | ||
artifactName, | ||
'folder-a', | ||
'folder-b', | ||
'folder-c', | ||
'good-item1.txt' | ||
) | ||
) | ||
} else if (specification.absoluteFilePath === goodItem2Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-d', 'good-item2.txt') | ||
) | ||
} else if (specification.absoluteFilePath === goodItem3Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-d', 'good-item3.txt') | ||
) | ||
} else if (specification.absoluteFilePath === goodItem4Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-d', 'good-item4.txt') | ||
) | ||
} else if (specification.absoluteFilePath === goodItem5Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'good-item5.txt') | ||
) | ||
} else if (specification.absoluteFilePath === extraFileInFolderCPath) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join( | ||
artifactName, | ||
'folder-a', | ||
'folder-b', | ||
'folder-c', | ||
'extra-file-in-folder-c.txt' | ||
) | ||
) | ||
} else if (specification.absoluteFilePath === amazingFileInFolderHPath) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-h', 'amazing-item.txt') | ||
) | ||
} else { | ||
throw new Error('this should never be reached') | ||
} | ||
} | ||
}) | ||
|
||
it('Upload Specification - Success with extra slash', async () => { | ||
const rootWithSlash = `${root}/` | ||
const specifications = getUploadSpecification( | ||
artifactName, | ||
rootWithSlash, | ||
artifactFilesToUpload | ||
) | ||
expect(specifications.length).toEqual(7) | ||
|
||
const absolutePaths = specifications.map(item => item.absoluteFilePath) | ||
expect(absolutePaths.includes(goodItem1Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem2Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem3Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem4Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem5Path)).toEqual(true) | ||
expect(absolutePaths.includes(extraFileInFolderCPath)).toEqual(true) | ||
expect(absolutePaths.includes(amazingFileInFolderHPath)).toEqual(true) | ||
|
||
for (const specification of specifications) { | ||
if (specification.absoluteFilePath === goodItem1Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join( | ||
artifactName, | ||
'folder-a', | ||
'folder-b', | ||
'folder-c', | ||
'good-item1.txt' | ||
) | ||
) | ||
} else if (specification.absoluteFilePath === goodItem2Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-d', 'good-item2.txt') | ||
) | ||
} else if (specification.absoluteFilePath === goodItem3Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-d', 'good-item3.txt') | ||
) | ||
} else if (specification.absoluteFilePath === goodItem4Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-d', 'good-item4.txt') | ||
) | ||
} else if (specification.absoluteFilePath === goodItem5Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'good-item5.txt') | ||
) | ||
} else if (specification.absoluteFilePath === extraFileInFolderCPath) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join( | ||
artifactName, | ||
'folder-a', | ||
'folder-b', | ||
'folder-c', | ||
'extra-file-in-folder-c.txt' | ||
) | ||
) | ||
} else if (specification.absoluteFilePath === amazingFileInFolderHPath) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-h', 'amazing-item.txt') | ||
) | ||
} else { | ||
throw new Error('this should never be reached') | ||
} | ||
} | ||
}) | ||
|
||
it('Upload Specification - Directories should not be included', async () => { | ||
const folderEPath = path.join(root, 'folder-a', 'folder-b', 'folder-e') | ||
const filesWithDirectory = [ | ||
goodItem1Path, | ||
goodItem4Path, | ||
folderEPath, | ||
badItem3Path | ||
] | ||
const specifications = getUploadSpecification( | ||
artifactName, | ||
root, | ||
filesWithDirectory | ||
) | ||
expect(specifications.length).toEqual(3) | ||
const absolutePaths = specifications.map(item => item.absoluteFilePath) | ||
expect(absolutePaths.includes(goodItem1Path)).toEqual(true) | ||
expect(absolutePaths.includes(goodItem4Path)).toEqual(true) | ||
expect(absolutePaths.includes(badItem3Path)).toEqual(true) | ||
|
||
for (const specification of specifications) { | ||
if (specification.absoluteFilePath === goodItem1Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join( | ||
artifactName, | ||
'folder-a', | ||
'folder-b', | ||
'folder-c', | ||
'good-item1.txt' | ||
) | ||
) | ||
} else if (specification.absoluteFilePath === goodItem2Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-d', 'good-item2.txt') | ||
) | ||
} else if (specification.absoluteFilePath === goodItem4Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-d', 'good-item4.txt') | ||
) | ||
} else if (specification.absoluteFilePath === badItem3Path) { | ||
expect(specification.uploadFilePath).toEqual( | ||
path.join(artifactName, 'folder-f', 'bad-item3.txt') | ||
) | ||
} else { | ||
throw new Error('this should never be reached') | ||
} | ||
} | ||
}) | ||
}) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going to fail the test by throwing an error, we should be more explicit about what went wrong.
In this specific case, it might be better to simplify this into an array contains
https://jestjs.io/docs/en/expect#tocontainitem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toContain
is fairly similar to what I have withincludes
, I can swap that out in a few places that I use it because it seems nicerI use an array to check for the
absolutePaths
however using just another array foruploadFilePath
does not 100% check for what we need. It is possible that all the correct strings exist foruploadFilePath
in an array, however the right combination must match with theabsolutePath
which is what I'm doing with theif else-if
statements