Compare commits
No commits in common. "d89a58c0ab7b6f5c21bf4c7f6f124d38b0492180" and "e8a638d11d8d3f1dae14b6d5d03f8a88e5b0b2a3" have entirely different histories.
d89a58c0ab
...
e8a638d11d
|
|
@ -11,30 +11,7 @@ source "$ROOT_DIR/scripts/config.sh"
|
||||||
git push origin main
|
git push origin main
|
||||||
|
|
||||||
# SSH to target and update
|
# SSH to target and update
|
||||||
ssh "$HOST" "cd $DEST && git pull origin main && bun run build"
|
ssh "$HOST" "cd $DEST && git pull origin main && bun run build && sudo systemctl restart toes.service"
|
||||||
|
|
||||||
# Sync default apps/tools from repo to APPS_DIR
|
|
||||||
echo "=> Syncing default apps..."
|
|
||||||
ssh "$HOST" bash -s "$DEST" "$APPS_DIR" <<'SCRIPT'
|
|
||||||
DEST="$1"
|
|
||||||
APPS_DIR="$2"
|
|
||||||
for app_dir in "$DEST"/apps/*/; do
|
|
||||||
app=$(basename "$app_dir")
|
|
||||||
for version_dir in "$app_dir"*/; do
|
|
||||||
[ -d "$version_dir" ] || continue
|
|
||||||
version=$(basename "$version_dir")
|
|
||||||
[ -f "$version_dir/package.json" ] || continue
|
|
||||||
target="$APPS_DIR/$app/$version"
|
|
||||||
mkdir -p "$target"
|
|
||||||
cp -a "$version_dir"/. "$target"/
|
|
||||||
rm -f "$APPS_DIR/$app/current"
|
|
||||||
echo " $app/$version"
|
|
||||||
(cd "$target" && bun install --frozen-lockfile 2>/dev/null || bun install)
|
|
||||||
done
|
|
||||||
done
|
|
||||||
SCRIPT
|
|
||||||
|
|
||||||
ssh "$HOST" "sudo systemctl restart toes.service"
|
|
||||||
|
|
||||||
echo "=> Deployed to $HOST"
|
echo "=> Deployed to $HOST"
|
||||||
echo "=> Visit $URL"
|
echo "=> Visit $URL"
|
||||||
|
|
|
||||||
|
|
@ -7,62 +7,11 @@ interface EnvVar {
|
||||||
value: string
|
value: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseKeyValue(keyOrKeyValue: string, valueArg?: string): { key: string, value: string } | null {
|
export async function envList(name: string | undefined) {
|
||||||
if (valueArg !== undefined) {
|
|
||||||
const key = keyOrKeyValue.trim()
|
|
||||||
if (!key) { console.error('Key cannot be empty'); return null }
|
|
||||||
return { key, value: valueArg }
|
|
||||||
}
|
|
||||||
const eqIndex = keyOrKeyValue.indexOf('=')
|
|
||||||
if (eqIndex === -1) {
|
|
||||||
console.error('Invalid format. Use: KEY value or KEY=value')
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const key = keyOrKeyValue.slice(0, eqIndex).trim()
|
|
||||||
if (!key) { console.error('Key cannot be empty'); return null }
|
|
||||||
return { key, value: keyOrKeyValue.slice(eqIndex + 1) }
|
|
||||||
}
|
|
||||||
|
|
||||||
async function globalEnvSet(keyOrKeyValue: string, valueArg?: string) {
|
|
||||||
const parsed = parseKeyValue(keyOrKeyValue, valueArg)
|
|
||||||
if (!parsed) return
|
|
||||||
const { key, value } = parsed
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await post<{ ok: boolean, error?: string }>('/api/env', { key, value })
|
|
||||||
if (result?.ok) {
|
|
||||||
console.log(color.green(`Set global ${color.bold(key.toUpperCase())}`))
|
|
||||||
} else {
|
|
||||||
console.error(result?.error ?? 'Failed to set variable')
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
handleError(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function envList(name: string | undefined, opts: { global?: boolean }) {
|
|
||||||
if (opts.global) {
|
|
||||||
const vars = await get<EnvVar[]>('/api/env')
|
|
||||||
console.log(color.bold().cyan('Global Environment Variables'))
|
|
||||||
console.log()
|
|
||||||
if (!vars || vars.length === 0) {
|
|
||||||
console.log(color.gray(' No global environment variables set'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for (const v of vars) {
|
|
||||||
console.log(` ${color.bold(v.key)}=${color.gray(v.value)}`)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const appName = resolveAppName(name)
|
const appName = resolveAppName(name)
|
||||||
if (!appName) return
|
if (!appName) return
|
||||||
|
|
||||||
const [vars, globalVars] = await Promise.all([
|
const vars = await get<EnvVar[]>(`/api/apps/${appName}/env`)
|
||||||
get<EnvVar[]>(`/api/apps/${appName}/env`),
|
|
||||||
get<EnvVar[]>('/api/env'),
|
|
||||||
])
|
|
||||||
|
|
||||||
if (!vars) {
|
if (!vars) {
|
||||||
console.error(`App not found: ${appName}`)
|
console.error(`App not found: ${appName}`)
|
||||||
return
|
return
|
||||||
|
|
@ -71,9 +20,7 @@ export async function envList(name: string | undefined, opts: { global?: boolean
|
||||||
console.log(color.bold().cyan(`Environment Variables for ${appName}`))
|
console.log(color.bold().cyan(`Environment Variables for ${appName}`))
|
||||||
console.log()
|
console.log()
|
||||||
|
|
||||||
const appKeys = new Set(vars.map(v => v.key))
|
if (vars.length === 0) {
|
||||||
|
|
||||||
if (vars.length === 0 && (!globalVars || globalVars.length === 0)) {
|
|
||||||
console.log(color.gray(' No environment variables set'))
|
console.log(color.gray(' No environment variables set'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -81,30 +28,31 @@ export async function envList(name: string | undefined, opts: { global?: boolean
|
||||||
for (const v of vars) {
|
for (const v of vars) {
|
||||||
console.log(` ${color.bold(v.key)}=${color.gray(v.value)}`)
|
console.log(` ${color.bold(v.key)}=${color.gray(v.value)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalVars && globalVars.length > 0) {
|
|
||||||
const inherited = globalVars.filter(v => !appKeys.has(v.key))
|
|
||||||
if (inherited.length > 0) {
|
|
||||||
if (vars.length > 0) console.log()
|
|
||||||
console.log(color.gray(' Inherited from global:'))
|
|
||||||
for (const v of inherited) {
|
|
||||||
console.log(` ${color.bold(v.key)}=${color.gray(v.value)}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function envSet(name: string | undefined, keyOrKeyValue: string, valueArg: string | undefined, opts: { global?: boolean }) {
|
export async function envSet(name: string | undefined, keyOrKeyValue: string, valueArg?: string) {
|
||||||
// With --global, args shift: name becomes key, key becomes value
|
let key: string
|
||||||
if (opts.global) {
|
let value: string
|
||||||
const actualKey = name ?? keyOrKeyValue
|
|
||||||
const actualValue = name ? keyOrKeyValue : valueArg
|
if (valueArg !== undefined) {
|
||||||
return globalEnvSet(actualKey, actualValue)
|
// KEY value format
|
||||||
|
key = keyOrKeyValue.trim()
|
||||||
|
value = valueArg
|
||||||
|
} else {
|
||||||
|
// KEY=value format
|
||||||
|
const eqIndex = keyOrKeyValue.indexOf('=')
|
||||||
|
if (eqIndex === -1) {
|
||||||
|
console.error('Invalid format. Use: KEY value or KEY=value')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key = keyOrKeyValue.slice(0, eqIndex).trim()
|
||||||
|
value = keyOrKeyValue.slice(eqIndex + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const parsed = parseKeyValue(keyOrKeyValue, valueArg)
|
if (!key) {
|
||||||
if (!parsed) return
|
console.error('Key cannot be empty')
|
||||||
const { key, value } = parsed
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const appName = resolveAppName(name)
|
const appName = resolveAppName(name)
|
||||||
if (!appName) return
|
if (!appName) return
|
||||||
|
|
@ -122,21 +70,7 @@ export async function envSet(name: string | undefined, keyOrKeyValue: string, va
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function envRm(name: string | undefined, key: string, opts: { global?: boolean }) {
|
export async function envRm(name: string | undefined, key: string) {
|
||||||
// With --global, args shift: name becomes key
|
|
||||||
if (opts.global) {
|
|
||||||
const actualKey = name ?? key
|
|
||||||
if (!actualKey) {
|
|
||||||
console.error('Key is required')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const ok = await del(`/api/env/${actualKey.toUpperCase()}`)
|
|
||||||
if (ok) {
|
|
||||||
console.log(color.green(`Removed global ${color.bold(actualKey.toUpperCase())}`))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key) {
|
if (!key) {
|
||||||
console.error('Key is required')
|
console.error('Key is required')
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,6 @@ const env = program
|
||||||
.helpGroup('Config:')
|
.helpGroup('Config:')
|
||||||
.description('Manage environment variables')
|
.description('Manage environment variables')
|
||||||
.argument('[name]', 'app name (uses current directory if omitted)')
|
.argument('[name]', 'app name (uses current directory if omitted)')
|
||||||
.option('-g, --global', 'manage global variables shared by all apps')
|
|
||||||
.action(envList)
|
.action(envList)
|
||||||
|
|
||||||
env
|
env
|
||||||
|
|
@ -240,7 +239,6 @@ env
|
||||||
.argument('[name]', 'app name (uses current directory if omitted)')
|
.argument('[name]', 'app name (uses current directory if omitted)')
|
||||||
.argument('<key>', 'variable name')
|
.argument('<key>', 'variable name')
|
||||||
.argument('[value]', 'variable value (or use KEY=value format)')
|
.argument('[value]', 'variable value (or use KEY=value format)')
|
||||||
.option('-g, --global', 'set a global variable shared by all apps')
|
|
||||||
.action(envSet)
|
.action(envSet)
|
||||||
|
|
||||||
env
|
env
|
||||||
|
|
@ -248,7 +246,6 @@ env
|
||||||
.description('Remove an environment variable')
|
.description('Remove an environment variable')
|
||||||
.argument('[name]', 'app name (uses current directory if omitted)')
|
.argument('[name]', 'app name (uses current directory if omitted)')
|
||||||
.argument('<key>', 'variable name to remove')
|
.argument('<key>', 'variable name to remove')
|
||||||
.option('-g, --global', 'remove a global variable')
|
|
||||||
.action(envRm)
|
.action(envRm)
|
||||||
|
|
||||||
program
|
program
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user