@process-engine/ci_tools
Version:
CI tools for process-engine.io
202 lines (199 loc) • 7.51 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateGitHubRelease = exports.printHelp = exports.getShortDoc = exports.run = void 0;
const glob = require("glob");
const mime = require("mime-types");
const rest_1 = require("@octokit/rest");
const Path = require("path");
const yargsParser = require("yargs-parser");
const fs_1 = require("fs");
const git_1 = require("../git/git");
const package_version_1 = require("../versions/package_version");
const setup_git_and_npm_connections_1 = require("./internal/setup-git-and-npm-connections");
const COMMAND_NAME = 'update-github-release';
const BADGE = `[${COMMAND_NAME}]\t`;
const DEFAULT_MODE = 'node';
const SKIP_CI_MESSAGE = '[skip ci]';
const DOC = `
Updates or creates a GitHub release using the current version (or given \`--version-tag\`).
Uploads all given \`--assets\`, resolving globs and updating existing assets on GitHub.
OPTIONS
--mode sets the package mode [dotnet, node, python] (default: node)
`;
// DOC: see above
async function run(...args) {
const argv = yargsParser(args, { default: { mode: DEFAULT_MODE } });
const isDryRun = argv.dry;
const mode = argv.mode;
let versionTag = argv.versionTag;
let title = argv.title;
let text = argv.text;
(0, setup_git_and_npm_connections_1.setupGit)();
if (versionTag == null) {
versionTag = await (0, package_version_1.getPackageVersionTag)(mode);
console.log(`${BADGE}No --version-tag given, versionTag set to:`, versionTag);
}
if (argv.useTitleAndTextFromGitTag) {
if (!(0, git_1.isExistingTag)(versionTag)) {
console.error(`${BADGE}Tag does not exists: ${versionTag}`);
console.error(`${BADGE}Aborting.`);
return false;
}
const { subject, body } = (0, git_1.getFullCommitMessageFromRef)(versionTag);
title = subject;
text = body.replace(SKIP_CI_MESSAGE, '').trim();
console.log(`${BADGE}`);
console.log(`${BADGE}Option --use-title-and-text-from-git-tag was given.`);
console.log(`${BADGE}title set to:`, title);
console.log(`${BADGE}text set to:`, text);
}
let assets = [];
if (argv.assets) {
const list = Array.isArray(argv.assets) ? argv.assets : [argv.assets];
list.forEach((pattern) => {
const files = glob.sync(pattern);
assets = assets.concat(files);
});
console.log(`${BADGE}`);
console.log(`${BADGE}Option --assets was given:`, assets);
}
const success = await updateGitHubRelease(versionTag, title, text, assets, isDryRun);
if (success) {
console.log(`${BADGE}Success.`);
}
return success;
}
exports.run = run;
function getShortDoc() {
return DOC.trim().split('\n')[0];
}
exports.getShortDoc = getShortDoc;
function printHelp() {
console.log(`Usage: ci_tools ${COMMAND_NAME} [--use-title-and-text-from-git-tag | --title [--text]] [--assets <asset-name-or-glob> ...]
[--version-tag] [--dry] [--mode <MODE>]`);
console.log('');
console.log(DOC.trim());
}
exports.printHelp = printHelp;
/**
* Updates the corresponding GitHub release for `versionTag` using the given `title` and `text`.
*/
async function updateGitHubRelease(versionTag, title, text, assets, dryRun = false) {
const repo = getCurrentRepoNameWithOwnerAsObject((0, git_1.getCurrentRepoNameWithOwner)());
const octokit = createOctokit(process.env.GH_TOKEN);
const releaseId = await getExistingReleaseId(octokit, repo, versionTag);
const releaseExists = releaseId != null;
if (releaseExists) {
if (dryRun) {
console.log(`${BADGE}Would now update existing release. Skipping since this is a dry run!`);
return true;
}
console.log(`${BADGE}Updating existing release for ${versionTag} ...`);
return updateExistingRelease(octokit, repo, releaseId, title, text, assets);
}
if (dryRun) {
console.log(`${BADGE}Would now create a new release. Skipping since this is a dry run!`);
return true;
}
console.log(`${BADGE}Creating new release for ${versionTag} ...`);
return createNewRelease(octokit, repo, versionTag, title, text, assets);
}
exports.updateGitHubRelease = updateGitHubRelease;
async function updateExistingRelease(octokit, repo, releaseId, title, text, assets) {
const response = await octokit.repos.updateRelease({
owner: repo.owner,
repo: repo.name,
release_id: releaseId,
name: title,
body: text,
});
let success = response.status === 200;
if (success) {
const uploadUrl = response.data.upload_url;
for (const filename of assets) {
console.log(`${BADGE}- Uploading '${filename}' ...`);
try {
const uploadSuccess = await uploadAsset(octokit, uploadUrl, filename);
success = success && uploadSuccess;
}
catch (error) {
const data = tryToParseJson(error.message);
const errorIsFromOctokitAndAssetAlreadyExists = data?.errors?.length === 1 && data?.errors[0]?.code === 'already_exists';
if (errorIsFromOctokitAndAssetAlreadyExists) {
console.log(`${BADGE} INFO: Asset '${filename}' already exists.`);
}
else {
throw error;
}
}
}
}
return success;
}
async function uploadAsset(octokit, uploadUrl, filename) {
const buffer = (0, fs_1.readFileSync)(filename);
const name = Path.basename(filename).replace(' ', '_');
const contentLength = (0, fs_1.statSync)(filename).size;
const contentType = mime.lookup(filename) || 'text/plain';
const options = {
url: uploadUrl,
file: buffer,
contentType: contentType,
contentLength: contentLength,
name: name,
};
const uploadResponse = await octokit.repos.uploadReleaseAsset(options);
return uploadResponse.status === 201;
}
async function createNewRelease(octokit, repo, versionTag, title, text, assets) {
const isPrerelease = versionTag.match(/-/) != null;
const response = await octokit.repos.createRelease({
owner: repo.owner,
repo: repo.name,
tag_name: versionTag,
name: title,
body: text,
prerelease: isPrerelease,
});
const success = response.status === 201;
if (success) {
const releaseId = response.data.id;
return updateExistingRelease(octokit, repo, releaseId, title, text, assets);
}
return success;
}
function createOctokit(githubAuthToken) {
const octokit = new rest_1.Octokit({
auth: githubAuthToken,
});
return octokit;
}
function getCurrentRepoNameWithOwnerAsObject(nameWithOwner) {
const parts = nameWithOwner.split('/');
return {
name: parts[1],
owner: parts[0],
};
}
async function getExistingReleaseId(octokit, repo, versionTag) {
try {
const response = await octokit.repos.getReleaseByTag({
owner: repo.owner,
repo: repo.name,
tag: versionTag,
});
return response.data.id;
}
catch (error) {
return null;
}
}
function tryToParseJson(text) {
try {
return JSON.parse(text);
}
catch (e) {
return null;
}
}
//# sourceMappingURL=update-github-release.js.map
;