initial commit of actions

This commit is contained in:
Dominik Polakovics Polakovics 2026-01-31 18:56:04 +01:00
commit 949ece5785
44660 changed files with 12034344 additions and 0 deletions

View file

@ -0,0 +1,12 @@
import { ZipUploadStream } from './zip';
export interface BlobUploadResponse {
/**
* The total reported upload size in bytes. Empty if the upload failed
*/
uploadSize?: number;
/**
* The SHA256 hash of the uploaded file. Empty if the upload failed
*/
sha256Hash?: string;
}
export declare function uploadZipToBlobStorage(authenticatedUploadURL: string, zipUploadStream: ZipUploadStream): Promise<BlobUploadResponse>;

View file

@ -0,0 +1,110 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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.uploadZipToBlobStorage = void 0;
const storage_blob_1 = require("@azure/storage-blob");
const config_1 = require("../shared/config");
const core = __importStar(require("@actions/core"));
const crypto = __importStar(require("crypto"));
const stream = __importStar(require("stream"));
const errors_1 = require("../shared/errors");
function uploadZipToBlobStorage(authenticatedUploadURL, zipUploadStream) {
return __awaiter(this, void 0, void 0, function* () {
let uploadByteCount = 0;
let lastProgressTime = Date.now();
const abortController = new AbortController();
const chunkTimer = (interval) => __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
const timer = setInterval(() => {
if (Date.now() - lastProgressTime > interval) {
reject(new Error('Upload progress stalled.'));
}
}, interval);
abortController.signal.addEventListener('abort', () => {
clearInterval(timer);
resolve();
});
});
});
const maxConcurrency = (0, config_1.getConcurrency)();
const bufferSize = (0, config_1.getUploadChunkSize)();
const blobClient = new storage_blob_1.BlobClient(authenticatedUploadURL);
const blockBlobClient = blobClient.getBlockBlobClient();
core.debug(`Uploading artifact zip to blob storage with maxConcurrency: ${maxConcurrency}, bufferSize: ${bufferSize}`);
const uploadCallback = (progress) => {
core.info(`Uploaded bytes ${progress.loadedBytes}`);
uploadByteCount = progress.loadedBytes;
lastProgressTime = Date.now();
};
const options = {
blobHTTPHeaders: { blobContentType: 'zip' },
onProgress: uploadCallback,
abortSignal: abortController.signal
};
let sha256Hash = undefined;
const uploadStream = new stream.PassThrough();
const hashStream = crypto.createHash('sha256');
zipUploadStream.pipe(uploadStream); // This stream is used for the upload
zipUploadStream.pipe(hashStream).setEncoding('hex'); // This stream is used to compute a hash of the zip content that gets used. Integrity check
core.info('Beginning upload of artifact content to blob storage');
try {
yield Promise.race([
blockBlobClient.uploadStream(uploadStream, bufferSize, maxConcurrency, options),
chunkTimer((0, config_1.getUploadChunkTimeout)())
]);
}
catch (error) {
if (errors_1.NetworkError.isNetworkErrorCode(error === null || error === void 0 ? void 0 : error.code)) {
throw new errors_1.NetworkError(error === null || error === void 0 ? void 0 : error.code);
}
throw error;
}
finally {
abortController.abort();
}
core.info('Finished uploading artifact content to blob storage!');
hashStream.end();
sha256Hash = hashStream.read();
core.info(`SHA256 hash of uploaded artifact zip is ${sha256Hash}`);
if (uploadByteCount === 0) {
core.warning(`No data was uploaded to blob storage. Reported upload byte count is 0.`);
}
return {
uploadSize: uploadByteCount,
sha256Hash
};
});
}
exports.uploadZipToBlobStorage = uploadZipToBlobStorage;
//# sourceMappingURL=blob-upload.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"blob-upload.js","sourceRoot":"","sources":["../../../src/internal/upload/blob-upload.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1,8 @@
/**
* Validates the name of the artifact to check to make sure there are no illegal characters
*/
export declare function validateArtifactName(name: string): void;
/**
* Validates file paths to check for any illegal characters that can cause problems on different file systems
*/
export declare function validateFilePath(path: string): void;

View file

