improve release code

This commit is contained in:
SrGooglo 2024-09-16 10:26:16 +00:00
parent 576f99d325
commit 9fc93ce434
5 changed files with 232 additions and 187 deletions

View File

@ -1,158 +1,77 @@
require("dotenv").config()
// dependencies
const packagejson = require("../package.json")
const path = require("path")
const fs = require("fs")
const child_process = require("child_process")
const { Octokit } = require("@octokit/rest")
const sevenzip = require("7zip-min")
const axios = require("axios")
// utils
const compressDistBundle = require("./utils/compressDistBundle")
const buildAppDist = require("./utils/buildAppDist")
const createGithubRelease = require("./utils/createGithubRelease")
const uploadAssets = require("./utils/uploadAssets")
const composeChangelog = require("./utils/composeChangelog")
const bumpVersion = require("./utils/bumpVersion")
// constants & paths
const repo = "ragestudio/comty"
const appSrcPath = path.resolve(process.cwd(), "packages/app/src")
const appDistPath = path.resolve(process.cwd(), "packages/app/dist")
const changelogsPath = path.resolve(process.cwd(), "changelogs")
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN
})
const composeChangelog = require("./utils/composeChangelog")
const bumpVersion = require("./utils/bumpVersion")
async function createGithubRelease(payload) {
if (process.argv.includes("--noPublish")) {
console.log("🔥 Skipping release creation due to `noPublish` argument")
return true
}
const { version, changelog } = payload
const response = await axios({
method: "post",
url: `https://api.github.com/repos/${repo}/releases`,
headers: {
"Authorization": `token ${process.env.GITHUB_TOKEN}`,
"Content-Type": "application/json"
},
data: {
tag_name: version,
name: `v${version}`,
body: changelog
}
})
console.log("⚒ Creating release done!")
return response.data
}
async function createAppDistBundle() {
// check if has `noBuild` argument
if (process.argv.includes("--noBuild")) {
console.log("🔥 Skipping build due to `noBuild` argument")
return true
}
// build app for production
console.log("⚒ Building app...")
await child_process.execSync("yarn build", {
cwd: appSrcPath,
stdio: "inherit"
})
console.log("⚒ Building app done!")
return appDistPath
}
async function compressDistBundle() {
const outPath = path.resolve(appDistPath, "../app_dist.7z")
if (process.argv.includes("--noCompress") || process.argv.includes("--noBuild")) {
console.log("🔥 Skipping compress due to `noBuild` or `noCompress` argument")
return outPath
}
// compress with 7zip
console.log("⚒ Compressing app...")
// check if out file exists
if (fs.existsSync(outPath)) {
fs.unlinkSync(outPath)
}
await new Promise((resolve, reject) => {
sevenzip.pack(appDistPath, outPath, (err) => {
if (err) {
return reject(err)
}
return resolve(outPath)
})
})
console.log("⚒ Compressing app done! > " + outPath)
return outPath
}
async function uploadAssets({ release, bundlePath, changelogFilepath }) {
// 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(`ReleaseID: ${release.id}`)
const appDistAsset = await octokit.repos.uploadReleaseAsset({
release_id: release.id,
owner: repo.split("/")[0],
repo: repo.split("/")[1],
name: "app_dist.7z",
data: fs.readFileSync(bundlePath)
})
const changelogAsset = await octokit.repos.uploadReleaseAsset({
release_id: release.id,
owner: repo.split("/")[0],
repo: repo.split("/")[1],
name: "changelog.md",
data: fs.readFileSync(changelogFilepath)
})
if (!appDistAsset) {
return false
}
if (!changelogAsset) {
return false
}
console.log("⚒ Uploading assets done!")
return true
}
const packedDistPath = path.resolve(appDistPath, "dist.zip")
async function main() {
// check if no GITHUB_TOKEN env
if (!process.env.GITHUB_TOKEN) {
console.error("🆘 Missing GITHUB_TOKEN env")
return false
}
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN
})
let steps = {
build: true,
bundle: true,
publish: true,
ignoreCommits: false,
ignoreVersion: false,
changelog: true,
}
if (process.argv.includes("--no-pack")) {
steps.bundle = false
}
if (process.argv.includes("--no-publish")) {
steps.publish = false
}
if (process.argv.includes("--no-build")) {
steps.build = false
}
if (process.argv.includes("--ignore-commits")) {
steps.ignoreCommits = true
}
if (process.argv.includes("--ignore-version")) {
steps.ignoreVersion = true
}
// check if is any changes pending to commit
if (!steps.ignoreCommits) {
const gitStatus = child_process.execSync("git status --porcelain", {
cwd: process.cwd()
}).toString().trim()
if (gitStatus.length > 0 && !process.argv.includes("--ignore-commits")) {
console.error("🆘 There are pending changes to commit, please commit first.")
if (gitStatus.length > 0) {
console.warn("There are pending changes to commit, please commit first.")
return false
}
}
let currentVersion = packagejson.version
@ -165,7 +84,13 @@ async function main() {
return false
})
if (latestRelease && latestRelease.data.tag_name === currentVersion && !process.argv.includes("--force")) {
if (!latestRelease) {
console.error("🆘 Failed to get latest release")
return false
}
if (!steps.ignoreVersion) {
if (latestRelease && latestRelease.data.tag_name === currentVersion) {
if (process.argv.includes("--bump")) {
const bumpType = process.argv[process.argv.indexOf("--bump") + 1]
@ -196,47 +121,76 @@ async function main() {
stdio: "inherit"
})
} 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.")
console.log("🚫 Current version is already latest version, please bump version first. \n - use --bump <patch|minor|major> to automatically bump version. \n - use --ignore-version to force release.")
return true
}
}
}
if (!latestRelease) return
if (steps.build) {
steps.build = await buildAppDist(appSrcPath)
}
await createAppDistBundle()
const bundlePath = await compressDistBundle()
if (steps.bundle) {
steps.bundle = await compressDistBundle(appDistPath, packedDistPath)
}
if (steps.changelog) {
const changelog = await composeChangelog()
const changelogFilepath = path.resolve(changelogsPath, `v${currentVersion.split(".").join("-")}.md`)
steps.changelog = path.resolve(changelogsPath, `v${currentVersion.split(".").join("-")}.md`)
console.log(`📝 Writing changelog to file > ${changelogFilepath}`)
console.log(`📝 Writing changelog to file > ${steps.changelog}`)
// write changelog to file
fs.writeFileSync(changelogFilepath, changelog)
fs.writeFileSync(steps.changelog, changelog)
}
const release = await createGithubRelease({
if (steps.publish) {
const release = await createGithubRelease(
repo,
{
version: currentVersion,
changelog,
}).catch((err) => {
},
process.env.GITHUB_TOKEN,
).catch((err) => {
console.error(`🆘 Failed to create release: ${err}`)
return false
})
if (!release) return
const assets = await uploadAssets({ release, bundlePath, changelogFilepath }).catch((err) => {
console.error(`🆘 Failed to upload asset: ${err}`, err.response)
return false
})
if (!assets) return
console.log("🎉 Release done!")
if (!release) {
return false
}
const assets = await uploadAssets(
octokit,
repo,
release,
[
{
name: packedDistPath,
data: fs.readFileSync(packedDistPath)
},
{
name: "changelog.md",
data: fs.readFileSync(steps.changelog)
}
],
)
console.log("🎉 Assets uploaded! >", assets)
console.log(`🔗 ${release.html_url}`)
}
console.log("All Done!")
return true
}
main().catch((err) => {
console.error(`Fatal error: `, err)
})

View File

@ -0,0 +1,15 @@
const child_process = require("child_process")
async function buildAppDist(srcPath) {
// build app for production
console.log("⚒ Building app...")
await child_process.execSync("yarn build", {
cwd: srcPath,
stdio: "inherit"
})
console.log("⚒ Building app done!")
return srcPath
}
module.exports = buildAppDist

View File

@ -0,0 +1,28 @@
const fs = require("fs")
const sevenzip = require("7zip-min")
async function compressDistBundle(origin, output) {
// compress with 7zip
console.log("⚒ Compressing app...")
// check if out file exists
if (fs.existsSync(output)) {
fs.unlinkSync(output)
}
await new Promise((resolve, reject) => {
sevenzip.pack(origin, output, (err) => {
if (err) {
return reject(err)
}
return resolve(output)
})
})
console.log("⚒ Compressing app done! > " + output)
return output
}
module.exports = compressDistBundle

View File

@ -0,0 +1,25 @@
const axios = require("axios")
async function createGithubRelease(repo, payload, token) {
const { version, changelog } = payload
const response = await axios({
method: "post",
url: `https://api.github.com/repos/${repo}/releases`,
headers: {
"Authorization": `token ${token}`,
"Content-Type": "application/json"
},
data: {
tag_name: version,
name: `v${version}`,
body: changelog
}
})
console.log("⚒ Creating release done!")
return response.data
}
module.exports = createGithubRelease

View File

@ -0,0 +1,23 @@
async function uploadAssets(octokit, repo, release, assets, { release, bundlePath, changelogFilepath }) {
console.log("⚒ Uploading assets...")
console.log(`ReleaseID: ${release.id}`)
for await (const asset of assets) {
console.log(`Uploading Asset: ${asset.name}`)
await octokit.repos.uploadReleaseAsset({
release_id: release.id,
owner: repo.split("/")[0],
repo: repo.split("/")[1],
name: asset.name,
data: asset.data
})
}
console.log("⚒ Uploading assets done!")
return true
}
module.exports = uploadAssets