mirror of
https://github.com/actions/upload-artifact.git
synced 2024-11-25 08:56:55 +01:00
add new overwrite input & docs
This commit is contained in:
parent
1eb3cb2b3e
commit
11ff42c7b1
10 changed files with 536 additions and 26 deletions
33
README.md
33
README.md
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
406
dist/index.js
vendored
406
dist/index.js
vendored
|
@ -824,7 +824,7 @@ __exportStar(__nccwpck_require__(63077), exports);
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.ArtifactService = exports.GetSignedArtifactURLResponse = exports.GetSignedArtifactURLRequest = exports.ListArtifactsResponse_MonolithArtifact = exports.ListArtifactsResponse = exports.ListArtifactsRequest = exports.FinalizeArtifactResponse = exports.FinalizeArtifactRequest = exports.CreateArtifactResponse = exports.CreateArtifactRequest = void 0;
|
||||
exports.ArtifactService = exports.DeleteArtifactResponse = exports.DeleteArtifactRequest = exports.GetSignedArtifactURLResponse = exports.GetSignedArtifactURLRequest = exports.ListArtifactsResponse_MonolithArtifact = exports.ListArtifactsResponse = exports.ListArtifactsRequest = exports.FinalizeArtifactResponse = exports.FinalizeArtifactRequest = exports.CreateArtifactResponse = exports.CreateArtifactRequest = void 0;
|
||||
// @generated by protobuf-ts 2.9.1 with parameter long_type_string,client_none,generate_dependencies
|
||||
// @generated from protobuf file "results/api/v1/artifact.proto" (package "github.actions.results.api.v1", syntax proto3)
|
||||
// tslint:disable
|
||||
|
@ -1400,6 +1400,121 @@ class GetSignedArtifactURLResponse$Type extends runtime_5.MessageType {
|
|||
* @generated MessageType for protobuf message github.actions.results.api.v1.GetSignedArtifactURLResponse
|
||||
*/
|
||||
exports.GetSignedArtifactURLResponse = new GetSignedArtifactURLResponse$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class DeleteArtifactRequest$Type extends runtime_5.MessageType {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.DeleteArtifactRequest", [
|
||||
{ no: 1, name: "workflow_run_backend_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 2, name: "workflow_job_run_backend_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 3, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value) {
|
||||
const message = { workflowRunBackendId: "", workflowJobRunBackendId: "", name: "" };
|
||||
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader, length, options, target) {
|
||||
let message = target !== null && target !== void 0 ? target : this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* string workflow_run_backend_id */ 1:
|
||||
message.workflowRunBackendId = reader.string();
|
||||
break;
|
||||
case /* string workflow_job_run_backend_id */ 2:
|
||||
message.workflowJobRunBackendId = reader.string();
|
||||
break;
|
||||
case /* string name */ 3:
|
||||
message.name = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? runtime_2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message, writer, options) {
|
||||
/* string workflow_run_backend_id = 1; */
|
||||
if (message.workflowRunBackendId !== "")
|
||||
writer.tag(1, runtime_1.WireType.LengthDelimited).string(message.workflowRunBackendId);
|
||||
/* string workflow_job_run_backend_id = 2; */
|
||||
if (message.workflowJobRunBackendId !== "")
|
||||
writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.workflowJobRunBackendId);
|
||||
/* string name = 3; */
|
||||
if (message.name !== "")
|
||||
writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.name);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.DeleteArtifactRequest
|
||||
*/
|
||||
exports.DeleteArtifactRequest = new DeleteArtifactRequest$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class DeleteArtifactResponse$Type extends runtime_5.MessageType {
|
||||
constructor() {
|
||||
super("github.actions.results.api.v1.DeleteArtifactResponse", [
|
||||
{ no: 1, name: "ok", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
||||
{ no: 2, name: "artifact_id", kind: "scalar", T: 3 /*ScalarType.INT64*/ }
|
||||
]);
|
||||
}
|
||||
create(value) {
|
||||
const message = { ok: false, artifactId: "0" };
|
||||
globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
(0, runtime_3.reflectionMergePartial)(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader, length, options, target) {
|
||||
let message = target !== null && target !== void 0 ? target : this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* bool ok */ 1:
|
||||
message.ok = reader.bool();
|
||||
break;
|
||||
case /* int64 artifact_id */ 2:
|
||||
message.artifactId = reader.int64().toString();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? runtime_2.UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message, writer, options) {
|
||||
/* bool ok = 1; */
|
||||
if (message.ok !== false)
|
||||
writer.tag(1, runtime_1.WireType.Varint).bool(message.ok);
|
||||
/* int64 artifact_id = 2; */
|
||||
if (message.artifactId !== "0")
|
||||
writer.tag(2, runtime_1.WireType.Varint).int64(message.artifactId);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message github.actions.results.api.v1.DeleteArtifactResponse
|
||||
*/
|
||||
exports.DeleteArtifactResponse = new DeleteArtifactResponse$Type();
|
||||
/**
|
||||
* @generated ServiceType for protobuf service github.actions.results.api.v1.ArtifactService
|
||||
*/
|
||||
|
@ -1407,7 +1522,8 @@ exports.ArtifactService = new runtime_rpc_1.ServiceType("github.actions.results.
|
|||
{ name: "CreateArtifact", options: {}, I: exports.CreateArtifactRequest, O: exports.CreateArtifactResponse },
|
||||
{ name: "FinalizeArtifact", options: {}, I: exports.FinalizeArtifactRequest, O: exports.FinalizeArtifactResponse },
|
||||
{ name: "ListArtifacts", options: {}, I: exports.ListArtifactsRequest, O: exports.ListArtifactsResponse },
|
||||
{ name: "GetSignedArtifactURL", options: {}, I: exports.GetSignedArtifactURLRequest, O: exports.GetSignedArtifactURLResponse }
|
||||
{ name: "GetSignedArtifactURL", options: {}, I: exports.GetSignedArtifactURLRequest, O: exports.GetSignedArtifactURLResponse },
|
||||
{ name: "DeleteArtifact", options: {}, I: exports.DeleteArtifactRequest, O: exports.DeleteArtifactResponse }
|
||||
]);
|
||||
//# sourceMappingURL=artifact.js.map
|
||||
|
||||
|
@ -1438,6 +1554,7 @@ class ArtifactServiceClientJSON {
|
|||
this.FinalizeArtifact.bind(this);
|
||||
this.ListArtifacts.bind(this);
|
||||
this.GetSignedArtifactURL.bind(this);
|
||||
this.DeleteArtifact.bind(this);
|
||||
}
|
||||
CreateArtifact(request) {
|
||||
const data = artifact_1.CreateArtifactRequest.toJson(request, {
|
||||
|
@ -1477,6 +1594,16 @@ class ArtifactServiceClientJSON {
|
|||
ignoreUnknownFields: true,
|
||||
}));
|
||||
}
|
||||
DeleteArtifact(request) {
|
||||
const data = artifact_1.DeleteArtifactRequest.toJson(request, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
});
|
||||
const promise = this.rpc.request("github.actions.results.api.v1.ArtifactService", "DeleteArtifact", "application/json", data);
|
||||
return promise.then((data) => artifact_1.DeleteArtifactResponse.fromJson(data, {
|
||||
ignoreUnknownFields: true,
|
||||
}));
|
||||
}
|
||||
}
|
||||
exports.ArtifactServiceClientJSON = ArtifactServiceClientJSON;
|
||||
class ArtifactServiceClientProtobuf {
|
||||
|
@ -1486,6 +1613,7 @@ class ArtifactServiceClientProtobuf {
|
|||
this.FinalizeArtifact.bind(this);
|
||||
this.ListArtifacts.bind(this);
|
||||
this.GetSignedArtifactURL.bind(this);
|
||||
this.DeleteArtifact.bind(this);
|
||||
}
|
||||
CreateArtifact(request) {
|
||||
const data = artifact_1.CreateArtifactRequest.toBinary(request);
|
||||
|
@ -1507,6 +1635,11 @@ class ArtifactServiceClientProtobuf {
|
|||
const promise = this.rpc.request("github.actions.results.api.v1.ArtifactService", "GetSignedArtifactURL", "application/protobuf", data);
|
||||
return promise.then((data) => artifact_1.GetSignedArtifactURLResponse.fromBinary(data));
|
||||
}
|
||||
DeleteArtifact(request) {
|
||||
const data = artifact_1.DeleteArtifactRequest.toBinary(request);
|
||||
const promise = this.rpc.request("github.actions.results.api.v1.ArtifactService", "DeleteArtifact", "application/protobuf", data);
|
||||
return promise.then((data) => artifact_1.DeleteArtifactResponse.fromBinary(data));
|
||||
}
|
||||
}
|
||||
exports.ArtifactServiceClientProtobuf = ArtifactServiceClientProtobuf;
|
||||
var ArtifactServiceMethod;
|
||||
|
@ -1515,12 +1648,14 @@ var ArtifactServiceMethod;
|
|||
ArtifactServiceMethod["FinalizeArtifact"] = "FinalizeArtifact";
|
||||
ArtifactServiceMethod["ListArtifacts"] = "ListArtifacts";
|
||||
ArtifactServiceMethod["GetSignedArtifactURL"] = "GetSignedArtifactURL";
|
||||
ArtifactServiceMethod["DeleteArtifact"] = "DeleteArtifact";
|
||||
})(ArtifactServiceMethod || (exports.ArtifactServiceMethod = ArtifactServiceMethod = {}));
|
||||
exports.ArtifactServiceMethodList = [
|
||||
ArtifactServiceMethod.CreateArtifact,
|
||||
ArtifactServiceMethod.FinalizeArtifact,
|
||||
ArtifactServiceMethod.ListArtifacts,
|
||||
ArtifactServiceMethod.GetSignedArtifactURL,
|
||||
ArtifactServiceMethod.DeleteArtifact,
|
||||
];
|
||||
function createArtifactServiceServer(service) {
|
||||
return new twirp_ts_1.TwirpServer({
|
||||
|
@ -1558,6 +1693,12 @@ function matchArtifactServiceRoute(method, events) {
|
|||
yield events.onMatch(ctx);
|
||||
return handleArtifactServiceGetSignedArtifactURLRequest(ctx, service, data, interceptors);
|
||||
});
|
||||
case "DeleteArtifact":
|
||||
return (ctx, service, data, interceptors) => __awaiter(this, void 0, void 0, function* () {
|
||||
ctx = Object.assign(Object.assign({}, ctx), { methodName: "DeleteArtifact" });
|
||||
yield events.onMatch(ctx);
|
||||
return handleArtifactServiceDeleteArtifactRequest(ctx, service, data, interceptors);
|
||||
});
|
||||
default:
|
||||
events.onNotFound();
|
||||
const msg = `no handler found`;
|
||||
|
@ -1608,6 +1749,17 @@ function handleArtifactServiceGetSignedArtifactURLRequest(ctx, service, data, in
|
|||
throw new twirp_ts_1.TwirpError(twirp_ts_1.TwirpErrorCode.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
function handleArtifactServiceDeleteArtifactRequest(ctx, service, data, interceptors) {
|
||||
switch (ctx.contentType) {
|
||||
case twirp_ts_1.TwirpContentType.JSON:
|
||||
return handleArtifactServiceDeleteArtifactJSON(ctx, service, data, interceptors);
|
||||
case twirp_ts_1.TwirpContentType.Protobuf:
|
||||
return handleArtifactServiceDeleteArtifactProtobuf(ctx, service, data, interceptors);
|
||||
default:
|
||||
const msg = "unexpected Content-Type";
|
||||
throw new twirp_ts_1.TwirpError(twirp_ts_1.TwirpErrorCode.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
function handleArtifactServiceCreateArtifactJSON(ctx, service, data, interceptors) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let request;
|
||||
|
@ -1732,6 +1884,37 @@ function handleArtifactServiceGetSignedArtifactURLJSON(ctx, service, data, inter
|
|||
}));
|
||||
});
|
||||
}
|
||||
function handleArtifactServiceDeleteArtifactJSON(ctx, service, data, interceptors) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let request;
|
||||
let response;
|
||||
try {
|
||||
const body = JSON.parse(data.toString() || "{}");
|
||||
request = artifact_1.DeleteArtifactRequest.fromJson(body, {
|
||||
ignoreUnknownFields: true,
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the json request could not be decoded";
|
||||
throw new twirp_ts_1.TwirpError(twirp_ts_1.TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = (0, twirp_ts_1.chainInterceptors)(...interceptors);
|
||||
response = yield interceptor(ctx, request, (ctx, inputReq) => {
|
||||
return service.DeleteArtifact(ctx, inputReq);
|
||||
});
|
||||
}
|
||||
else {
|
||||
response = yield service.DeleteArtifact(ctx, request);
|
||||
}
|
||||
return JSON.stringify(artifact_1.DeleteArtifactResponse.toJson(response, {
|
||||
useProtoFieldName: true,
|
||||
emitDefaultValues: false,
|
||||
}));
|
||||
});
|
||||
}
|
||||
function handleArtifactServiceCreateArtifactProtobuf(ctx, service, data, interceptors) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let request;
|
||||
|
@ -1832,6 +2015,31 @@ function handleArtifactServiceGetSignedArtifactURLProtobuf(ctx, service, data, i
|
|||
return Buffer.from(artifact_1.GetSignedArtifactURLResponse.toBinary(response));
|
||||
});
|
||||
}
|
||||
function handleArtifactServiceDeleteArtifactProtobuf(ctx, service, data, interceptors) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let request;
|
||||
let response;
|
||||
try {
|
||||
request = artifact_1.DeleteArtifactRequest.fromBinary(data);
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the protobuf request could not be decoded";
|
||||
throw new twirp_ts_1.TwirpError(twirp_ts_1.TwirpErrorCode.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = (0, twirp_ts_1.chainInterceptors)(...interceptors);
|
||||
response = yield interceptor(ctx, request, (ctx, inputReq) => {
|
||||
return service.DeleteArtifact(ctx, inputReq);
|
||||
});
|
||||
}
|
||||
else {
|
||||
response = yield service.DeleteArtifact(ctx, request);
|
||||
}
|
||||
return Buffer.from(artifact_1.DeleteArtifactResponse.toBinary(response));
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=artifact.twirp.js.map
|
||||
|
||||
/***/ }),
|
||||
|
@ -1867,6 +2075,7 @@ const core_1 = __nccwpck_require__(42186);
|
|||
const config_1 = __nccwpck_require__(74610);
|
||||
const upload_artifact_1 = __nccwpck_require__(42578);
|
||||
const download_artifact_1 = __nccwpck_require__(73555);
|
||||
const delete_artifact_1 = __nccwpck_require__(70071);
|
||||
const get_artifact_1 = __nccwpck_require__(29491);
|
||||
const list_artifacts_1 = __nccwpck_require__(44141);
|
||||
const errors_1 = __nccwpck_require__(38182);
|
||||
|
@ -1953,6 +2162,28 @@ If the error persists, please check whether Actions and API requests are operati
|
|||
|
||||
Errors can be temporary, so please try again and optionally run the action with debug mode enabled for more information.
|
||||
|
||||
If the error persists, please check whether Actions and API requests are operating normally at [https://githubstatus.com](https://www.githubstatus.com).`);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
deleteArtifact(artifactName, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
if ((0, config_1.isGhes)()) {
|
||||
throw new errors_1.GHESNotSupportedError();
|
||||
}
|
||||
if (options === null || options === void 0 ? void 0 : options.findBy) {
|
||||
const { findBy: { repositoryOwner, repositoryName, workflowRunId, token } } = options;
|
||||
return (0, delete_artifact_1.deleteArtifactPublic)(artifactName, workflowRunId, repositoryOwner, repositoryName, token);
|
||||
}
|
||||
return (0, delete_artifact_1.deleteArtifactInternal)(artifactName);
|
||||
}
|
||||
catch (error) {
|
||||
(0, core_1.warning)(`Delete Artifact failed with error: ${error}.
|
||||
|
||||
Errors can be temporary, so please try again and optionally run the action with debug mode enabled for more information.
|
||||
|
||||
If the error persists, please check whether Actions and API requests are operating normally at [https://githubstatus.com](https://www.githubstatus.com).`);
|
||||
throw error;
|
||||
}
|
||||
|
@ -1964,6 +2195,96 @@ exports.DefaultArtifactClient = DefaultArtifactClient;
|
|||
|
||||
/***/ }),
|
||||
|
||||
/***/ 70071:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.deleteArtifactInternal = exports.deleteArtifactPublic = void 0;
|
||||
const core_1 = __nccwpck_require__(42186);
|
||||
const github_1 = __nccwpck_require__(21260);
|
||||
const user_agent_1 = __nccwpck_require__(85164);
|
||||
const retry_options_1 = __nccwpck_require__(64597);
|
||||
const utils_1 = __nccwpck_require__(58154);
|
||||
const plugin_request_log_1 = __nccwpck_require__(68883);
|
||||
const plugin_retry_1 = __nccwpck_require__(86298);
|
||||
const artifact_twirp_client_1 = __nccwpck_require__(12312);
|
||||
const util_1 = __nccwpck_require__(63062);
|
||||
const generated_1 = __nccwpck_require__(49960);
|
||||
const get_artifact_1 = __nccwpck_require__(29491);
|
||||
const errors_1 = __nccwpck_require__(38182);
|
||||
function deleteArtifactPublic(artifactName, workflowRunId, repositoryOwner, repositoryName, token) {
|
||||
var _a;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const [retryOpts, requestOpts] = (0, retry_options_1.getRetryOptions)(utils_1.defaults);
|
||||
const opts = {
|
||||
log: undefined,
|
||||
userAgent: (0, user_agent_1.getUserAgentString)(),
|
||||
previews: undefined,
|
||||
retry: retryOpts,
|
||||
request: requestOpts
|
||||
};
|
||||
const github = (0, github_1.getOctokit)(token, opts, plugin_retry_1.retry, plugin_request_log_1.requestLog);
|
||||
const getArtifactResp = yield (0, get_artifact_1.getArtifactPublic)(artifactName, workflowRunId, repositoryOwner, repositoryName, token);
|
||||
const deleteArtifactResp = yield github.rest.actions.deleteArtifact({
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
artifact_id: getArtifactResp.artifact.id
|
||||
});
|
||||
if (deleteArtifactResp.status !== 204) {
|
||||
throw new errors_1.InvalidResponseError(`Invalid response from GitHub API: ${deleteArtifactResp.status} (${(_a = deleteArtifactResp === null || deleteArtifactResp === void 0 ? void 0 : deleteArtifactResp.headers) === null || _a === void 0 ? void 0 : _a['x-github-request-id']})`);
|
||||
}
|
||||
return {
|
||||
id: getArtifactResp.artifact.id
|
||||
};
|
||||
});
|
||||
}
|
||||
exports.deleteArtifactPublic = deleteArtifactPublic;
|
||||
function deleteArtifactInternal(artifactName) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const artifactClient = (0, artifact_twirp_client_1.internalArtifactTwirpClient)();
|
||||
const { workflowRunBackendId, workflowJobRunBackendId } = (0, util_1.getBackendIdsFromToken)();
|
||||
const listReq = {
|
||||
workflowRunBackendId,
|
||||
workflowJobRunBackendId,
|
||||
nameFilter: generated_1.StringValue.create({ value: artifactName })
|
||||
};
|
||||
const listRes = yield artifactClient.ListArtifacts(listReq);
|
||||
if (listRes.artifacts.length === 0) {
|
||||
throw new errors_1.ArtifactNotFoundError(`Artifact not found for name: ${artifactName}`);
|
||||
}
|
||||
let artifact = listRes.artifacts[0];
|
||||
if (listRes.artifacts.length > 1) {
|
||||
artifact = listRes.artifacts.sort((a, b) => Number(b.databaseId) - Number(a.databaseId))[0];
|
||||
(0, core_1.debug)(`More than one artifact found for a single name, returning newest (id: ${artifact.databaseId})`);
|
||||
}
|
||||
const req = {
|
||||
workflowRunBackendId: artifact.workflowRunBackendId,
|
||||
workflowJobRunBackendId: artifact.workflowJobRunBackendId,
|
||||
name: artifact.name
|
||||
};
|
||||
const res = yield artifactClient.DeleteArtifact(req);
|
||||
(0, core_1.info)(`Artifact '${artifactName}' (ID: ${res.artifactId}) deleted`);
|
||||
return {
|
||||
id: Number(res.artifactId)
|
||||
};
|
||||
});
|
||||
}
|
||||
exports.deleteArtifactInternal = deleteArtifactInternal;
|
||||
//# sourceMappingURL=delete-artifact.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 73555:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
|
@ -2005,7 +2326,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.downloadArtifactInternal = exports.downloadArtifactPublic = void 0;
|
||||
exports.downloadArtifactInternal = exports.downloadArtifactPublic = exports.streamExtractExternal = void 0;
|
||||
const promises_1 = __importDefault(__nccwpck_require__(73292));
|
||||
const github = __importStar(__nccwpck_require__(21260));
|
||||
const core = __importStar(__nccwpck_require__(42186));
|
||||
|
@ -2039,20 +2360,57 @@ function exists(path) {
|
|||
});
|
||||
}
|
||||
function streamExtract(url, directory) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let retryCount = 0;
|
||||
while (retryCount < 5) {
|
||||
try {
|
||||
yield streamExtractExternal(url, directory);
|
||||
return;
|
||||
}
|
||||
catch (error) {
|
||||
retryCount++;
|
||||
core.debug(`Failed to download artifact after ${retryCount} retries due to ${error.message}. Retrying in 5 seconds...`);
|
||||
// wait 5 seconds before retrying
|
||||
yield new Promise(resolve => setTimeout(resolve, 5000));
|
||||
}
|
||||
}
|
||||
throw new Error(`Artifact download failed after ${retryCount} retries.`);
|
||||
});
|
||||
}
|
||||
function streamExtractExternal(url, directory) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const client = new httpClient.HttpClient((0, user_agent_1.getUserAgentString)());
|
||||
const response = yield client.get(url);
|
||||
if (response.message.statusCode !== 200) {
|
||||
throw new Error(`Unexpected HTTP response from blob storage: ${response.message.statusCode} ${response.message.statusMessage}`);
|
||||
}
|
||||
const timeout = 30 * 1000; // 30 seconds
|
||||
return new Promise((resolve, reject) => {
|
||||
const timerFn = () => {
|
||||
response.message.destroy(new Error(`Blob storage chunk did not respond in ${timeout}ms`));
|
||||
};
|
||||
const timer = setTimeout(timerFn, timeout);
|
||||
response.message
|
||||
.on('data', () => {
|
||||
timer.refresh();
|
||||
})
|
||||
.on('error', (error) => {
|
||||
core.debug(`response.message: Artifact download failed: ${error.message}`);
|
||||
clearTimeout(timer);
|
||||
reject(error);
|
||||
})
|
||||
.pipe(unzip_stream_1.default.Extract({ path: directory }))
|
||||
.on('close', resolve)
|
||||
.on('error', reject);
|
||||
.on('close', () => {
|
||||
clearTimeout(timer);
|
||||
resolve();
|
||||
})
|
||||
.on('error', (error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.streamExtractExternal = streamExtractExternal;
|
||||
function downloadArtifactPublic(artifactId, repositoryOwner, repositoryName, token, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const downloadPath = yield resolveOrCreateDirectory(options === null || options === void 0 ? void 0 : options.path);
|
||||
|
@ -2211,7 +2569,9 @@ function getArtifactPublic(artifactName, workflowRunId, repositoryOwner, reposit
|
|||
throw new errors_1.InvalidResponseError(`Invalid response from GitHub API: ${getArtifactResp.status} (${(_a = getArtifactResp === null || getArtifactResp === void 0 ? void 0 : getArtifactResp.headers) === null || _a === void 0 ? void 0 : _a['x-github-request-id']})`);
|
||||
}
|
||||
if (getArtifactResp.data.artifacts.length === 0) {
|
||||
throw new errors_1.ArtifactNotFoundError(`Artifact not found for name: ${artifactName}`);
|
||||
throw new errors_1.ArtifactNotFoundError(`Artifact not found for name: ${artifactName}
|
||||
Please ensure that your artifact is not expired and the artifact was uploaded using a compatible version of toolkit/upload-artifact.
|
||||
For more information, visit the GitHub Artifacts FAQ: https://github.com/actions/toolkit/blob/main/packages/artifact/docs/faq.md`);
|
||||
}
|
||||
let artifact = getArtifactResp.data.artifacts[0];
|
||||
if (getArtifactResp.data.artifacts.length > 1) {
|
||||
|
@ -2240,7 +2600,9 @@ function getArtifactInternal(artifactName) {
|
|||
};
|
||||
const res = yield artifactClient.ListArtifacts(req);
|
||||
if (res.artifacts.length === 0) {
|
||||
throw new errors_1.ArtifactNotFoundError(`Artifact not found for name: ${artifactName}`);
|
||||
throw new errors_1.ArtifactNotFoundError(`Artifact not found for name: ${artifactName}
|
||||
Please ensure that your artifact is not expired and the artifact was uploaded using a compatible version of toolkit/upload-artifact.
|
||||
For more information, visit the GitHub Artifacts FAQ: https://github.com/actions/toolkit/blob/main/packages/artifact/docs/faq.md`);
|
||||
}
|
||||
let artifact = res.artifacts[0];
|
||||
if (res.artifacts.length > 1) {
|
||||
|
@ -126721,6 +127083,7 @@ var Inputs;
|
|||
Inputs["IfNoFilesFound"] = "if-no-files-found";
|
||||
Inputs["RetentionDays"] = "retention-days";
|
||||
Inputs["CompressionLevel"] = "compression-level";
|
||||
Inputs["Overwrite"] = "overwrite";
|
||||
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
||||
var NoFileOptions;
|
||||
(function (NoFileOptions) {
|
||||
|
@ -126779,6 +127142,7 @@ const constants_1 = __nccwpck_require__(69042);
|
|||
function getInputs() {
|
||||
const name = core.getInput(constants_1.Inputs.Name);
|
||||
const path = core.getInput(constants_1.Inputs.Path, { required: true });
|
||||
const overwrite = core.getBooleanInput(constants_1.Inputs.Overwrite);
|
||||
const ifNoFilesFound = core.getInput(constants_1.Inputs.IfNoFilesFound);
|
||||
const noFileBehavior = constants_1.NoFileOptions[ifNoFilesFound];
|
||||
if (!noFileBehavior) {
|
||||
|
@ -126787,7 +127151,8 @@ function getInputs() {
|
|||
const inputs = {
|
||||
artifactName: name,
|
||||
searchPath: path,
|
||||
ifNoFilesFound: noFileBehavior
|
||||
ifNoFilesFound: noFileBehavior,
|
||||
overwrite: overwrite
|
||||
};
|
||||
const retentionDaysStr = core.getInput(constants_1.Inputs.RetentionDays);
|
||||
if (retentionDaysStr) {
|
||||
|
@ -127018,16 +127383,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const core = __importStar(__nccwpck_require__(42186));
|
||||
const github = __importStar(__nccwpck_require__(95438));
|
||||
const artifact_1 = __importDefault(__nccwpck_require__(79450));
|
||||
const artifact_1 = __importStar(__nccwpck_require__(79450));
|
||||
const search_1 = __nccwpck_require__(13930);
|
||||
const input_helper_1 = __nccwpck_require__(46455);
|
||||
const constants_1 = __nccwpck_require__(69042);
|
||||
function deleteArtifactIfExists(artifactName) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield artifact_1.default.deleteArtifact(artifactName);
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof artifact_1.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.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
|
@ -127054,6 +127431,9 @@ function run() {
|
|||
const s = searchResult.filesToUpload.length === 1 ? '' : 's';
|
||||
core.info(`With the provided path, there will be ${searchResult.filesToUpload.length} file${s} uploaded`);
|
||||
core.debug(`Root artifact directory is ${searchResult.rootDirectory}`);
|
||||
if (inputs.overwrite) {
|
||||
yield deleteArtifactIfExists(inputs.artifactName);
|
||||
}
|
||||
const options = {};
|
||||
if (inputs.retentionDays) {
|
||||
options.retentionDays = inputs.retentionDays;
|
||||
|
@ -128967,7 +129347,7 @@ module.exports = parseParams
|
|||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = JSON.parse('{"name":"@actions/artifact","version":"2.0.0","preview":true,"description":"Actions artifact lib","keywords":["github","actions","artifact"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/artifact","license":"MIT","main":"lib/artifact.js","types":"lib/artifact.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/artifact"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"cd ../../ && npm run test ./packages/artifact","bootstrap":"cd ../../ && npm run bootstrap","tsc-run":"tsc","tsc":"npm run bootstrap && npm run tsc-run","gen:docs":"typedoc --plugin typedoc-plugin-markdown --out docs/generated src/artifact.ts --githubPages false --readme none"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.10.0","@actions/github":"^5.1.1","@actions/http-client":"^2.1.0","@azure/storage-blob":"^12.15.0","@octokit/core":"^3.5.1","@octokit/plugin-request-log":"^1.0.4","@octokit/plugin-retry":"^3.0.9","@octokit/request-error":"^5.0.0","@protobuf-ts/plugin":"^2.2.3-alpha.1","archiver":"^5.3.1","crypto":"^1.0.1","jwt-decode":"^3.1.2","twirp-ts":"^2.5.0","unzip-stream":"^0.3.1"},"devDependencies":{"@types/archiver":"^5.3.2","@types/unzip-stream":"^0.3.4","typedoc":"^0.25.4","typedoc-plugin-markdown":"^3.17.1","typescript":"^5.2.2"}}');
|
||||
module.exports = JSON.parse('{"name":"@actions/artifact","version":"2.1.0","preview":true,"description":"Actions artifact lib","keywords":["github","actions","artifact"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/artifact","license":"MIT","main":"lib/artifact.js","types":"lib/artifact.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/artifact"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"cd ../../ && npm run test ./packages/artifact","bootstrap":"cd ../../ && npm run bootstrap","tsc-run":"tsc","tsc":"npm run bootstrap && npm run tsc-run","gen:docs":"typedoc --plugin typedoc-plugin-markdown --out docs/generated src/artifact.ts --githubPages false --readme none"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.10.0","@actions/github":"^5.1.1","@actions/http-client":"^2.1.0","@azure/storage-blob":"^12.15.0","@octokit/core":"^3.5.1","@octokit/plugin-request-log":"^1.0.4","@octokit/plugin-retry":"^3.0.9","@octokit/request-error":"^5.0.0","@protobuf-ts/plugin":"^2.2.3-alpha.1","archiver":"^5.3.1","crypto":"^1.0.1","jwt-decode":"^3.1.2","twirp-ts":"^2.5.0","unzip-stream":"^0.3.1"},"devDependencies":{"@types/archiver":"^5.3.2","@types/unzip-stream":"^0.3.4","typedoc":"^0.25.4","typedoc-plugin-markdown":"^3.17.1","typescript":"^5.2.2"}}');
|
||||
|
||||
/***/ }),
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue