Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/dev-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ jobs:
--image-tag "${IMAGE_NAME}:dev" \
--base-url "${dev_base_url}" \
--installer-release-url "${dev_base_url}/release.json" \
--installer-update-release-url "${dev_base_url}/release.json" \
--installer-compose-url "${dev_base_url}/docker-compose.image.yml" \
--installer-manager-url "${dev_base_url}/subboost-manager" \
--installer-image "${IMAGE_NAME}:dev"
Expand Down
5 changes: 4 additions & 1 deletion local/scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ set -Eeuo pipefail
DEFAULT_HOME="/opt/subboost"
DEFAULT_BIN="/usr/local/bin/subboost"
DEFAULT_RELEASE_URL="https://github.com/SubBoost/subboost/releases/latest/download/release.json"
DEFAULT_UPDATE_RELEASE_URL="https://github.com/SubBoost/subboost/releases/latest/download/release.json"
DEFAULT_COMPOSE_URL="https://github.com/SubBoost/subboost/releases/latest/download/docker-compose.image.yml"
DEFAULT_MANAGER_URL="https://github.com/SubBoost/subboost/releases/latest/download/subboost-manager"
DEFAULT_IMAGE="ghcr.io/subboost/subboost:latest"

SUBBOOST_HOME="${SUBBOOST_HOME:-$DEFAULT_HOME}"
SUBBOOST_BIN="${SUBBOOST_BIN:-$DEFAULT_BIN}"
SUBBOOST_RELEASE_URL="${SUBBOOST_RELEASE_URL:-$DEFAULT_RELEASE_URL}"
SUBBOOST_UPDATE_RELEASE_URL="${SUBBOOST_UPDATE_RELEASE_URL:-$DEFAULT_UPDATE_RELEASE_URL}"
SUBBOOST_ASSUME_YES="${SUBBOOST_ASSUME_YES:-0}"
SUBBOOST_DRY_RUN="${SUBBOOST_DRY_RUN:-0}"

Expand Down Expand Up @@ -563,6 +565,7 @@ main() {
say "[dry-run] image=$image"
say "[dry-run] composeUrl=$compose_url"
say "[dry-run] managerUrl=$manager_url"
say "[dry-run] updateReleaseUrl=$SUBBOOST_UPDATE_RELEASE_URL"
exit 0
fi

Expand All @@ -576,7 +579,7 @@ main() {
if [ -f "$ENV_FILE" ]; then existing_env="1"; fi

set_env_value SUBBOOST_IMAGE "$image"
set_env_value SUBBOOST_RELEASE_URL "$SUBBOOST_RELEASE_URL"
set_env_value SUBBOOST_RELEASE_URL "$SUBBOOST_UPDATE_RELEASE_URL"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve explicit custom update sources

When an operator installs from a custom/fork/dev manifest by setting SUBBOOST_RELEASE_URL but does not also know to set the newly added SUBBOOST_UPDATE_RELEASE_URL, this persists the default official latest manifest into .env. Since subboost update later reads SUBBOOST_RELEASE_URL in update_cmd, those installs silently switch update channels after the first install instead of continuing to update from the requested source.

Useful? React with 👍 / 👎.

set_env_value SUBBOOST_COMPOSE_URL "$compose_url"
set_env_value SUBBOOST_MANAGER_URL "$manager_url"
ensure_env_value POSTGRES_DB "subboost"
Expand Down
77 changes: 77 additions & 0 deletions local/scripts/selfhost-shell.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,83 @@ ENV
expect(result.stdout).toContain("curl_count=7");
}, 10_000);

