Skip to content

Instantly share code, notes, and snippets.

@zsmatrix62
Last active September 12, 2024 09:15
Show Gist options
  • Save zsmatrix62/dd6df46342c78d09c88f0ff89242154f to your computer and use it in GitHub Desktop.
Save zsmatrix62/dd6df46342c78d09c88f0ff89242154f to your computer and use it in GitHub Desktop.
nushell script to increase a semmantic version number, add a tag and push to origin branch
# git-pub.nu
#
# nushell script to increase a semmantic version number, add a tag and push to origin branch
#
# prerequisits:
# - git
# - git-cliff
#
# usage:
# ```nushell
# source git-pub.nu;
# git pub release (major|minor|patch) (increase) [-p (branch)]
# ```
export def "git pub release" [
incType: string@_semmanticVerNumNames,
incValue: number
--pushBranch (-p): string
] {
check_prerequisites
# 1. git must be on dev branch
# 2. git must clean otherwise raise error
ensure_git_clean
# 3. generate changelog
gen_change_logs
# 4. get increased version and add git tag
(increase_version $incType $incValue | add_git_version_tag $in)
# 5. dump version to version file
increase_version $incType $incValue -w
# ------------------------------------
# 6. push to origin branch with tags
if ($pushBranch | is-not-empty) {
(git push origin $pushBranch --tags)
}
}
const permitted_branches = ["master", "dev", "main"]
def check_prerequisites [] {
if ((which git) | is-empty) {
error make {
msg: "git is not installed"
}
}
if ((which git-cliff) | is-empty) {
error make {
msg: "git-cliff is not installed"
}
}
}
def ensure_git_clean [] {
if ((git branch --show-current) not-in $permitted_branches) {
error make {
msg: $"git branch must be [master, main, dev]"
}
}
if (git status --porcelain | lines |length) > 0 {
error make {
msg: "git status is not clean - commit first"
}
}
}
def _semmanticVerNumNames [] {
return [
"major",
"minor",
"patch"
]
}
def increase_version [
incType: string@_semmanticVerNumNames,
incValue: number
--write (-w)
] {
# a version file must be in json format and must have a version key
const version_file_candidates = [
'info.json',
'package.json',
]
mut valid_version_file_path = ""
mut version_2 = ""
mut version_file_content = {}
for vf in $version_file_candidates {
if ($vf | path expand | path exists) {
let content = (open $vf)
mut version = ($content | get "version")
if ($version | is-not-empty) {
$valid_version_file_path = ($vf | path expand)
$version_2 = $version
$version_file_content = $content
break
}
}
}
# Semantic Versioning
let verDict = ($version_2 | parse "{major}.{minor}.{patch}")
let major = ($verDict | get "major")
let minor = ($verDict | get "minor")
let patch = ($verDict | get "patch")
if ( [ $major $minor $patch ] | any { |$it| ($it | is-empty) } ) {
error make {
msg: "version file must have a version key"
}
}
mut newVerDict = {}
if ($incType == "patch") {
$newVerDict = $verDict | update "patch" { ($in | into int) + $incValue }
}
if ($incType == "minor") {
$newVerDict = $verDict | update "minor" { ($in | into int) + $incValue }
}
if ($incType == "major") {
$newVerDict = $verDict | update "major" { ($in | into int) + $incValue }
}
let new_version = $"($newVerDict.major|get 0).($newVerDict.minor|get 0).($newVerDict.patch|get 0)"
if ($write) {
let new_content = ($version_file_content | update "version" $new_version)
($new_content | to json) | save -f $valid_version_file_path
(git add $valid_version_file_path; git commit -m $"chore: bump version to ($new_version)")
}
return $new_version
}
def add_git_version_tag [
version: string
] {
(git tag -a $"v($version)" -m $"chore: release ($version)")
}
def gen_change_logs [] {
const cliff_file = "cliff.toml"
if not ($cliff_file | path expand | path exists) {
error make {
msg: "cliff.toml file not found, run `git cliff init` first"
}
}
(git cliff -o CHANGELOG.md)
(git add CHANGELOG.md; git commit -m "chore: update changelog")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment