-
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
Conversation
Errr, didn't see this.... |
Still a lot of great feedback! I should have changed the PR title so it's more obvious that it's not ready for review, I'll do that moving forward. Thanks for taking a look! 😀 |
|
||
const parameters: UploadFileParameters[] = [] | ||
let continueOnError = true | ||
if (options) { |
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.
This is not future proof - if we add another option in the future, this check will fail. Would
const continueOnError = !!(options && options.continueOnError)
work?
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.
In upload-options.ts
, continueOnError
is a required property though, so as long as there are some uploadOptions
provided this should work even if some extra properties are added to uploadOptions
If there ever are more options added to upload-options.ts
, they should be required (there would be a lot of unnecessary checks if there were optional parameters in an already optional object). The general flow will be something like this?
// define default options
if (options){
// update default options to whatever is specified in options
}
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.
In general, individual options in the options
object should not be required. Imagine if there are many options available, user should only need to set the ones they care about.
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.
Changed continueOnError
so it is optional in upload-options.ts
Changed the rest to this:
// by default, file uploads will continue if there is an error unless specified differently in the options
let continueOnError = true
if (options) {
if (options.continueOnError === false) {
continueOnError = false
}
}
The double bang operators didn't seem very readable so I tried to avoid it. We do also need to support a default value if no continueOnError
option is specified. Doing all that in a single line is possible but it gets pretty ugly so I think what I have is easy to follow
Also added two extra tests so now we have the following cases:
- no
uploadOptions
uploadOptions
withcontinueOnError
set toundefined
uploadOptions
withcontinueOnError
set tofalse
uploadOptions
withcontinueOnError
set totrue
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.
I think this would be more readable as Yang suggested:
const continueOnError = !!(options && options.continueOnError)
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.
So that one liner would be fine if we didn't care about the default true
behavior if no options are provided. So it just won't work
Changing to just that one line changes the expected behavior if no options are provided (2 tests start to fail).
@ericsciple could you also take a 👀 at this PR. Getting ready to merge this in. A new package to the toolkit is quite a hefty addition and you're probably the best person to look at this. I have another PR pretty much ready to go after this with documentation and all the extra code related to downloading an artifact. |
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.
path.join(artifactName, 'folder-f', 'bad-item3.txt') | ||
) | ||
} else { | ||
throw new Error('this should never be reached') |
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
expect(badUploadFilePaths).toContain(specification.uploadFilePath)
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 with includes
, I can swap that out in a few places that I use it because it seems nicer
I use an array to check for the absolutePaths
however using just another array for uploadFilePath
does not 100% check for what we need. It is possible that all the correct strings exist for uploadFilePath
in an array, however the right combination must match with the absolutePath
which is what I'm doing with the if else-if
statements
packages/artifact/src/artifact.ts
Outdated
} | ||
|
||
if (uploadSpecification.length === 0) { | ||
core.warning(`No files found that can be uploaded`) |
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.
Should this be a warning? It seems like an error case if there are no files to upload.
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.
The current behavior is that and empty upload will throw a warning but not fail.
It is possible that someone includes only empty directories in the files that they want uploaded. If that is the case, the uploadspecification
will be empty and this will be hit because directories get ignored by the FCS during upload.
|
||
const parameters: UploadFileParameters[] = [] | ||
let continueOnError = true | ||
if (options) { |
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.
I think this would be more readable as Yang suggested:
const continueOnError = !!(options && options.continueOnError)
) | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(`Total size of all the files uploaded is ${fileSizes} bytes`) |
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.
Minor: you can use core.info
here and elsewhere if you want to console.log
. It's easier to mock core
than console
and you don't need the eslint disables
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.
It seems like core.info
isn't documented anywhere, even though it exists 🤔 https://github.com/actions/toolkit/tree/master/packages/core
I can use it a few places, though console.log
is better because it isn't limited to just strings so certain things like formatted http responses look better
…tions/toolkit into konradpabjan/actions/artifact
if (isSuccessStatusCode(retryResponse.message.statusCode)) { | ||
return true | ||
} else { | ||
// eslint-disable-next-line no-console |
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.
i think stdout is preferred so unit tests can be less noisy
e.g. here is a snippet from somewhere else in toolkit
process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${EOL}`)
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.
not sure, the linter may have another reason for avoiding console.log
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.
Perhaps we could disable console.log in the jest configuration? https://stackoverflow.com/questions/44467657/jest-better-way-to-disable-console-inside-unit-tests
Some of the response logging that I have is really noisy, for the tests I'll just mock console.log
so that there is no annoying output
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
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.
I ended up doing the following for each of the tests
jest.spyOn(console, 'log').mockImplementation(() => {})
jest.spyOn(core, 'debug').mockImplementation(() => {})
jest.spyOn(core, 'info').mockImplementation(() => {})
jest.spyOn(core, 'warning').mockImplementation(() => {})
Shouldn't be any noise in the tests now
* Initial commit for @actions/artifact package
Initial commit for the
@actions/artifact
package. So far only contains the code for uploading an artifact, download will come in a separate PR.Adds support for uploading artifacts with new APIs that are independent of the runner (non-plugin). The original code for uploading artifacts can be found here (see https://github.com/actions/runner/tree/master/src/Runner.Plugins/Artifact). This PR largely ports over the C# code for uploading artifacts to node and switches over to some recently added APIs. This new package will be used for the
v2
versions ofactions/upload-artifact
andactions/download-artifact
.Been using the structure of
@actions/glob
in this repo as an example. For this PR I deliberately did not dotsc
andnpm-install
so there is nolib
folder ornode_modules
folder. Trying to keep it clean and simple for this PR so that it is easy to review.Been testing with the following two repos for upload artifact: https://github.com/bbq-beets/artifact-package and https://github.com/bbq-beets/upload-artifact-v2
Future work not part of this PR
Tests (all the code in(Tests have been added)search.ts
andutil.ts
is a good candidate, will be added to a_TEST_
directory just like in all the other packages in this repo)downloadArtifact
anddownloadAllArtifacts
(TODOs can be seen insrc/internal-artifact.ts
)lib
andnode_modules
folder, (just like in `@actions/glob), will be added as we get close to release and everything is testedSearch uses our new glob package:(searching will be externally done)@actions/glob
Http calls are made using our new:
@actions/http-client
package in order to support proxiesMuch of the work that was done in
@actions/cache
was used as a reference in terms of how concurrent chunked uploads are done, see: actions/cache#128Formatting was done by doing
prettier --write packages src/*.ts
so the style should be consistent with the other code in this repo.