PSA/cli/migrate.nu
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

168 lines
7.5 KiB
Plaintext

# Manage database migrations
def --env load-migration-env [project_root: string] {
let server_dir = ($project_root | path join "server")
let env_files = [
($server_dir | path join ".env")
($server_dir | path join ".env.local")
]
mut loaded_files = []
for env_file in $env_files {
if ($env_file | path exists) {
let env_vars = (open $env_file
| lines
| each { |line| $line | str trim }
| where { |line| not ($line | str starts-with '#') and ($line | str length) > 0 and ($line | str contains '=') }
| split column "=" -n 2
| rename key value
| update key { |it| $it.key | str trim }
| update value { |it|
if ($it.value | is-empty) {
""
} else {
let raw_value = ($it.value | str trim)
let is_quoted = (($raw_value | str starts-with '"') or ($raw_value | str starts-with "'"))
let normalized = ($raw_value | str trim -c '"' | str trim -c "'")
if $is_quoted {
$normalized
} else {
$normalized | str replace -r '\s+#.*$' ''
}
}
}
| reduce -f {} { |item, acc| $acc | upsert $item.key $item.value })
if (($env_vars | columns | length) > 0) {
load-env $env_vars
}
$loaded_files = ($loaded_files | append ($env_file | path basename))
}
}
if (($loaded_files | length) > 0) {
print $"($env.ALGA_COLOR_CYAN)Loaded migration env from ($loaded_files | str join ', '); server/.env.local overrides server/.env.($env.ALGA_COLOR_RESET)"
} else {
print $"($env.ALGA_COLOR_YELLOW)No server env files found (expected server/.env and optionally server/.env.local). Using current shell env only.($env.ALGA_COLOR_RESET)"
}
}
export def run-migrate [
action: string # The migration action to perform: up, latest, down, or status
--ee # Run combined CE + EE migrations (latest, down, status)
] {
let project_root = find-project-root
load-migration-env $project_root
if $ee {
if not ($action in ["latest", "down", "status"]) {
error make { msg: $"($env.ALGA_COLOR_RED)--ee is only supported with 'latest', 'down', or 'status' actions($env.ALGA_COLOR_RESET)" }
}
# Map action to npm script name
let npm_script = match $action {
"latest" => "migrate:ee",
"down" => "migrate:ee:down",
"status" => "migrate:ee:status"
}
print $"($env.ALGA_COLOR_CYAN)Running CE + EE migrations ($action)...($env.ALGA_COLOR_RESET)"
let result = do {
cd $project_root
npm -w server run $npm_script | complete
}
if $result.exit_code == 0 {
if not ($result.stdout | is-empty) {
print $result.stdout
}
print $"($env.ALGA_COLOR_GREEN)CE + EE migrations ($action) completed successfully.($env.ALGA_COLOR_RESET)"
return
}
if not ($result.stderr | is-empty) {
print $"($env.ALGA_COLOR_RED)($result.stderr)($env.ALGA_COLOR_RESET)"
}
error make { msg: $"($env.ALGA_COLOR_RED)CE + EE migrations ($action) failed($env.ALGA_COLOR_RESET)", code: $result.exit_code }
}
match $action {
"up" => {
print $"($env.ALGA_COLOR_CYAN)Running next pending database migration...($env.ALGA_COLOR_RESET)"
# Change to the server directory and run the knex command
# Capture stdout and stderr
let result = do {
cd ($project_root | path join "server")
npx knex migrate:up --knexfile knexfile.cjs --env migration | complete # Use migrate:up
}
# Print output or error
if $result.exit_code == 0 {
print $result.stdout # Keep knex output as is
print $"($env.ALGA_COLOR_GREEN)Migration 'up' completed successfully.($env.ALGA_COLOR_RESET)"
} else {
print $"($env.ALGA_COLOR_RED)($result.stderr)($env.ALGA_COLOR_RESET)"
error make { msg: $"($env.ALGA_COLOR_RED)Migration 'up' failed($env.ALGA_COLOR_RESET)", code: $result.exit_code }
}
}
"latest" => { # Add separate case for 'latest'
print $"($env.ALGA_COLOR_CYAN)Running all pending database migrations...($env.ALGA_COLOR_RESET)"
# Change to the server directory and run the knex command
# Capture stdout and stderr
let result = do {
cd ($project_root | path join "server")
npx knex migrate:latest --knexfile knexfile.cjs --env migration | complete # Use migrate:latest
}
# Print output or error
if $result.exit_code == 0 {
print $result.stdout # Keep knex output as is
print $"($env.ALGA_COLOR_GREEN)Migrations 'latest' completed successfully.($env.ALGA_COLOR_RESET)"
} else {
print $"($env.ALGA_COLOR_RED)($result.stderr)($env.ALGA_COLOR_RESET)"
error make { msg: $"($env.ALGA_COLOR_RED)Migration 'latest' failed($env.ALGA_COLOR_RESET)", code: $result.exit_code }
}
}
"down" => {
print $"($env.ALGA_COLOR_CYAN)Reverting last database migration...($env.ALGA_COLOR_RESET)"
# Change to the server directory and run the knex command
# Capture stdout and stderr
let result = do {
cd ($project_root | path join "server")
npx knex migrate:down --knexfile knexfile.cjs --env migration | complete
}
# Print output or error
if $result.exit_code == 0 {
print $result.stdout # Keep knex output as is
print $"($env.ALGA_COLOR_GREEN)Migration reverted successfully.($env.ALGA_COLOR_RESET)"
} else {
print $"($env.ALGA_COLOR_RED)($result.stderr)($env.ALGA_COLOR_RESET)"
error make { msg: $"($env.ALGA_COLOR_RED)Migration revert failed($env.ALGA_COLOR_RESET)", code: $result.exit_code }
}
}
"status" => {
print $"($env.ALGA_COLOR_CYAN)Checking migration status...($env.ALGA_COLOR_RESET)"
# Change to the server directory and run the knex command
# Capture stdout and stderr
let result = do {
cd ($project_root | path join "server")
npx knex migrate:status --knexfile knexfile.cjs --env migration | complete
}
# Print output or error
if $result.exit_code == 0 {
print $result.stdout # Keep knex output as is
print $"($env.ALGA_COLOR_GREEN)Migration status checked successfully.($env.ALGA_COLOR_RESET)"
} else {
print $"($env.ALGA_COLOR_RED)($result.stderr)($env.ALGA_COLOR_RESET)"
error make { msg: $"($env.ALGA_COLOR_RED)Checking migration status failed($env.ALGA_COLOR_RESET)", code: $result.exit_code }
}
}
_ => {
# This case should technically not be reachable due to the type annotation
# but it's good practice to include it.
error make { msg: $"($env.ALGA_COLOR_RED)Unknown migration action: ($action)($env.ALGA_COLOR_RESET)" }
}
}
}