add new overwrite input & docs

This commit is contained in:
Rob Herley
2024-01-18 13:31:03 -05:00
parent 1eb3cb2b3e
commit 11ff42c7b1
10 changed files with 536 additions and 26 deletions
+32 -1
View File
@@ -24,6 +24,7 @@ See also [download-artifact](https://github.com/actions/download-artifact).
- [Using Outputs](#using-outputs)
- [Example output between steps](#example-output-between-steps)
- [Example output between jobs](#example-output-between-jobs)
- [Overwriting an Artifact](#overwriting-an-artifact)
- [Limitations](#limitations)
- [Number of Artifacts](#number-of-artifacts)
- [Zip archives](#zip-archives)
@@ -44,7 +45,7 @@ For more information, see the [`@actions/artifact`](https://github.com/actions/t
1. Uploads are significantly faster, upwards of 90% improvement in worst case scenarios.
2. Once uploaded, an Artifact ID is returned and Artifacts are immediately available in the UI and [REST API](https://docs.github.com/en/rest/actions/artifacts). Previously, you would have to wait for the run to be completed before an ID was available or any APIs could be utilized.
3. The contents of an Artifact are uploaded together into an _immutable_ archive. They cannot be altered by subsequent jobs. Both of these factors help reduce the possibility of accidentally corrupting Artifact files.
3. The contents of an Artifact are uploaded together into an _immutable_ archive. They cannot be altered by subsequent jobs unless the Artifacts are deleted and recreated (where they will have a new ID). Both of these factors help reduce the possibility of accidentally corrupting Artifact files.
4. The compression level of an Artifact can be manually tweaked for speed or size reduction.
### Breaking Changes
@@ -365,6 +366,36 @@ jobs:
run: echo "Artifact ID from previous job is $OUTPUT1"
```
### Overwriting an Artifact
Although it's not possible to mutate an Artifact, can completely overwrite one. But do note that this will give the Artifact a new ID, the previous one will no longer exist:
```yaml
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Create a file
run: echo "hello world" > my-file.txt
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
upload-again:
needs: upload
runs-on: ubuntu-latest
steps:
- name: Create a different file
run: echo "goodbye world" > my-file.txt
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
overwrite: true
```
## Limitations
### Number of Artifacts
+6
View File
@@ -34,6 +34,12 @@ inputs:
Higher levels will result in better compression, but will take longer to complete.
For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads.
default: '6'
overwrite:
description: >
If true, an artifact matching name will be deleted before a new one is uploaded.
If false, the action will fail if an artifact for the given name already exists.
Does not fail if the artifact does not exist.
default: 'false'
outputs:
artifact-id:
+393 -13
View File
File diff suppressed because one or more lines are too long
+64
View File
@@ -2,6 +2,7 @@
- [Migration](#migration)
- [Multiple uploads to the same named Artifact](#multiple-uploads-to-the-same-named-artifact)
- [Overwriting an Artifact](#overwriting-an-artifact)
Several behavioral differences exist between Artifact actions `v3` and below vs `v4`. This document outlines common scenarios in `v3`, and how they would be handled in `v4`.
@@ -78,3 +79,66 @@ jobs:
```
In `v4`, the new `pattern:` input will filter the downloaded Artifacts to match the name specified. The new `merge-multiple:` input will support downloading multiple Artifacts to the same directory. If the files within the Artifacts have the same name, the last writer wins.
## Overwriting an Artifact
In `v3`, the contents of an Artifact were mutable so something like the following was possible:
```yaml
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Create a file
run: echo "hello world" > my-file.txt
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
upload-again:
needs: upload
runs-on: ubuntu-latest
steps:
- name: Create a different file
run: echo "goodbye world" > my-file.txt
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
```
The resulting `my-file.txt` in `my-artifact` will have "goodbye world" as the content.
In `v4`, Artifacts are immutable unless deleted. To achieve this same behavior, you can use `overwrite: true` to delete the Artifact before a new one is created:
```diff
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Create a file
run: echo "hello world" > my-file.txt
- name: Upload Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
upload-again:
needs: upload
runs-on: ubuntu-latest
steps:
- name: Create a different file
run: echo "goodbye world" > my-file.txt
- name: Upload Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: my-artifact # NOTE: same artifact name
path: my-file.txt
+ overwrite: true
```
Note that this will create an _entirely_ new Artifact, with a different ID from the previous.
+7 -7
View File
@@ -9,7 +9,7 @@
"version": "4.0.0",
"license": "MIT",
"dependencies": {
"@actions/artifact": "^2.0.0",
"@actions/artifact": "^2.1.0",
"@actions/core": "^1.10.0",
"@actions/github": "^6.0.0",
"@actions/glob": "^0.3.0",
@@ -33,9 +33,9 @@
}
},
"node_modules/@actions/artifact": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-2.0.0.tgz",
"integrity": "sha512-rr1yJ7/2c4i/OdQ9G0MXJfV4svPgqe+UfNWOK2+jZghTVJatJJAlJskJFK+RqzTyX8qn6CWgG/w7tJRNDzNnhQ==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-2.1.0.tgz",
"integrity": "sha512-R7RI/5tnbOAWPrkKisB0DK58K5jMiizk1weoQQSN9m20dhCmRhGsQtOzNCVeAbOBXewn//1ddbGKKrtlSEvIUg==",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/github": "^5.1.1",
@@ -7518,9 +7518,9 @@
},
"dependencies": {
"@actions/artifact": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-2.0.0.tgz",
"integrity": "sha512-rr1yJ7/2c4i/OdQ9G0MXJfV4svPgqe+UfNWOK2+jZghTVJatJJAlJskJFK+RqzTyX8qn6CWgG/w7tJRNDzNnhQ==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-2.1.0.tgz",
"integrity": "sha512-R7RI/5tnbOAWPrkKisB0DK58K5jMiizk1weoQQSN9m20dhCmRhGsQtOzNCVeAbOBXewn//1ddbGKKrtlSEvIUg==",
"requires": {
"@actions/core": "^1.10.0",
"@actions/github": "^5.1.1",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "upload-artifact",
"version": "4.0.0",
"version": "4.2.0",
"description": "Upload an Actions Artifact in a workflow run",
"main": "dist/index.js",
"scripts": {
@@ -29,7 +29,7 @@
},
"homepage": "https://github.com/actions/upload-artifact#readme",
"dependencies": {
"@actions/artifact": "^2.0.0",
"@actions/artifact": "^2.1.0",
"@actions/core": "^1.10.0",
"@actions/github": "^6.0.0",
"@actions/glob": "^0.3.0",
+2 -1
View File
@@ -4,7 +4,8 @@ export enum Inputs {
Path = 'path',
IfNoFilesFound = 'if-no-files-found',
RetentionDays = 'retention-days',
CompressionLevel = 'compression-level'
CompressionLevel = 'compression-level',
Overwrite = 'overwrite'
}
export enum NoFileOptions {
+3 -1
View File
@@ -8,6 +8,7 @@ import {UploadInputs} from './upload-inputs'
export function getInputs(): UploadInputs {
const name = core.getInput(Inputs.Name)
const path = core.getInput(Inputs.Path, {required: true})
const overwrite = core.getBooleanInput(Inputs.Overwrite)
const ifNoFilesFound = core.getInput(Inputs.IfNoFilesFound)
const noFileBehavior: NoFileOptions = NoFileOptions[ifNoFilesFound]
@@ -25,7 +26,8 @@ export function getInputs(): UploadInputs {
const inputs = {
artifactName: name,
searchPath: path,
ifNoFilesFound: noFileBehavior
ifNoFilesFound: noFileBehavior,
overwrite: overwrite
} as UploadInputs
const retentionDaysStr = core.getInput(Inputs.RetentionDays)
+22 -1
View File
@@ -1,10 +1,27 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import artifact, {UploadArtifactOptions} from '@actions/artifact'
import artifact, {
UploadArtifactOptions,
ArtifactNotFoundError
} from '@actions/artifact'
import {findFilesToUpload} from './search'
import {getInputs} from './input-helper'
import {NoFileOptions} from './constants'
async function deleteArtifactIfExists(artifactName: string): Promise<void> {
try {
await artifact.deleteArtifact(artifactName)
} catch (error) {
if (error instanceof ArtifactNotFoundError) {
core.debug(`Skipping deletion of '${artifactName}', it does not exist`)
return
}
// Best effort, we don't want to fail the action if this fails
core.debug(`Unable to delete artifact: ${(error as Error).message}`)
}
}
async function run(): Promise<void> {
try {
const inputs = getInputs()
@@ -38,6 +55,10 @@ async function run(): Promise<void> {
)
core.debug(`Root artifact directory is ${searchResult.rootDirectory}`)
if (inputs.overwrite) {
await deleteArtifactIfExists(inputs.artifactName)
}
const options: UploadArtifactOptions = {}
if (inputs.retentionDays) {
options.retentionDays = inputs.retentionDays
+5
View File
@@ -25,4 +25,9 @@ export interface UploadInputs {
* The level of compression for Zlib to be applied to the artifact archive.
*/
compressionLevel?: number
/**
* Whether or not to replace an existing artifact with the same name
*/
overwrite: boolean
}