1
0
mirror of https://github.com/actions/upload-artifact.git synced 2026-02-26 13:42:35 +00:00

Support direct file uploads

This commit is contained in:
Daniel Kennedy
2026-02-25 13:02:50 -05:00
parent 4177a106a5
commit 6b68470975
9 changed files with 46 additions and 7 deletions

View File

@ -72,6 +72,7 @@ const mockInputs = (
[Inputs.RetentionDays]: 0, [Inputs.RetentionDays]: 0,
[Inputs.CompressionLevel]: 6, [Inputs.CompressionLevel]: 6,
[Inputs.Overwrite]: false, [Inputs.Overwrite]: false,
[Inputs.Archive]: true,
...overrides ...overrides
} }

View File

@ -3,10 +3,10 @@ description: 'Upload a build artifact that can be used by subsequent workflow st
author: 'GitHub' author: 'GitHub'
inputs: inputs:
name: name:
description: 'Artifact name' description: 'Artifact name. If the "archive" input is `false`, the name of the file uploaded will be the artifact name.'
default: 'artifact' default: 'artifact'
path: path:
description: 'A file, directory or wildcard pattern that describes what to upload' description: 'A file, directory or wildcard pattern that describes what to upload.'
required: true required: true
if-no-files-found: if-no-files-found:
description: > description: >
@ -45,6 +45,12 @@ inputs:
If true, hidden files will be included in the artifact. If true, hidden files will be included in the artifact.
If false, hidden files will be excluded from the artifact. If false, hidden files will be excluded from the artifact.
default: 'false' default: 'false'
archive:
description: >
If true, the artifact will be archived (zipped) before uploading.
If false, the artifact will be uploaded as-is without archiving.
When archive is false, only a single file can be uploaded. The name of the file will be used as the artifact name.
default: 'true'
outputs: outputs:
artifact-id: artifact-id:

13
dist/upload/index.js vendored
View File

