1
0
mirror of https://github.com/actions/upload-artifact.git synced 2026-02-25 21:22:28 +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.CompressionLevel]: 6,
[Inputs.Overwrite]: false,
[Inputs.Archive]: true,
...overrides
}

View File

@ -3,10 +3,10 @@ description: 'Upload a build artifact that can be used by subsequent workflow st
author: 'GitHub'
inputs:
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'
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
if-no-files-found:
description: >
@ -45,6 +45,12 @@ inputs:
If true, hidden files will be included in the artifact.
If false, hidden files will be excluded from the artifact.
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:
artifact-id:

13
dist/upload/index.js vendored
View File

@ -130457,6 +130457,7 @@ var Inputs;
Inputs["CompressionLevel"] = "compression-level";
Inputs["Overwrite"] = "overwrite";
Inputs["IncludeHiddenFiles"] = "include-hidden-files";
Inputs["Archive"] = "archive";
})(Inputs || (Inputs = {}));
var NoFileOptions;
(function (NoFileOptions) {
@ -130485,6 +130486,7 @@ function getInputs() {
const path = getInput(Inputs.Path, { required: true });
const overwrite = getBooleanInput(Inputs.Overwrite);
const includeHiddenFiles = getBooleanInput(Inputs.IncludeHiddenFiles);
const archive = getBooleanInput(Inputs.Archive);
const ifNoFilesFound = getInput(Inputs.IfNoFilesFound);
const noFileBehavior = NoFileOptions[ifNoFilesFound];
if (!noFileBehavior) {
@ -130495,7 +130497,8 @@ function getInputs() {
searchPath: path,
ifNoFilesFound: noFileBehavior,
overwrite: overwrite,
includeHiddenFiles: includeHiddenFiles
includeHiddenFiles: includeHiddenFiles,
archive: archive
};
const retentionDaysStr = getInput(Inputs.RetentionDays);
if (retentionDaysStr) {
@ -130576,6 +130579,11 @@ async function run() {
const s = searchResult.filesToUpload.length === 1 ? '' : 's';
info(`With the provided path, there will be ${searchResult.filesToUpload.length} file${s} uploaded`);
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) {
await deleteArtifactIfExists(inputs.artifactName);
}
@ -130586,6 +130594,9 @@ async function run() {
if (typeof inputs.compressionLevel !== 'undefined') {
options.compressionLevel = inputs.compressionLevel;
}
if (!inputs.archive) {
options.skipArchive = true;
}
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",
"license": "MIT",
"dependencies": {
"@actions/artifact": "^6.1.0",
"@actions/artifact": "^6.2.0",
"@actions/core": "^3.0.0",
"@actions/github": "^9.0.0",
"@actions/glob": "^0.6.1",

View File

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

View File

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

View File

@ -10,6 +10,7 @@ export function getInputs(): UploadInputs {
const path = core.getInput(Inputs.Path, {required: true})
const overwrite = core.getBooleanInput(Inputs.Overwrite)
const includeHiddenFiles = core.getBooleanInput(Inputs.IncludeHiddenFiles)
const archive = core.getBooleanInput(Inputs.Archive)
const ifNoFilesFound = core.getInput(Inputs.IfNoFilesFound)
const noFileBehavior: NoFileOptions = NoFileOptions[ifNoFilesFound]
@ -29,7 +30,8 @@ export function getInputs(): UploadInputs {
searchPath: path,
ifNoFilesFound: noFileBehavior,
overwrite: overwrite,
includeHiddenFiles: includeHiddenFiles
includeHiddenFiles: includeHiddenFiles,
archive: archive
} as UploadInputs
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}`)
// 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) {
await deleteArtifactIfExists(inputs.artifactName)
}
@ -70,6 +78,10 @@ export async function run(): Promise<void> {
options.compressionLevel = inputs.compressionLevel
}
if (!inputs.archive) {
options.skipArchive = true
}
await uploadArtifact(
inputs.artifactName,
searchResult.filesToUpload,

View File

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