diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e0fa2ad..b8171bd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,10 +10,6 @@ on: paths-ignore: - '**.md' -permissions: - contents: read - actions: write - jobs: build: name: Build @@ -98,7 +94,7 @@ jobs: # Download Artifact #1 and verify the correctness of the content - name: 'Download artifact #1' - uses: actions/download-artifact@main + uses: actions/download-artifact@v4 with: name: 'Artifact-A-${{ matrix.runs-on }}' path: some/new/path @@ -118,7 +114,7 @@ jobs: # Download Artifact #2 and verify the correctness of the content - name: 'Download artifact #2' - uses: actions/download-artifact@main + uses: actions/download-artifact@v4 with: name: 'Artifact-Wildcard-${{ matrix.runs-on }}' path: some/other/path @@ -139,7 +135,7 @@ jobs: # Download Artifact #4 and verify the correctness of the content - name: 'Download artifact #4' - uses: actions/download-artifact@main + uses: actions/download-artifact@v4 with: name: 'Multi-Path-Artifact-${{ matrix.runs-on }}' path: multi/artifact @@ -159,7 +155,7 @@ jobs: shell: pwsh - name: 'Download symlinked artifact' - uses: actions/download-artifact@main + uses: actions/download-artifact@v4 with: name: 'Symlinked-Artifact-${{ matrix.runs-on }}' path: from/symlink @@ -200,7 +196,7 @@ jobs: # Download replaced Artifact #1 and verify the correctness of the content - name: 'Download artifact #1 again' - uses: actions/download-artifact@main + uses: actions/download-artifact@v4 with: name: 'Artifact-A-${{ matrix.runs-on }}' path: overwrite/some/new/path @@ -217,101 +213,6 @@ jobs: Write-Error "File contents of downloaded artifact are incorrect" } shell: pwsh - - # Upload a single file without archiving (direct file upload) - - name: 'Create direct upload file' - run: echo -n 'direct file upload content' > direct-upload-${{ matrix.runs-on }}.txt - shell: bash - - - name: 'Upload direct file artifact' - uses: ./ - with: - name: 'Direct-File-${{ matrix.runs-on }}' - path: direct-upload-${{ matrix.runs-on }}.txt - archive: false - - - name: 'Download direct file artifact' - uses: actions/download-artifact@main - with: - name: direct-upload-${{ matrix.runs-on }}.txt - path: direct-download - - - name: 'Verify direct file artifact' - run: | - $file = "direct-download/direct-upload-${{ matrix.runs-on }}.txt" - if(!(Test-Path -path $file)) - { - Write-Error "Expected file does not exist" - } - if(!((Get-Content $file -Raw).TrimEnd() -ceq "direct file upload content")) - { - Write-Error "File contents of downloaded artifact are incorrect" - } - shell: pwsh - - upload-html-report: - name: Upload HTML Report - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node 24 - uses: actions/setup-node@v4 - with: - node-version: 24.x - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Compile - run: npm run build - - - name: Create HTML report - run: | - cat > report.html << 'EOF' - - - - - - Artifact Upload Test Report - - - -

Artifact Upload Test Report

-
- This HTML file was uploaded as a single un-zipped artifact. - If you can see this in the browser, the feature is working correctly! -
- - - - - -
PropertyValue
Upload methodarchive: false
Content-Typetext/html
Filereport.html
-

✔ Single file upload is working!

