From 8b22fe549bf4c1a8e0b37de2f371c8c4ff23dc32 Mon Sep 17 00:00:00 2001 From: Robear Selwans Date: Tue, 5 May 2026 18:23:13 +0300 Subject: [PATCH] Support multiple unarchived file uploads --- PATCH.md | 5 ++++- README.md | 24 +++++++++++++++++------- action.yml | 4 ++-- dist/upload/index.js | 24 ++++++++++++++++-------- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/PATCH.md b/PATCH.md index 173bae4..849b235 100644 --- a/PATCH.md +++ b/PATCH.md @@ -1,3 +1,6 @@ Vendored from actions/upload-artifact v7.0.1. -Patch: dist/upload/index.js isGhes() returns false so Gitea Actions is not rejected as GHES. +Patches: + +- `dist/upload/index.js` `isGhes()` returns false so Gitea Actions is not rejected as GHES. +- `archive: false` supports multiple matched files by uploading each file as a separate unarchived artifact named after the file basename. diff --git a/README.md b/README.md index e1fb5a3..e6b6068 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,31 @@ A Gitea-compatible vendored copy of `actions/upload-artifact@v7.0.1`. -The bundled `dist/upload/index.js` is patched so `isGhes()` returns `false`. -Gitea sets `GITHUB_SERVER_URL` to the Gitea instance URL, which upstream -`actions/upload-artifact@v7` mis-detects as GitHub Enterprise Server and rejects -before it can use Gitea's artifact runtime service. +The bundled `dist/upload/index.js` includes two Gitea patches: + +1. `isGhes()` returns `false`. Gitea sets `GITHUB_SERVER_URL` to the Gitea + instance URL, which upstream `actions/upload-artifact@v7` mis-detects as + GitHub Enterprise Server and rejects before it can use Gitea's artifact + runtime service. +2. `archive: false` accepts multiple matched files. Upstream v7 only permits one + unarchived file; this fork uploads every matched file as a separate + unarchived artifact named after that file's basename. ## Usage ```yaml -- uses: mo7sen/upload-artifact-gitea@v7 +- uses: https://git.neosisyphus.com/mo7sen/upload-artifact-gitea@v7 with: - name: meson-log.txt - path: build/meson-logs/meson-log.txt + path: | + build/meson-logs/meson-log.txt + build/meson-logs/testlog.txt archive: false ``` +With `archive: false`, each matched file is uploaded unzipped as its own +artifact. The artifact name is the file basename, so `name` is ignored in this +mode. + ## Upstream Based on . diff --git a/action.yml b/action.yml index 1ce8bfa..1f7c22a 100644 --- a/action.yml +++ b/action.yml @@ -48,8 +48,8 @@ inputs: 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 (ignoring the `name` parameter). + If false, files will be uploaded as-is without archiving. + When `archive` is `false`, every matched file is uploaded as a separate unarchived artifact. The basename of each file is used as the artifact name (ignoring the `name` parameter). default: 'true' outputs: diff --git a/dist/upload/index.js b/dist/upload/index.js index 14b7590..4a6a8ec 100644 --- a/dist/upload/index.js +++ b/dist/upload/index.js @@ -130597,14 +130597,6 @@ 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); - } const options = {}; if (inputs.retentionDays) { options.retentionDays = inputs.retentionDays; @@ -130614,6 +130606,22 @@ async function run() { } if (!inputs.archive) { options.skipArchive = true; + // Gitea patch: upstream upload-artifact@v7 only supports skipArchive + // for one file per artifact. Accept multi-path/multi-file input by + // creating one unarchived artifact for each matched file. In + // skipArchive mode the library names the artifact after the file's + // basename, matching upstream single-file behavior. + for (const fileToUpload of searchResult.filesToUpload) { + const artifactName = external_path_.basename(fileToUpload); + if (inputs.overwrite) { + await deleteArtifactIfExists(artifactName); + } + await upload_artifact_uploadArtifact(artifactName, [fileToUpload], searchResult.rootDirectory, options); + } + return; + } + if (inputs.overwrite) { + await deleteArtifactIfExists(inputs.artifactName); } await upload_artifact_uploadArtifact(inputs.artifactName, searchResult.filesToUpload, searchResult.rootDirectory, options); }