@ -0,0 +1,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateFilePath = exports.validateArtifactName = void 0;
const core_1 = require("@actions/core");
/**
* Invalid characters that cannot be in the artifact name or an uploaded file. Will be rejected
* from the server if attempted to be sent over. These characters are not allowed due to limitations with certain
* file systems such as NTFS. To maintain platform-agnostic behavior, all characters that are not supported by an
* individual filesystem/platform will not be supported on all fileSystems/platforms
*
* FilePaths can include characters such as \ and / which are not permitted in the artifact name alone
*/
const invalidArtifactFilePathCharacters = new Map([
['"', ' Double quote "'],
[':', ' Colon :'],
['<', ' Less than <'],
['>', ' Greater than >'],
['|', ' Vertical bar |'],
['*', ' Asterisk *'],
['?', ' Question mark ?'],
['\r', ' Carriage return \\r'],
['\n', ' Line feed \\n']
]);
const invalidArtifactNameCharacters = new Map([
...invalidArtifactFilePathCharacters,
['\\', ' Backslash \\'],
['/', ' Forward slash /']
]);
/**
* Validates the name of the artifact to check to make sure there are no illegal characters
*/
function validateArtifactName(name) {
if (!name) {
throw new Error(`Provided artifact name input during validation is empty`);
}
for (const [invalidCharacterKey, errorMessageForCharacter] of invalidArtifactNameCharacters) {
if (name.includes(invalidCharacterKey)) {
throw new Error(`The artifact name is not valid: ${name}. Contains the following character: ${errorMessageForCharacter}
Invalid characters include: ${Array.from(invalidArtifactNameCharacters.values()).toString()}
These characters are not allowed in the artifact name due to limitations with certain file systems such as NTFS. To maintain file system agnostic behavior, these characters are intentionally not allowed to prevent potential problems with downloads on different file systems.`);
}
}
(0, core_1.info)(`Artifact name is valid!`);
}
exports.validateArtifactName = validateArtifactName;
/**
* Validates file paths to check for any illegal characters that can cause problems on different file systems
*/
function validateFilePath(path) {
if (!path) {
throw new Error(`Provided file path input during validation is empty`);
}
for (const [invalidCharacterKey, errorMessageForCharacter] of invalidArtifactFilePathCharacters) {
if (path.includes(invalidCharacterKey)) {
throw new Error(`The path for one of the files in artifact is not valid: ${path}. Contains the following character: ${errorMessageForCharacter}
Invalid characters include: ${Array.from(invalidArtifactFilePathCharacters.values()).toString()}
The following characters are not allowed in files that are uploaded due to limitations with certain file systems such as NTFS. To maintain file system agnostic behavior, these characters are intentionally not allowed to prevent potential problems with downloads on different file systems.
`);
}
}
}
exports.validateFilePath = validateFilePath;
//# sourceMappingURL=path-and-artifact-name-validation.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"path-and-artifact-name-validation.js","sourceRoot":"","sources":["../../../src/internal/upload/path-and-artifact-name-validation.ts"],"names":[],"mappings":";;;AAAA,wCAAkC;AAElC;;;;;;;GAOG;AACH,MAAM,iCAAiC,GAAG,IAAI,GAAG,CAAiB;IAChE,CAAC,GAAG,EAAE,iBAAiB,CAAC;IACxB,CAAC,GAAG,EAAE,UAAU,CAAC;IACjB,CAAC,GAAG,EAAE,cAAc,CAAC;IACrB,CAAC,GAAG,EAAE,iBAAiB,CAAC;IACxB,CAAC,GAAG,EAAE,iBAAiB,CAAC;IACxB,CAAC,GAAG,EAAE,aAAa,CAAC;IACpB,CAAC,GAAG,EAAE,kBAAkB,CAAC;IACzB,CAAC,IAAI,EAAE,sBAAsB,CAAC;IAC9B,CAAC,IAAI,EAAE,gBAAgB,CAAC;CACzB,CAAC,CAAA;AAEF,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAiB;IAC5D,GAAG,iCAAiC;IACpC,CAAC,IAAI,EAAE,eAAe,CAAC;IACvB,CAAC,GAAG,EAAE,kBAAkB,CAAC;CAC1B,CAAC,CAAA;AAEF;;GAEG;AACH,SAAgB,oBAAoB,CAAC,IAAY;IAC/C,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;KAC3E;IAED,KAAK,MAAM,CACT,mBAAmB,EACnB,wBAAwB,CACzB,IAAI,6BAA6B,EAAE;QAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE;YACtC,MAAM,IAAI,KAAK,CACb,mCAAmC,IAAI,uCAAuC,wBAAwB;;8BAEhF,KAAK,CAAC,IAAI,CAC9B,6BAA6B,CAAC,MAAM,EAAE,CACvC,CAAC,QAAQ,EAAE;;mRAE+P,CAC5Q,CAAA;SACF;KACF;IAED,IAAA,WAAI,EAAC,yBAAyB,CAAC,CAAA;AACjC,CAAC;AAvBD,oDAuBC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;KACvE;IAED,KAAK,MAAM,CACT,mBAAmB,EACnB,wBAAwB,CACzB,IAAI,iCAAiC,EAAE;QACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE;YACtC,MAAM,IAAI,KAAK,CACb,2DAA2D,IAAI,uCAAuC,wBAAwB;;8BAExG,KAAK,CAAC,IAAI,CAC9B,iCAAiC,CAAC,MAAM,EAAE,CAC3C,CAAC,QAAQ,EAAE;;;WAGT,CACJ,CAAA;SACF;KACF;AACH,CAAC;AAtBD,4CAsBC"}

