improve release script with new args

This commit is contained in:
SrGooglo 2023-04-27 00:26:22 +00:00
parent 0cb3088aad
commit dc1ea9f68f
3 changed files with 242 additions and 33 deletions

View File

@ -12,40 +12,14 @@ const axios = require("axios")
const repo = "ragestudio/comty" const repo = "ragestudio/comty"
const appSrcPath = path.resolve(process.cwd(), "packages/app/src") const appSrcPath = path.resolve(process.cwd(), "packages/app/src")
const appDistPath = path.resolve(process.cwd(), "packages/app/dist") const appDistPath = path.resolve(process.cwd(), "packages/app/dist")
const changelogsPath = path.resolve(process.cwd(), "changelogs")
const octokit = new Octokit({ const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN auth: process.env.GITHUB_TOKEN
}) })
async function getChangeLogString() { const composeChangelog = require("./utils/composeChangelog")
// get latest tag const bumpVersion = require("./utils/bumpVersion")
const latestTag = await octokit.repos.getLatestRelease({
owner: repo.split("/")[0],
repo: repo.split("/")[1]
})
// get commits since latest tag
const commits = await octokit.repos.listCommits({
owner: repo.split("/")[0],
repo: repo.split("/")[1],
since: latestTag.data.published_at
})
const changelog = commits.data.map((commit) => {
return {
message: commit.commit.message,
author: commit.commit.author.name,
url: commit.html_url,
}
})
// make a string from the changes with Markdown syntax
const changelogString = changelog.map((commit) => {
return `* [${commit.message}](${commit.url}) - ${commit.author}`
}).join("\n")
return changelogString
}
async function createGithubRelease(payload) { async function createGithubRelease(payload) {
if (process.argv.includes("--noPublish")) { if (process.argv.includes("--noPublish")) {
@ -93,8 +67,8 @@ async function createAppDistBundle() {
} }
async function compressDistBundle() { async function compressDistBundle() {
if (process.argv.includes("--noCompress")) { if (process.argv.includes("--noCompress") || process.argv.includes("--noBuild")) {
console.log("🔥 Skipping build due to `noBuild` argument") console.log("🔥 Skipping compress due to `noBuild` or `noCompress` argument")
return true return true
} }
@ -124,6 +98,12 @@ async function compressDistBundle() {
} }
async function uploadAssets({ release, bundlePath }) { async function uploadAssets({ release, bundlePath }) {
// check if has `noPublish` argument, if true, skip uploading assets
if (process.argv.includes("--noPublish")) {
console.log("🔥 Skipping upload assets due to `noPublish` argument")
return true
}
console.log("⚒ Uploading assets...") console.log("⚒ Uploading assets...")
console.log(`ReleaseID: ${release.id}`) console.log(`ReleaseID: ${release.id}`)
@ -146,13 +126,53 @@ async function uploadAssets({ release, bundlePath }) {
} }
async function main() { async function main() {
let currentVersion = packagejson.version
// check if currentVersion match with current latest release on github
const latestRelease = await octokit.repos.getLatestRelease({
owner: repo.split("/")[0],
repo: repo.split("/")[1]
}).catch((err) => {
console.error(`🆘 Failed to get latest release: ${err}`)
return false
})
if (latestRelease && latestRelease.data.tag_name === currentVersion && !process.argv.includes("--force")) {
if (process.argv.includes("--bump")) {
const bumpType = process.argv[process.argv.indexOf("--bump") + 1]
const newVersion = await bumpVersion(bumpType, 1).catch((err) => {
console.error(`🆘 Failed to bump version: ${err}`)
return false
})
if (!newVersion) {
throw new Error("Failed to bump version")
}
currentVersion = newVersion
} else {
console.log("🚫 Current version is already latest version, please bump version first. \n - use --bump <patch|minor|major> to automatically bump version. \n - use --force to force release.")
}
return true
}
if (!latestRelease) return
await createAppDistBundle() await createAppDistBundle()
const bundlePath = await compressDistBundle() const bundlePath = await compressDistBundle()
const changelog = await getChangeLogString() const changelog = await composeChangelog()
console.log("📝 Writing changelog to file...")
// write changelog to file
fs.writeFileSync(path.resolve(changelogsPath, `v${currentVersion.replace(".", "-")}.md`), changelog)
const release = await createGithubRelease({ const release = await createGithubRelease({
version: packagejson.version, version: currentVersion,
changelog, changelog,
}).catch((err) => { }).catch((err) => {
console.error(`🆘 Failed to create release: ${err}`) console.error(`🆘 Failed to create release: ${err}`)

View File

@ -0,0 +1,99 @@
const path = require("path")
const fs = require("fs")
const validTypes = ["patch", "minor", "major"]
async function bumpVersion(type, count, noWrite = false) {
if (!validTypes.includes(type)) {
console.error("Invalid version type")
return false
}
// read all directories from `./packages` and __dirname/..
// find `package.json` files
// and bump depending on the `type` argument (patch, minor, major)
// write into `package.json` files
// exclude gitignored
const ignore = fs.readFileSync(path.resolve(process.cwd(), ".gitignore"), "utf8").split("\n").filter(line => line !== "").filter(line => !line.startsWith("#"))
const ignoreRegex = ignore.map((line) => {
let regex = line.replace(/\./g, "\\.").replace(/\*/g, ".*")
if (!regex.startsWith("/")) {
regex = `/${regex}`
}
if (!regex.endsWith("/")) {
regex = `${regex}/`
}
return regex
})
const packagesPath = path.resolve(__dirname, "..", "..", "packages")
let packages = fs.readdirSync(packagesPath)
packages = packages.filter((package) => {
let isIgnored = false
ignoreRegex.forEach(regex => {
if (new RegExp(regex).test(`/${package}/`)) {
isIgnored = true
}
})
return !isIgnored
})
// filter out ignored packages
packages = packages.filter((package) => !ignore.includes(package))
// filter out non-directories
packages = packages.filter((package) => fs.lstatSync(path.resolve(packagesPath, package)).isDirectory())
// filter out non-package.json
packages = packages.filter((package) => fs.existsSync(path.resolve(packagesPath, package, "package.json")))
for (let package of packages) {
const pkgjson = require(path.resolve(packagesPath, package, "package.json"))
if (!pkgjson || !pkgjson.version) {
continue
}
let version = pkgjson.version.split(".")
switch (type) {
case "patch":
version[2] = parseInt(version[2]) + Number(count ?? 1)
break
case "minor":
version[1] = parseInt(version[1]) + Number(count ?? 1)
break
case "major":
version[0] = parseInt(version[0]) + Number(count ?? 1)
break
default:
console.error("Invalid version type")
return false
}
version = version.join(".")
console.log(`⏩ Bumped [${pkgjson.name}] ${pkgjson.version} to ${version}`)
pkgjson.version = version
if (noWrite) {
continue
}
fs.writeFileSync(path.resolve(packagesPath, package, "package.json"), JSON.stringify(pkgjson, null, 4))
}
return true
}
module.exports = bumpVersion

View File

@ -0,0 +1,90 @@
require("dotenv").config()
const { Octokit } = require("@octokit/rest")
const repo = "ragestudio/comty"
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
})
async function getChangeLogString() {
// get latest tag
const latestTag = await octokit.repos.getLatestRelease({
owner: repo.split("/")[0],
repo: repo.split("/")[1]
})
// get commits since latest tag
const commits = await octokit.repos.listCommits({
owner: repo.split("/")[0],
repo: repo.split("/")[1],
since: latestTag.data.published_at
})
let changelog = commits.data.map(async (commit) => {
const commitData = await octokit.repos.getCommit({
owner: repo.split("/")[0],
repo: repo.split("/")[1],
ref: commit.sha
})
const filenamesChanged = commitData.data.files.map((file) => {
return file.filename
})
// check packages involved in each commit
let packagesChanged = filenamesChanged.map((file) => {
// search for the pkg name in the path (eg packages/app/src/...)
const pkg = file.split("/")[1]
// if the pkg is not found, return null
if (!pkg) return null
return pkg
})
// filter out null values
packagesChanged = packagesChanged.filter((pkg) => {
return pkg !== null
})
// remove duplicates
packagesChanged = [...new Set(packagesChanged)]
// if no packages changed, return "internal"
if (packagesChanged.length === 0) {
packagesChanged = ["internal"]
}
return {
message: commitData.data.commit.message,
author: commitData.data.commit.author.name,
authorUrl: commitData.data.author.html_url,
url: commit.html_url,
filenamesChanged: filenamesChanged,
files: commitData.data.files,
packages: packagesChanged,
}
})
changelog = await Promise.all(changelog)
// make a string from the changes with Markdown syntax
let changelogString = changelog.map((commit) => {
const additions = commit.files.map((file) => {
return file.additions
}).reduce((a, b) => a + b, 0)
const deletions = commit.files.map((file) => {
return file.deletions
}).reduce((a, b) => a + b, 0)
return `* [+${additions}/-${deletions}][${commit.packages.join(" | ")}] [${commit.message}](${commit.url}) - by [@${commit.author}](${commit.authorUrl})`
}).join("\n")
changelogString = changelogString.trim()
return changelogString
}
module.exports = getChangeLogString