it("uses refreshed release metadata before pulling during update", () => {
const script = `
set -Eeuo pipefail
home="$(mktemp -d)"
trap 'rm -rf "$home"' EXIT
release_dir="$home/release"
mkdir -p "$release_dir" "$home/bin"
cat > "$release_dir/release.json" <<'JSON'
{"image":"new-image","composeUrl":"docker-compose.image.yml","managerUrl":"subboost-manager"}
JSON
printf 'services:\\n app:\\n image: \${SUBBOOST_IMAGE}\\n' > "$release_dir/docker-compose.image.yml"
printf '#!/usr/bin/env bash\\necho manager\\n' > "$release_dir/subboost-manager"
cat > "$home/.env" <<ENV
SUBBOOST_RELEASE_URL=file://$release_dir/release.json
SUBBOOST_IMAGE=old-image
POSTGRES_DB=subboost
POSTGRES_USER=subboost
POSTGRES_PASSWORD=password
DATABASE_URL=postgresql://subboost:password@db:5432/subboost?schema=public
ENCRYPTION_KEY=key
JWT_SECRET=jwt
CRON_SECRET=cron
APP_URL=http://127.0.0.1:31000
SUBBOOST_PORT=31000
ENV
: > "$home/docker-compose.yml"
export SUBBOOST_SCRIPT_SOURCE_ONLY=1
export SUBBOOST_HOME="$home"
export SUBBOOST_BIN="$home/bin/subboost"
export SUBBOOST_DOCTOR_HEALTH_ATTEMPTS=1
export SUBBOOST_DOCTOR_HEALTH_INTERVAL_SECONDS=0
source local/scripts/subboost.sh
sudo_do() { "$@"; }
install_secret_file() { cp "$1" "$2"; }
read_env_file() { cat "$ENV_FILE"; }
docker_log="$home/docker-log"
: > "$docker_log"
docker() {
if [ "$1" = "info" ]; then return 0; fi
if [ "$1" = "compose" ]; then
case "$*" in
"compose version"*) return 0 ;;
*" config") return 0 ;;
*" pull")
printf 'pull_image=%s\\n' "\${SUBBOOST_IMAGE:-}" >> "$docker_log"
return 0
;;
*" up -d --remove-orphans") return 0 ;;
*" up -d --no-deps --force-recreate app") return 0 ;;
*" ps -q app") printf 'app-id\\n'; return 0 ;;
*" ps -q db") printf 'db-id\\n'; return 0 ;;
*" ps -q cron") printf 'cron-id\\n'; return 0 ;;
esac
fi
if [ "$1" = "inspect" ]; then
case "$*" in
*".State.Status"*) printf 'running\\n'; return 0 ;;
*".State.Health"*) printf 'healthy\\n'; return 0 ;;
esac
fi
return 0
}
curl() { return 0; }
update_cmd
cat "$docker_log"
cat "$home/.env"
`;

const result = runBash(script);

expect(result.status).toBe(0);
expect(result.stdout).toContain("pull_image=new-image");
expect(result.stdout).toContain("SUBBOOST_IMAGE=new-image");
expect(result.stdout).toContain("SUBBOOST_COMPOSE_URL=file://");
expect(result.stdout).toContain("SUBBOOST_MANAGER_URL=file://");
}, 10_000);

it("updates exact env keys without removing similarly prefixed names", () => {
const script = `
set -Eeuo pipefail
Expand Down
13 changes: 10 additions & 3 deletions local/scripts/subboost.sh
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ write_env_value() {
install_secret_file "$tmp" "$ENV_FILE"
}

write_runtime_env_value() {
local key="$1"
local value="$2"
write_env_value "$key" "$value"
export "$key=$value"
}

install_file_from_url() {
local url="$1"
local destination="$2"
Expand Down Expand Up @@ -278,14 +285,14 @@ update_cmd() {
image="$(json_get image "$release_file" || true)"
compose_url="$(resolve_url "$release_url" "$(json_get composeUrl "$release_file" || true)")"
manager_url="$(resolve_url "$release_url" "$(json_get managerUrl "$release_file" || true)")"
if [ -n "$image" ]; then write_env_value SUBBOOST_IMAGE "$image"; fi
if [ -n "$image" ]; then write_runtime_env_value SUBBOOST_IMAGE "$image"; fi
if [ -n "$compose_url" ]; then
install_file_from_url "$compose_url" "$COMPOSE_FILE" 644
write_env_value SUBBOOST_COMPOSE_URL "$compose_url"
write_runtime_env_value SUBBOOST_COMPOSE_URL "$compose_url"
fi
if [ -n "$manager_url" ]; then
install_file_from_url "$manager_url" "${SUBBOOST_BIN:-/usr/local/bin/subboost}" 755
write_env_value SUBBOOST_MANAGER_URL "$manager_url"
write_runtime_env_value SUBBOOST_MANAGER_URL "$manager_url"
fi
else
say "Release manifest unavailable; updating current image and compose only."
Expand Down
9 changes: 8 additions & 1 deletion scripts/selfhost-release-assets.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ const INSTALLER_DEFAULTS = [
name: "DEFAULT_RELEASE_URL",
value: "https://github.com/SubBoost/subboost/releases/latest/download/release.json",
},
{
arg: "--installer-update-release-url",
env: "SUBBOOST_INSTALLER_UPDATE_RELEASE_URL",
key: "installerUpdateReleaseUrl",
name: "DEFAULT_UPDATE_RELEASE_URL",
value: "https://github.com/SubBoost/subboost/releases/latest/download/release.json",
},
{
arg: "--installer-compose-url",
env: "SUBBOOST_INSTALLER_COMPOSE_URL",
Expand All @@ -40,7 +47,7 @@ const INSTALLER_DEFAULTS = [
function usage() {
return [
"Usage:",
" node scripts/selfhost-release-assets.cjs [--output <dir>] [--image <image>] [--image-tag <image>] [--base-url <url>] [--tag <vX.Y.Z>] [--build-sha <sha>] [--installer-release-url <url>] [--installer-compose-url <url>] [--installer-manager-url <url>] [--installer-image <image>] [--dry-run]",
" node scripts/selfhost-release-assets.cjs [--output <dir>] [--image <image>] [--image-tag <image>] [--base-url <url>] [--tag <vX.Y.Z>] [--build-sha <sha>] [--installer-release-url <url>] [--installer-update-release-url <url>] [--installer-compose-url <url>] [--installer-manager-url <url>] [--installer-image <image>] [--dry-run]",
"",
"Creates release.json, install.sh, docker-compose.image.yml, and subboost-manager for GitHub Release assets.",
].join("\n");
Expand Down
Loading