View file

@ -0,0 +1,2 @@
import { Timestamp } from '../../generated';
export declare function getExpiration(retentionDays?: number): Timestamp | undefined;

View file

@ -0,0 +1,54 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getExpiration = void 0;
const generated_1 = require("../../generated");
const core = __importStar(require("@actions/core"));
function getExpiration(retentionDays) {
if (!retentionDays) {
return undefined;
}
const maxRetentionDays = getRetentionDays();
if (maxRetentionDays && maxRetentionDays < retentionDays) {
core.warning(`Retention days cannot be greater than the maximum allowed retention set within the repository. Using ${maxRetentionDays} instead.`);
retentionDays = maxRetentionDays;
}
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + retentionDays);
return generated_1.Timestamp.fromDate(expirationDate);
}
exports.getExpiration = getExpiration;
function getRetentionDays() {
const retentionDays = process.env['GITHUB_RETENTION_DAYS'];
if (!retentionDays) {
return undefined;
}
const days = parseInt(retentionDays);
if (isNaN(days)) {
return undefined;
}
return days;
}
//# sourceMappingURL=retention.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"retention.js","sourceRoot":"","sources":["../../../src/internal/upload/retention.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAyC;AACzC,oDAAqC;AAErC,SAAgB,aAAa,CAAC,aAAsB;IAClD,IAAI,CAAC,aAAa,EAAE;QAClB,OAAO,SAAS,CAAA;KACjB;IAED,MAAM,gBAAgB,GAAG,gBAAgB,EAAE,CAAA;IAC3C,IAAI,gBAAgB,IAAI,gBAAgB,GAAG,aAAa,EAAE;QACxD,IAAI,CAAC,OAAO,CACV,wGAAwG,gBAAgB,WAAW,CACpI,CAAA;QACD,aAAa,GAAG,gBAAgB,CAAA;KACjC;IAED,MAAM,cAAc,GAAG,IAAI,IAAI,EAAE,CAAA;IACjC,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,aAAa,CAAC,CAAA;IAEhE,OAAO,qBAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAA;AAC3C,CAAC;AAjBD,sCAiBC;AAED,SAAS,gBAAgB;IACvB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;IAC1D,IAAI,CAAC,aAAa,EAAE;QAClB,OAAO,SAAS,CAAA;KACjB;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAA;IACpC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;QACf,OAAO,SAAS,CAAA;KACjB;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}

View file

@ -0,0 +1,2 @@
import { UploadArtifactOptions, UploadArtifactResponse } from '../shared/interfaces';
export declare function uploadArtifact(name: string, files: string[], rootDirectory: string, options?: UploadArtifactOptions | undefined): Promise<UploadArtifactResponse>;

View file

@ -0,0 +1,103 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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.uploadArtifact = void 0;
const core = __importStar(require("@actions/core"));
const retention_1 = require("./retention");
const path_and_artifact_name_validation_1 = require("./path-and-artifact-name-validation");
const artifact_twirp_client_1 = require("../shared/artifact-twirp-client");
const upload_zip_specification_1 = require("./upload-zip-specification");
const util_1 = require("../shared/util");
const blob_upload_1 = require("./blob-upload");
const zip_1 = require("./zip");
const generated_1 = require("../../generated");
const errors_1 = require("../shared/errors");
function uploadArtifact(name, files, rootDirectory, options) {
return __awaiter(this, void 0, void 0, function* () {
(0, path_and_artifact_name_validation_1.validateArtifactName)(name);
(0, upload_zip_specification_1.validateRootDirectory)(rootDirectory);
const zipSpecification = (0, upload_zip_specification_1.getUploadZipSpecification)(files, rootDirectory);
if (zipSpecification.length === 0) {
throw new errors_1.FilesNotFoundError(zipSpecification.flatMap(s => (s.sourcePath ? [s.sourcePath] : [])));
}
// get the IDs needed for the artifact creation
const backendIds = (0, util_1.getBackendIdsFromToken)();
// create the artifact client
const artifactClient = (0, artifact_twirp_client_1.internalArtifactTwirpClient)();
// create the artifact
const createArtifactReq = {
workflowRunBackendId: backendIds.workflowRunBackendId,
workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
name,
version: 4
};
// if there is a retention period, add it to the request
const expiresAt = (0, retention_1.getExpiration)(options === null || options === void 0 ? void 0 : options.retentionDays);
if (expiresAt) {
createArtifactReq.expiresAt = expiresAt;
}
const createArtifactResp = yield artifactClient.CreateArtifact(createArtifactReq);
if (!createArtifactResp.ok) {
throw new errors_1.InvalidResponseError('CreateArtifact: response from backend was not ok');
}
const zipUploadStream = yield (0, zip_1.createZipUploadStream)(zipSpecification, options === null || options === void 0 ? void 0 : options.compressionLevel);
// Upload zip to blob storage
const uploadResult = yield (0, blob_upload_1.uploadZipToBlobStorage)(createArtifactResp.signedUploadUrl, zipUploadStream);
// finalize the artifact
const finalizeArtifactReq = {
workflowRunBackendId: backendIds.workflowRunBackendId,
workflowJobRunBackendId: backendIds.workflowJobRunBackendId,
name,
size: uploadResult.uploadSize ? uploadResult.uploadSize.toString() : '0'
};
if (uploadResult.sha256Hash) {
finalizeArtifactReq.hash = generated_1.StringValue.create({
value: `sha256:${uploadResult.sha256Hash}`
});
}
core.info(`Finalizing artifact upload`);
const finalizeArtifactResp = yield artifactClient.FinalizeArtifact(finalizeArtifactReq);
if (!finalizeArtifactResp.ok) {
throw new errors_1.InvalidResponseError('FinalizeArtifact: response from backend was not ok');
}
const artifactId = BigInt(finalizeArtifactResp.artifactId);
core.info(`Artifact ${name}.zip successfully finalized. Artifact ID ${artifactId}`);
return {
size: uploadResult.uploadSize,
id: Number(artifactId)
};
});
}
exports.uploadArtifact = uploadArtifact;
//# sourceMappingURL=upload-artifact.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"upload-artifact.js","sourceRoot":"","sources":["../../../src/internal/upload/upload-artifact.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1,21 @@
export interface UploadZipSpecification {
/**
* An absolute source path that points to a file that will be added to a zip. Null if creating a new directory
*/
sourcePath: string | null;
/**
* The destination path in a zip for a file
*/
destinationPath: string;
}
/**
* Checks if a root directory exists and is valid
* @param rootDirectory an absolute root directory path common to all input files that that will be trimmed from the final zip structure
*/
export declare function validateRootDirectory(rootDirectory: string): void;
/**
* Creates a specification that describes how a zip file will be created for a set of input files
* @param filesToZip a list of file that should be included in the zip
* @param rootDirectory an absolute root directory path common to all input files that that will be trimmed from the final zip structure
*/
export declare function getUploadZipSpecification(filesToZip: string[], rootDirectory: string): UploadZipSpecification[];

View file

