UNPKG

@process-engine/ci_tools

Version:
202 lines (199 loc) 7.51 kB
"use strict"; 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