@vis.gl/dev-tools
Version:
Dev tools for vis.gl frameworks
97 lines • 3.17 kB
JavaScript
// This script is designed to work with automated release workflow
// Requires env var GITHUB_TOKEN
// See https://github.com/visgl/.github/blob/main/workflow-templates/release.yml
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
/** GitHub token with release access */
const token = process.env.GITHUB_TOKEN;
if (!token) {
// Do not proceed if publish token is not provided
console.warn('Environment variable GITHUB_TOKEN not found, skipping release');
process.exit(0);
}
/** GitHub repo path, e.g. visgl/deck.gl */
const repository = getRepoName();
if (!repository) {
// Do not proceed if repository is not defined
console.warn('repository.url not defined in package.json, skipping release');
process.exit(0);
}
/** Version tag, e.g. v1.0.0 */
const tag = getGitTag();
if (!tag) {
console.error('TAG NOT FOUND');
process.exit(1);
}
/** Description of this release, parsed from CHANGELOG.md */
const releaseNotes = getReleaseNotes(tag);
if (releaseNotes === null) {
console.error('CHANGELOG NOT FOUND');
process.exit(1);
}
createRelease();
async function createRelease() {
// Publish release notes to GitHub
// https://docs.github.com/en/rest/reference/repos#create-a-release
const url = `https://api.github.com/repos/${repository}/releases`;
const resp = await fetch(url, {
method: 'POST',
headers: {
Authorization: `token ${token}`,
Accept: 'application/vnd.github.v3+json'
},
body: JSON.stringify({
tag_name: tag,
name: tag,
body: releaseNotes,
prerelease: tag.search(/alpha|beta|rc/) > 0
})
});
if (!resp.ok) {
let reason = `POST to ${url} failed with code ${resp.status}`;
try {
const details = await resp.text();
reason += `\n${details}`;
}
catch {
// ignore
}
throw new Error(reason);
}
console.log(`Release created: https://github.com/${repository}/releases/tag/${tag}`);
}
function getRepoName() {
const packageInfo = JSON.parse(readFileSync('package.json', 'utf-8'));
const repoUrl = packageInfo.repository?.url;
if (!repoUrl || !repoUrl.includes('github.com')) {
return null;
}
const m = repoUrl.match(/([\w\.\-]+\/[\w\.\-]+?)(.git)?$/);
return m?.[1] ?? null;
}
function getGitTag() {
try {
return execSync('git describe --tags --exact-match HEAD', {
stdio: [null, 'pipe', null],
encoding: 'utf-8'
}).trim();
}
catch (err) {
// not tagged
return null;
}
}
function getReleaseNotes(version) {
let changelog = readFileSync('CHANGELOG.md', 'utf-8');
const header = changelog.match(new RegExp(`^##.*\\bv?${version.replace('v', '')}\\b.*$`, 'm'));
if (!header) {
return null;
}
changelog = changelog.slice(header.index + header[0].length);
const endIndex = changelog.search(/^#/m);
if (endIndex > 0) {
changelog = changelog.slice(0, endIndex);
}
return changelog.trim();
}
//# sourceMappingURL=github-release.js.map