@ -0,0 +1,113 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUploadZipSpecification = exports.validateRootDirectory = void 0;
const fs = __importStar(require("fs"));
const core_1 = require("@actions/core");
const path_1 = require("path");
const path_and_artifact_name_validation_1 = require("./path-and-artifact-name-validation");
/**
* Checks if a root directory exists and is valid
* @param rootDirectory an absolute root directory path common to all input files that that will be trimmed from the final zip structure
*/
function validateRootDirectory(rootDirectory) {
if (!fs.existsSync(rootDirectory)) {
throw new Error(`The provided rootDirectory ${rootDirectory} does not exist`);
}
if (!fs.statSync(rootDirectory).isDirectory()) {
throw new Error(`The provided rootDirectory ${rootDirectory} is not a valid directory`);
}
(0, core_1.info)(`Root directory input is valid!`);
}
exports.validateRootDirectory = validateRootDirectory;
/**
* Creates a specification that describes how a zip file will be created for a set of input files
* @param filesToZip a list of file that should be included in the zip
* @param rootDirectory an absolute root directory path common to all input files that that will be trimmed from the final zip structure
*/
function getUploadZipSpecification(filesToZip, rootDirectory) {
const specification = [];
// Normalize and resolve, this allows for either absolute or relative paths to be used
rootDirectory = (0, path_1.normalize)(rootDirectory);
rootDirectory = (0, path_1.resolve)(rootDirectory);
/*
Example
Input:
rootDirectory: '/home/user/files/plz-upload'
artifactFiles: [
'/home/user/files/plz-upload/file1.txt',
'/home/user/files/plz-upload/file2.txt',
'/home/user/files/plz-upload/dir/file3.txt'
]
Output:
specifications: [
['/home/user/files/plz-upload/file1.txt', '/file1.txt'],
['/home/user/files/plz-upload/file1.txt', '/file2.txt'],
['/home/user/files/plz-upload/file1.txt', '/dir/file3.txt']
]
The final zip that is later uploaded will look like this:
my-artifact.zip
- file.txt
- file2.txt
- dir/
- file3.txt
*/
for (let file of filesToZip) {
if (!fs.existsSync(file)) {
throw new Error(`File ${file} does not exist`);
}
if (!fs.statSync(file).isDirectory()) {
// Normalize and resolve, this allows for either absolute or relative paths to be used
file = (0, path_1.normalize)(file);
file = (0, path_1.resolve)(file);
if (!file.startsWith(rootDirectory)) {
throw new Error(`The rootDirectory: ${rootDirectory} is not a parent directory of the file: ${file}`);
}
// Check for forbidden characters in file paths that may cause ambiguous behavior if downloaded on different file systems
const uploadPath = file.replace(rootDirectory, '');
(0, path_and_artifact_name_validation_1.validateFilePath)(uploadPath);
specification.push({
sourcePath: file,
destinationPath: uploadPath
});
}
else {
// Empty directory
const directoryPath = file.replace(rootDirectory, '');
(0, path_and_artifact_name_validation_1.validateFilePath)(directoryPath);
specification.push({
sourcePath: null,
destinationPath: directoryPath
});
}
}
return specification;
}
exports.getUploadZipSpecification = getUploadZipSpecification;
//# sourceMappingURL=upload-zip-specification.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"upload-zip-specification.js","sourceRoot":"","sources":["../../../src/internal/upload/upload-zip-specification.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAwB;AACxB,wCAAkC;AAClC,+BAAuC;AACvC,2FAAoE;AAcpE;;;GAGG;AACH,SAAgB,qBAAqB,CAAC,aAAqB;IACzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;QACjC,MAAM,IAAI,KAAK,CACb,8BAA8B,aAAa,iBAAiB,CAC7D,CAAA;KACF;IACD,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,EAAE;QAC7C,MAAM,IAAI,KAAK,CACb,8BAA8B,aAAa,2BAA2B,CACvE,CAAA;KACF;IACD,IAAA,WAAI,EAAC,gCAAgC,CAAC,CAAA;AACxC,CAAC;AAZD,sDAYC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CACvC,UAAoB,EACpB,aAAqB;IAErB,MAAM,aAAa,GAA6B,EAAE,CAAA;IAElD,sFAAsF;IACtF,aAAa,GAAG,IAAA,gBAAS,EAAC,aAAa,CAAC,CAAA;IACxC,aAAa,GAAG,IAAA,cAAO,EAAC,aAAa,CAAC,CAAA;IAEtC;;;;;;;;;;;;;;;;;;;;;;;;;MAyBE;IACF,KAAK,IAAI,IAAI,IAAI,UAAU,EAAE;QAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YACxB,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,iBAAiB,CAAC,CAAA;SAC/C;QACD,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;YACpC,sFAAsF;YACtF,IAAI,GAAG,IAAA,gBAAS,EAAC,IAAI,CAAC,CAAA;YACtB,IAAI,GAAG,IAAA,cAAO,EAAC,IAAI,CAAC,CAAA;YACpB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;gBACnC,MAAM,IAAI,KAAK,CACb,sBAAsB,aAAa,2CAA2C,IAAI,EAAE,CACrF,CAAA;aACF;YAED,yHAAyH;YACzH,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;YAClD,IAAA,oDAAgB,EAAC,UAAU,CAAC,CAAA;YAE5B,aAAa,CAAC,IAAI,CAAC;gBACjB,UAAU,EAAE,IAAI;gBAChB,eAAe,EAAE,UAAU;aAC5B,CAAC,CAAA;SACH;aAAM;YACL,kBAAkB;YAClB,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;YACrD,IAAA,oDAAgB,EAAC,aAAa,CAAC,CAAA;YAE/B,aAAa,CAAC,IAAI,CAAC;gBACjB,UAAU,EAAE,IAAI;gBAChB,eAAe,EAAE,aAAa;aAC/B,CAAC,CAAA;SACH;KACF;IACD,OAAO,aAAa,CAAA;AACtB,CAAC;AAtED,8DAsEC"}