- - - EOF - - - name: Upload HTML report (no archive) - uses: ./ - with: - name: 'test-report' - path: report.html - archive: false - merge: name: Merge needs: build @@ -329,7 +230,7 @@ jobs: # easier to identify each of the merged artifacts separate-directories: true - name: 'Download merged artifacts' - uses: actions/download-artifact@main + uses: actions/download-artifact@v4 with: name: merged-artifacts path: all-merged-artifacts @@ -365,7 +266,7 @@ jobs: # Download merged artifacts and verify the correctness of the content - name: 'Download merged artifacts' - uses: actions/download-artifact@main + uses: actions/download-artifact@v4 with: name: Merged-Artifact-As path: merged-artifact-a @@ -389,40 +290,3 @@ jobs: } shell: pwsh - cleanup: - name: Cleanup Artifacts - needs: [build, merge] - runs-on: ubuntu-latest - - steps: - - name: Delete test artifacts - uses: actions/github-script@v8 - with: - script: | - const keep = ['report.html']; - const owner = context.repo.owner; - const repo = context.repo.repo; - const runId = context.runId; - - const {data: {artifacts}} = await github.rest.actions.listWorkflowRunArtifacts({ - owner, - repo, - run_id: runId - }); - - for (const a of artifacts) { - if (keep.includes(a.name)) { - console.log(`Keeping artifact '${a.name}'`); - continue; - } - try { - await github.rest.actions.deleteArtifact({ - owner, - repo, - artifact_id: a.id - }); - console.log(`Deleted artifact '${a.name}'`); - } catch (err) { - console.log(`Could not delete artifact '${a.name}': ${err.message}`); - } - } diff --git a/.licenses/npm/balanced-match-4.0.4.dep.yml b/.licenses/npm/balanced-match-4.0.4.dep.yml new file mode 100644 index 0000000..101c2c3 --- /dev/null +++ b/.licenses/npm/balanced-match-4.0.4.dep.yml @@ -0,0 +1,34 @@ +--- +name: balanced-match +version: 4.0.4 +type: npm +summary: Match balanced character pairs, like "{" and "}" +homepage: +license: mit +licenses: +- sources: LICENSE.md + text: | + (MIT) + + Original code Copyright Julian Gruber + + Port to TypeScript Copyright Isaac Z. Schlueter + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +notices: [] diff --git a/.licenses/npm/brace-expansion-5.0.3.dep.yml b/.licenses/npm/brace-expansion-5.0.3.dep.yml new file mode 100644 index 0000000..07359b8 --- /dev/null +++ b/.licenses/npm/brace-expansion-5.0.3.dep.yml @@ -0,0 +1,34 @@ +--- +name: brace-expansion +version: 5.0.3 +type: npm +summary: Brace expansion as known from sh/bash +homepage: +license: mit +licenses: +- sources: LICENSE + text: | + MIT License + + Copyright Julian Gruber + + TypeScript port Copyright Isaac Z. Schlueter + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +notices: [] diff --git a/.licenses/npm/fast-content-type-parse.dep.yml b/.licenses/npm/fast-content-type-parse.dep.yml new file mode 100644 index 0000000..e411b38 --- /dev/null +++ b/.licenses/npm/fast-content-type-parse.dep.yml @@ -0,0 +1,37 @@ +--- +name: fast-content-type-parse +version: 3.0.0 +type: npm +summary: Parse HTTP Content-Type header according to RFC 7231 +homepage: https://github.com/fastify/fast-content-type-parse#readme +license: other +licenses: +- sources: LICENSE + text: |- + MIT License + + Copyright (c) 2023 The Fastify Team + + The Fastify team members are listed at https://github.com/fastify/fastify#team + and in the README file. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +- sources: README.md + text: Licensed under [MIT](./LICENSE). +notices: [] diff --git a/.licenses/npm/json-with-bigint.dep.yml b/.licenses/npm/json-with-bigint.dep.yml new file mode 100644 index 0000000..d496868 --- /dev/null +++ b/.licenses/npm/json-with-bigint.dep.yml @@ -0,0 +1,33 @@ +--- +name: json-with-bigint +version: 3.5.3 +type: npm +summary: JS library that allows you to easily serialize and deserialize data with + BigInt values +homepage: +license: mit +licenses: +- sources: LICENSE + text: | + MIT License + + Copyright (c) 2023 Ivan Korolenko + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +notices: [] diff --git a/.licenses/npm/minimatch-9.0.8.dep.yml b/.licenses/npm/minimatch-9.0.8.dep.yml new file mode 100644 index 0000000..e8d3203 --- /dev/null +++ b/.licenses/npm/minimatch-9.0.8.dep.yml @@ -0,0 +1,66 @@ +--- +name: minimatch +version: 9.0.8 +type: npm +summary: +homepage: +license: blueoak-1.0.0 +licenses: +- sources: LICENSE.md + text: | + # Blue Oak Model License + + Version 1.0.0 + + ## Purpose + + This license gives everyone as much permission to work with + this software as possible, while protecting contributors + from liability. + + ## Acceptance + + In order to receive this license, you must agree to its + rules. The rules of this license are both obligations + under that agreement and conditions to your license. + You must not do anything with this software that triggers + a rule that you cannot or will not follow. + + ## Copyright + + Each contributor licenses you to do everything with this + software that would otherwise infringe that contributor's + copyright in it. + + ## Notices + + You must ensure that everyone who gets a copy of + any part of this software from you, with or without + changes, also gets the text of this license or a link to + . + + ## Excuse + + If anyone notifies you in writing that you have not + complied with [Notices](#notices), you can keep your + license by taking all practical steps to comply within 30 + days after the notice. If you do not do so, your license + ends immediately. + + ## Patent + + Each contributor licenses you to do everything with this + software that would otherwise infringe any patent claims + they can license or become able to license. + + ## Reliability + + No contributor can revoke this license. + + ## No Liability + + **_As far as the law allows, this software comes as is, + without any warranty or condition, and no contributor + will be liable to anyone for any damages related to this + software or this license, under any kind of legal claim._** +notices: [] diff --git a/.licenses/npm/minimatch.dep.yml b/.licenses/npm/minimatch.dep.yml index 8ed580a..b3a5b56 100644 --- a/.licenses/npm/minimatch.dep.yml +++ b/.licenses/npm/minimatch.dep.yml @@ -1,9 +1,9 @@ --- name: minimatch -version: 10.2.4 +version: 10.1.1 type: npm -summary: -homepage: +summary: a glob matcher in javascript +homepage: license: blueoak-1.0.0 licenses: - sources: LICENSE.md @@ -63,4 +63,4 @@ licenses: without any warranty or condition, and no contributor will be liable to anyone for any damages related to this software or this license, under any kind of legal claim._** -notices: [] +notices: [] \ No newline at end of file diff --git a/__tests__/upload.test.ts b/__tests__/upload.test.ts index de81a1c..6e0c26a 100644 --- a/__tests__/upload.test.ts +++ b/__tests__/upload.test.ts @@ -72,7 +72,6 @@ const mockInputs = ( [Inputs.RetentionDays]: 0, [Inputs.CompressionLevel]: 6, [Inputs.Overwrite]: false, - [Inputs.Archive]: true, ...overrides } @@ -274,57 +273,4 @@ describe('upload', () => { `Skipping deletion of '${fixtures.artifactName}', it does not exist` ) }) - - test('passes skipArchive when archive is false', async () => { - mockInputs({ - [Inputs.Archive]: false - }) - - mockFindFilesToUpload.mockResolvedValue({ - filesToUpload: [fixtures.filesToUpload[0]], - rootDirectory: fixtures.rootDirectory - }) - - await run() - - expect(artifact.default.uploadArtifact).toHaveBeenCalledWith( - fixtures.artifactName, - [fixtures.filesToUpload[0]], - fixtures.rootDirectory, - {compressionLevel: 6, skipArchive: true} - ) - }) - - test('does not pass skipArchive when archive is true', async () => { - mockInputs({ - [Inputs.Archive]: true - }) - - mockFindFilesToUpload.mockResolvedValue({ - filesToUpload: [fixtures.filesToUpload[0]], - rootDirectory: fixtures.rootDirectory - }) - - await run() - - expect(artifact.default.uploadArtifact).toHaveBeenCalledWith( - fixtures.artifactName, - [fixtures.filesToUpload[0]], - fixtures.rootDirectory, - {compressionLevel: 6} - ) - }) - - test('fails when archive is false and multiple files are provided', async () => { - mockInputs({ - [Inputs.Archive]: false - }) - - await run() - - expect(core.setFailed).toHaveBeenCalledWith( - `When 'archive' is set to false, only a single file can be uploaded. Found ${fixtures.filesToUpload.length} files to upload.` - ) - expect(artifact.default.uploadArtifact).not.toHaveBeenCalled() - }) }) diff --git a/action.yml b/action.yml index 7cb4d1e..28f04cc 100644 --- a/action.yml +++ b/action.yml @@ -3,10 +3,10 @@ description: 'Upload a build artifact that can be used by subsequent workflow st author: 'GitHub' inputs: name: - description: 'Artifact name. If the `archive` input is `false`, the name of the file uploaded will be the artifact name.' + description: '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,12 +45,6 @@ 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 (ignoring the `name` parameter). - default: 'true' outputs: artifact-id: diff --git a/dist/upload/index.js b/dist/upload/index.js index a4ca651..f08f27c 100644 --- a/dist/upload/index.js +++ b/dist/upload/index.js @@ -130457,7 +130457,6 @@ var Inputs; Inputs["CompressionLevel"] = "compression-level"; Inputs["Overwrite"] = "overwrite"; Inputs["IncludeHiddenFiles"] = "include-hidden-files"; - Inputs["Archive"] = "archive"; })(Inputs || (Inputs = {})); var NoFileOptions; (function (NoFileOptions) { @@ -130486,7 +130485,6 @@ 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) { @@ -130497,8 +130495,7 @@ function getInputs() { searchPath: path, ifNoFilesFound: noFileBehavior, overwrite: overwrite, - includeHiddenFiles: includeHiddenFiles, - archive: archive + includeHiddenFiles: includeHiddenFiles }; const retentionDaysStr = getInput(Inputs.RetentionDays); if (retentionDaysStr) { @@ -130579,11 +130576,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); } @@ -130594,9 +130586,6 @@ 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); } } diff --git a/package-lock.json b/package-lock.json index 5739b1d..a0c89f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "7.0.0", "license": "MIT", "dependencies": { - "@actions/artifact": "^6.2.0", + "@actions/artifact": "^6.1.0", "@actions/core": "^3.0.0", "@actions/github": "^9.0.0", "@actions/glob": "^0.6.1", diff --git a/package.json b/package.json index b71533f..c668d43 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "node": ">=24" }, "dependencies": { - "@actions/artifact": "^6.2.0", + "@actions/artifact": "^6.1.0", "@actions/core": "^3.0.0", "@actions/github": "^9.0.0", "@actions/glob": "^0.6.1", diff --git a/src/upload/constants.ts b/src/upload/constants.ts index 61ec717..8407bc1 100644 --- a/src/upload/constants.ts +++ b/src/upload/constants.ts @@ -6,8 +6,7 @@ export enum Inputs { RetentionDays = 'retention-days', CompressionLevel = 'compression-level', Overwrite = 'overwrite', - IncludeHiddenFiles = 'include-hidden-files', - Archive = 'archive' + IncludeHiddenFiles = 'include-hidden-files' } export enum NoFileOptions { diff --git a/src/upload/input-helper.ts b/src/upload/input-helper.ts index 29605c6..527ce6c 100644 --- a/src/upload/input-helper.ts +++ b/src/upload/input-helper.ts @@ -10,7 +10,6 @@ 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] @@ -30,8 +29,7 @@ export function getInputs(): UploadInputs { searchPath: path, ifNoFilesFound: noFileBehavior, overwrite: overwrite, - includeHiddenFiles: includeHiddenFiles, - archive: archive + includeHiddenFiles: includeHiddenFiles } as UploadInputs const retentionDaysStr = core.getInput(Inputs.RetentionDays) diff --git a/src/upload/upload-artifact.ts b/src/upload/upload-artifact.ts index 432ec11..1cffa3d 100644 --- a/src/upload/upload-artifact.ts +++ b/src/upload/upload-artifact.ts @@ -57,14 +57,6 @@ export async function run(): Promise { ) 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) } @@ -78,10 +70,6 @@ export async function run(): Promise { options.compressionLevel = inputs.compressionLevel } - if (!inputs.archive) { - options.skipArchive = true - } - await uploadArtifact( inputs.artifactName, searchResult.filesToUpload, diff --git a/src/upload/upload-inputs.ts b/src/upload/upload-inputs.ts index 61f221d..b3fa72e 100644 --- a/src/upload/upload-inputs.ts +++ b/src/upload/upload-inputs.ts @@ -35,10 +35,4 @@ 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 }