@ -130457,6 +130457,7 @@ var Inputs;
Inputs["CompressionLevel"] = "compression-level"; Inputs["CompressionLevel"] = "compression-level";
Inputs["Overwrite"] = "overwrite"; Inputs["Overwrite"] = "overwrite";
Inputs["IncludeHiddenFiles"] = "include-hidden-files"; Inputs["IncludeHiddenFiles"] = "include-hidden-files";
Inputs["Archive"] = "archive";
})(Inputs || (Inputs = {})); })(Inputs || (Inputs = {}));
var NoFileOptions; var NoFileOptions;
(function (NoFileOptions) { (function (NoFileOptions) {
@ -130485,6 +130486,7 @@ function getInputs() {
const path = getInput(Inputs.Path, { required: true }); const path = getInput(Inputs.Path, { required: true });
const overwrite = getBooleanInput(Inputs.Overwrite); const overwrite = getBooleanInput(Inputs.Overwrite);
const includeHiddenFiles = getBooleanInput(Inputs.IncludeHiddenFiles); const includeHiddenFiles = getBooleanInput(Inputs.IncludeHiddenFiles);
const archive = getBooleanInput(Inputs.Archive);
const ifNoFilesFound = getInput(Inputs.IfNoFilesFound); const ifNoFilesFound = getInput(Inputs.IfNoFilesFound);
const noFileBehavior = NoFileOptions[ifNoFilesFound]; const noFileBehavior = NoFileOptions[ifNoFilesFound];
if (!noFileBehavior) { if (!noFileBehavior) {
@ -130495,7 +130497,8 @@ function getInputs() {
searchPath: path, searchPath: path,
ifNoFilesFound: noFileBehavior, ifNoFilesFound: noFileBehavior,
overwrite: overwrite, overwrite: overwrite,
includeHiddenFiles: includeHiddenFiles includeHiddenFiles: includeHiddenFiles,
archive: archive
}; };
const retentionDaysStr = getInput(Inputs.RetentionDays); const retentionDaysStr = getInput(Inputs.RetentionDays);
if (retentionDaysStr) { if (retentionDaysStr) {
@ -130576,6 +130579,11 @@ async function run() {
const s = searchResult.filesToUpload.length === 1 ? '' : 's'; const s = searchResult.filesToUpload.length === 1 ? '' : 's';
info(`With the provided path, there will be ${searchResult.filesToUpload.length} file${s} uploaded`); info(`With the provided path, there will be ${searchResult.filesToUpload.length} file${s} uploaded`);
core_debug(`Root artifact directory is ${searchResult.rootDirectory}`); core_debug(`Root artifact directory is ${searchResult.rootDirectory}`);
// Validate that only a single file is uploaded when archive is false
if (!inputs.archive && searchResult.filesToUpload.length > 1) {
setFailed(`When 'archive' is set to false, only a single file can be uploaded. Found ${searchResult.filesToUpload.length} files to upload.`);
return;
}
if (inputs.overwrite) { if (inputs.overwrite) {
await deleteArtifactIfExists(inputs.artifactName); await deleteArtifactIfExists(inputs.artifactName);
} }
@ -130586,6 +130594,9 @@ async function run() {
if (typeof inputs.compressionLevel !== 'undefined') { if (typeof inputs.compressionLevel !== 'undefined') {
options.compressionLevel = inputs.compressionLevel; options.compressionLevel = inputs.compressionLevel;
} }
if (!inputs.archive) {
options.skipArchive = true;
}
await upload_artifact_uploadArtifact(inputs.artifactName, searchResult.filesToUpload, searchResult.rootDirectory, options); await upload_artifact_uploadArtifact(inputs.artifactName, searchResult.filesToUpload, searchResult.rootDirectory, options);
} }
} }

2
package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "7.0.0", "version": "7.0.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/artifact": "^6.1.0", "@actions/artifact": "^6.2.0",
"@actions/core": "^3.0.0", "@actions/core": "^3.0.0",
"@actions/github": "^9.0.0", "@actions/github": "^9.0.0",
"@actions/glob": "^0.6.1", "@actions/glob": "^0.6.1",

View File

@ -33,7 +33,7 @@
"node": ">=24" "node": ">=24"
}, },
"dependencies": { "dependencies": {
"@actions/artifact": "^6.1.0", "@actions/artifact": "^6.2.0",
"@actions/core": "^3.0.0", "@actions/core": "^3.0.0",
"@actions/github": "^9.0.0", "@actions/github": "^9.0.0",
"@actions/glob": "^0.6.1", "@actions/glob": "^0.6.1",

View File

@ -6,7 +6,8 @@ export enum Inputs {
RetentionDays = 'retention-days', RetentionDays = 'retention-days',
CompressionLevel = 'compression-level', CompressionLevel = 'compression-level',
Overwrite = 'overwrite', Overwrite = 'overwrite',
IncludeHiddenFiles = 'include-hidden-files' IncludeHiddenFiles = 'include-hidden-files',
Archive = 'archive'
} }
export enum NoFileOptions { export enum NoFileOptions {

View File

@ -10,6 +10,7 @@ export function getInputs(): UploadInputs {
const path = core.getInput(Inputs.Path, {required: true}) const path = core.getInput(Inputs.Path, {required: true})
const overwrite = core.getBooleanInput(Inputs.Overwrite) const overwrite = core.getBooleanInput(Inputs.Overwrite)
const includeHiddenFiles = core.getBooleanInput(Inputs.IncludeHiddenFiles) const includeHiddenFiles = core.getBooleanInput(Inputs.IncludeHiddenFiles)
const archive = core.getBooleanInput(Inputs.Archive)
const ifNoFilesFound = core.getInput(Inputs.IfNoFilesFound) const ifNoFilesFound = core.getInput(Inputs.IfNoFilesFound)
const noFileBehavior: NoFileOptions = NoFileOptions[ifNoFilesFound] const noFileBehavior: NoFileOptions = NoFileOptions[ifNoFilesFound]
@ -29,7 +30,8 @@ export function getInputs(): UploadInputs {
searchPath: path, searchPath: path,
ifNoFilesFound: noFileBehavior, ifNoFilesFound: noFileBehavior,
overwrite: overwrite, overwrite: overwrite,
includeHiddenFiles: includeHiddenFiles includeHiddenFiles: includeHiddenFiles,
archive: archive
} as UploadInputs } as UploadInputs
const retentionDaysStr = core.getInput(Inputs.RetentionDays) const retentionDaysStr = core.getInput(Inputs.RetentionDays)

View File

@ -57,6 +57,14 @@ export async function run(): Promise<void> {
) )
core.debug(`Root artifact directory is ${searchResult.rootDirectory}`) core.debug(`Root artifact directory is ${searchResult.rootDirectory}`)
// Validate that only a single file is uploaded when archive is false
if (!inputs.archive && searchResult.filesToUpload.length > 1) {
core.setFailed(
`When 'archive' is set to false, only a single file can be uploaded. Found ${searchResult.filesToUpload.length} files to upload.`
)
return
}
if (inputs.overwrite) { if (inputs.overwrite) {
await deleteArtifactIfExists(inputs.artifactName) await deleteArtifactIfExists(inputs.artifactName)
} }
@ -70,6 +78,10 @@ export async function run(): Promise<void> {
options.compressionLevel = inputs.compressionLevel options.compressionLevel = inputs.compressionLevel
} }
if (!inputs.archive) {
options.skipArchive = true
}
await uploadArtifact( await uploadArtifact(
inputs.artifactName, inputs.artifactName,
searchResult.filesToUpload, searchResult.filesToUpload,

View File

@ -35,4 +35,10 @@ export interface UploadInputs {
* Whether or not to include hidden files in the artifact * Whether or not to include hidden files in the artifact
*/ */
includeHiddenFiles: boolean includeHiddenFiles: boolean
/**
* Whether or not to archive (zip) the artifact before uploading.
* When false, only a single file can be uploaded.
*/
archive: boolean
} }