View file

@ -0,0 +1,9 @@
/// <reference types="node" />
import * as stream from 'stream';
import { UploadZipSpecification } from './upload-zip-specification';
export declare const DEFAULT_COMPRESSION_LEVEL = 6;
export declare class ZipUploadStream extends stream.Transform {
constructor(bufferSize: number);
_transform(chunk: any, enc: any, cb: any): void;
}
export declare function createZipUploadStream(uploadSpecification: UploadZipSpecification[], compressionLevel?: number): Promise<ZipUploadStream>;

View file

@ -0,0 +1,112 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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.createZipUploadStream = exports.ZipUploadStream = exports.DEFAULT_COMPRESSION_LEVEL = void 0;
const stream = __importStar(require("stream"));
const archiver = __importStar(require("archiver"));
const core = __importStar(require("@actions/core"));
const config_1 = require("../shared/config");
exports.DEFAULT_COMPRESSION_LEVEL = 6;
// Custom stream transformer so we can set the highWaterMark property
// See https://github.com/nodejs/node/issues/8855
class ZipUploadStream extends stream.Transform {
constructor(bufferSize) {
super({
highWaterMark: bufferSize
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_transform(chunk, enc, cb) {
cb(null, chunk);
}
}
exports.ZipUploadStream = ZipUploadStream;
function createZipUploadStream(uploadSpecification, compressionLevel = exports.DEFAULT_COMPRESSION_LEVEL) {
return __awaiter(this, void 0, void 0, function* () {
core.debug(`Creating Artifact archive with compressionLevel: ${compressionLevel}`);
const zip = archiver.create('zip', {
highWaterMark: (0, config_1.getUploadChunkSize)(),
zlib: { level: compressionLevel }
});
// register callbacks for various events during the zip lifecycle
zip.on('error', zipErrorCallback);
zip.on('warning', zipWarningCallback);
zip.on('finish', zipFinishCallback);
zip.on('end', zipEndCallback);
for (const file of uploadSpecification) {
if (file.sourcePath !== null) {
// Add a normal file to the zip
zip.file(file.sourcePath, {
name: file.destinationPath
});
}
else {
// Add a directory to the zip
zip.append('', { name: file.destinationPath });
}
}
const bufferSize = (0, config_1.getUploadChunkSize)();
const zipUploadStream = new ZipUploadStream(bufferSize);
core.debug(`Zip write high watermark value ${zipUploadStream.writableHighWaterMark}`);
core.debug(`Zip read high watermark value ${zipUploadStream.readableHighWaterMark}`);
zip.pipe(zipUploadStream);
zip.finalize();
return zipUploadStream;
});
}
exports.createZipUploadStream = createZipUploadStream;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const zipErrorCallback = (error) => {
core.error('An error has occurred while creating the zip file for upload');
core.info(error);
throw new Error('An error has occurred during zip creation for the artifact');
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const zipWarningCallback = (error) => {
if (error.code === 'ENOENT') {
core.warning('ENOENT warning during artifact zip creation. No such file or directory');
core.info(error);
}
else {
core.warning(`A non-blocking warning has occurred during artifact zip creation: ${error.code}`);
core.info(error);
}
};
const zipFinishCallback = () => {
core.debug('Zip stream for upload has finished.');
};
const zipEndCallback = () => {
core.debug('Zip stream for upload has ended.');
};
//# sourceMappingURL=zip.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"zip.js","sourceRoot":"","sources":["../../../src/internal/upload/zip.ts"],"names":[],"mappings":"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"}