feat(build): nushell release scripts
This commit is contained in:
78
scripts/check-deps.nu
Normal file
78
scripts/check-deps.nu
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env nu
|
||||
|
||||
use std/log
|
||||
|
||||
# Check release dependencies
|
||||
export def main [] {
|
||||
print "Checking Release Dependencies"
|
||||
print "=============================\n"
|
||||
|
||||
log info "Checking .env file..."
|
||||
if not (".env" | path exists) {
|
||||
error make {msg: ".env file not found"}
|
||||
}
|
||||
log debug " .env file found"
|
||||
|
||||
log info "Validating Sentry configuration..."
|
||||
# Get env variables dynamically and reduce the table into a record
|
||||
let env_vars = (
|
||||
open .env
|
||||
| lines
|
||||
| where { |line| ($line | str trim) != "" and not ($line | str starts-with "#") }
|
||||
| each { |line|
|
||||
let parts = ($line | split column "=" key value | first)
|
||||
{ name: ($parts.key | str trim), value: ($parts.value | str trim) }
|
||||
}
|
||||
| reduce --fold {} { |it, acc| $acc | merge { ($it.name): $it.value } }
|
||||
)
|
||||
|
||||
let sentry_org = $env_vars | get SENTRY_ORG?
|
||||
if $sentry_org != "longhorn-developers" {
|
||||
error make {msg: $"SENTRY_ORG must be set to longhorn-developers in .env\nGot: ($sentry_org)"}
|
||||
}
|
||||
log debug $" SENTRY_ORG: ($sentry_org)"
|
||||
|
||||
|
||||
let sentry_project = $env_vars | get SENTRY_PROJECT?
|
||||
if $sentry_project != "ut-registration-plus" {
|
||||
error make {msg: $"SENTRY_PROJECT must be set to ut-registration-plus in .env\nGot: ($sentry_project)"}
|
||||
}
|
||||
log debug $" SENTRY_PROJECT: ($sentry_project)"
|
||||
|
||||
let sentry_auth_token = $env_vars | get SENTRY_AUTH_TOKEN?
|
||||
if ($sentry_auth_token | is-empty) {
|
||||
error make {msg: "SENTRY_AUTH_TOKEN must be populated in .env"}
|
||||
}
|
||||
log debug " SENTRY_AUTH_TOKEN: [set]"
|
||||
|
||||
#Check for required commands
|
||||
mut missing_deps = []
|
||||
|
||||
if (which pnpm | is-empty) {
|
||||
$missing_deps = ($missing_deps | append "pnpm")
|
||||
}
|
||||
if (which npm | is-empty) {
|
||||
$missing_deps = ($missing_deps | append "npm")
|
||||
}
|
||||
if (which conventional-changelog | is-empty) {
|
||||
$missing_deps = ($missing_deps | append "conventional-changelog")
|
||||
}
|
||||
|
||||
log info "Checking VCS"
|
||||
if not (which jj | is-empty) {
|
||||
log debug " Version control: jujutsu"
|
||||
} else if not (which git | is-empty) {
|
||||
log debug " Version control: git"
|
||||
} else {
|
||||
$missing_deps = ($missing_deps | append "git or jujutsu")
|
||||
}
|
||||
|
||||
if ($missing_deps | length) > 0 {
|
||||
let deps: string = $missing_deps | str join ", "
|
||||
let error_msg: string = ("Missing required dependencies: " | append $deps | str join)
|
||||
error make { msg: $error_msg }
|
||||
}
|
||||
|
||||
log info "All required commands found"
|
||||
log info "All dependency checks passed"
|
||||
}
|
||||
31
scripts/publish-release.nu
Normal file
31
scripts/publish-release.nu
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env nu
|
||||
|
||||
use std/log
|
||||
|
||||
# Publish the release (creates distribution package and displays checksum)
|
||||
export def main [] {
|
||||
print "Publishing Release"
|
||||
print "==================\n"
|
||||
|
||||
log info "pnpm zip:to-publish"
|
||||
let result = (pnpm zip:to-publish | complete)
|
||||
|
||||
if ($result.stderr | str contains -i "error") or ($result.stderr | str contains -i "failed") {
|
||||
error make {msg: "Package creation failed"}
|
||||
}
|
||||
|
||||
# Find and verify the zip file
|
||||
let zip_files = (ls package/*.zip | where type == file)
|
||||
if ($zip_files | is-empty) {
|
||||
error make {msg: "No package found in package/ directory"}
|
||||
}
|
||||
|
||||
# Get last modified zip file
|
||||
let zip_file = ($zip_files | sort-by -r modified | first | get name)
|
||||
let checksum = (open $zip_file | hash sha256)
|
||||
|
||||
log info "Release published successfully!"
|
||||
log info "Package ready for distribution:"
|
||||
log info $"($zip_file)"
|
||||
log info $"SHA256: ($checksum)"
|
||||
}
|
||||
29
scripts/release.nu
Normal file
29
scripts/release.nu
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env nu
|
||||
|
||||
use check-deps.nu
|
||||
use stage-release.nu
|
||||
use publish-release.nu
|
||||
|
||||
# UTRP Release workflow
|
||||
export def main [
|
||||
--bump: string = "minor", # bump type: major, minor, or patch
|
||||
--dry-run = true, # Dry run release workflow
|
||||
] {
|
||||
check-deps
|
||||
|
||||
if $dry_run {
|
||||
print "\ndry-run todo:"
|
||||
print "- stage-release"
|
||||
print "- publish-release"
|
||||
exit 0
|
||||
}
|
||||
|
||||
mut vcs = ""
|
||||
if not (which jj | is-empty) { $vcs = "jj" } else if not (which git | is-empty) { $vcs = "git"}
|
||||
|
||||
stage-release $bump $vcs
|
||||
publish-release
|
||||
|
||||
print "Release workflow completed!"
|
||||
}
|
||||
|
||||
97
scripts/stage-release.nu
Normal file
97
scripts/stage-release.nu
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env nu
|
||||
|
||||
use std/log
|
||||
|
||||
# Stage a new release (bump version, changelog, commit, and tag)
|
||||
export def main [
|
||||
version_type: string = "minor", # Version type: major, minor, or patch
|
||||
vcs: string = "jj", # VCS: jj or git
|
||||
] {
|
||||
print "Staging Release"
|
||||
print "===============\n"
|
||||
|
||||
if $version_type not-in ["major, minor", "patch"] {
|
||||
error make {msg: $"version_type must be major, minor, or patch.\nGot: ($version_type)"}
|
||||
}
|
||||
|
||||
if $vcs not-in ["jj", "git"] {
|
||||
error make {msg: $"vcs must be jj or git.\nGot: ($vcs)"}
|
||||
}
|
||||
|
||||
|
||||
log info $"Using ($vcs)"
|
||||
if $vcs == "git" {
|
||||
# Check for uncommitted changes (git only)
|
||||
let status = (git diff-index --quiet HEAD -- | complete)
|
||||
if $status.exit_code != 0 {
|
||||
error make {msg: "You have uncommitted changes. Please commit or stash them first."}
|
||||
}
|
||||
}
|
||||
|
||||
# Bump version in package.json without committing or tagging
|
||||
log info "Bumping version in package.json..."
|
||||
npm version $version_type --no-git-tag-version | complete
|
||||
|
||||
let new_version = (open package.json | get version)
|
||||
log debug $"New version: ($new_version)"
|
||||
|
||||
changelog
|
||||
|
||||
log info "Committing changes..."
|
||||
if $vcs == "jj" {
|
||||
jj commit -m $"chore: release v($new_version)"
|
||||
log debug "Commit created"
|
||||
|
||||
# Update main bookmark (jj only)
|
||||
log info "Updating main bookmark..."
|
||||
jj bookmark set main -r @
|
||||
log debug "Bookmark 'main' updated to current commit"
|
||||
} else {
|
||||
git add package.json package-lock.json CHANGELOG.md
|
||||
git commit -m $"chore: release v($new_version)"
|
||||
}
|
||||
|
||||
if $vcs == "jj" {
|
||||
log info "Creating annotated tag via git..."
|
||||
jj git export
|
||||
git tag -a $"v($new_version)" -m $"Release v($new_version)"
|
||||
jj git import
|
||||
log debug $"Annotated tag 'v($new_version)' created via git"
|
||||
} else {
|
||||
log info "Creating annotated tag..."
|
||||
git tag -a $"v($new_version)" -m $"Release v($new_version)"
|
||||
log debug $"Annotated tag 'v($new_version)' created"
|
||||
}
|
||||
|
||||
log info $"Release v($new_version) staged successfully!"
|
||||
print "Next steps:"
|
||||
if $vcs == "jj" {
|
||||
print " - Review changes: jj show @-"
|
||||
print " - Push to remote: jj git push && git push --tags"
|
||||
} else {
|
||||
print " - Review changes: git show"
|
||||
print " - Push to remote: git push && git push --tags"
|
||||
}
|
||||
}
|
||||
|
||||
def changelog [] {
|
||||
log info "Generating changelog with new version..."
|
||||
let changelog_exists = ("CHANGELOG.md" | path exists)
|
||||
let changelog_before = if $changelog_exists {
|
||||
(ls CHANGELOG.md | get modified | first)
|
||||
}
|
||||
|
||||
let result = (pnpm generate-changelog | complete)
|
||||
if ($result.stderr | str contains -i "error") or ($result.stderr | str contains -i "failed") or ($result.stderr | str contains -i "command not found") {
|
||||
error make {msg: "Changelog generation failed"}
|
||||
}
|
||||
|
||||
if not ("CHANGELOG.md" | path exists) {
|
||||
error make {msg: "CHANGELOG.md was not created"}
|
||||
}
|
||||
|
||||
let changelog_after = (ls CHANGELOG.md | get modified | first)
|
||||
if $changelog_exists and ($changelog_after <= $changelog_before) {
|
||||
error make {msg: "CHANGELOG.md was not updated"}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user