From 753e49b3dc619b3df9ce6187e3cccf369aa7feca Mon Sep 17 00:00:00 2001 From: Kasra Bigdeli Date: Sat, 5 Sep 2026 22:04:04 -0700 Subject: [PATCH] Consolidate release configuration --- edge-override.json | 4 -- release/build-and-push.sh | 19 ++++---- release/create-draft-release.sh | 4 +- release/dockerfile.edge | 5 ++- release/release.conf | 7 +++ release/validate-version.sh | 78 ++++++++------------------------- src/utils/CaptainConstants.ts | 19 +++++++- 7 files changed, 59 insertions(+), 77 deletions(-) delete mode 100644 edge-override.json create mode 100644 release/release.conf diff --git a/edge-override.json b/edge-override.json deleted file mode 100644 index 84032033..00000000 --- a/edge-override.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "publishedNameOnDockerHub": "caprover/caprover-edge", - "version": "0.0.1" -} \ No newline at end of file diff --git a/release/build-and-push.sh b/release/build-and-push.sh index 496ee0ea..1d26fe4c 100755 --- a/release/build-and-push.sh +++ b/release/build-and-push.sh @@ -6,6 +6,9 @@ set -e # Print all commands set -x +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. "$SCRIPT_DIR/release.conf" + CHANNEL="${1:-}" if [ "$#" -ne 1 ] || { [ "$CHANNEL" != "edge" ] && [ "$CHANNEL" != "release" ]; }; then @@ -22,15 +25,15 @@ fi if [ "$CHANNEL" = "edge" ]; then EXPECTED_BRANCH=master - CAPROVER_VERSION=0.0.1 - IMAGE_NAME=caprover/caprover-edge + CAPROVER_VERSION="$EDGE_VERSION" + IMAGE_NAME="$EDGE_IMAGE_NAME" DOCKERFILE=release/dockerfile.edge - FRONTEND_COMMIT_HASH='' + FRONTEND_COMMIT_HASH="$EDGE_FRONTEND_COMMIT" else EXPECTED_BRANCH=release - IMAGE_NAME=caprover/caprover + IMAGE_NAME="$CAPROVER_IMAGE_NAME" DOCKERFILE=release/dockerfile.release - FRONTEND_COMMIT_HASH=c9005cc2e5ac1b6816cb983d2d3732338c546a94 + FRONTEND_COMMIT_HASH="$RELEASE_FRONTEND_COMMIT" fi # Ensure publishing only happens from the expected GitHub Actions branch. @@ -49,10 +52,10 @@ if [ "$BRANCH" != "$EXPECTED_BRANCH" ]; then fi sudo apt-get update -sudo apt-get install -y jq qemu-user-static +sudo apt-get install -y qemu-user-static if [ "$CHANNEL" = "release" ]; then - CAPROVER_VERSION="$(./release/validate-version.sh "$IMAGE_NAME")" + ./release/validate-version.sh fi ## Building frontend app @@ -61,7 +64,7 @@ FRONTEND_DIR=/home/runner/app-frontend curl -Iv https://registry.yarnpkg.com/ mkdir -p "$FRONTEND_DIR" -git clone https://github.com/githubsaturn/caprover-frontend.git "$FRONTEND_DIR/caprover-frontend" +git clone "$FRONTEND_REPOSITORY" "$FRONTEND_DIR/caprover-frontend" cd "$FRONTEND_DIR/caprover-frontend" if [ -n "$FRONTEND_COMMIT_HASH" ]; then git reset --hard "$FRONTEND_COMMIT_HASH" diff --git a/release/create-draft-release.sh b/release/create-draft-release.sh index b8cd3345..d01c38bc 100755 --- a/release/create-draft-release.sh +++ b/release/create-draft-release.sh @@ -3,7 +3,9 @@ set -e set -o pipefail -CAPROVER_VERSION="$(sed -n "s/^[[:space:]]*version: '\([^']*\)',/\1/p" src/utils/CaptainConstants.ts)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. "$SCRIPT_DIR/release.conf" + RELEASE_NOTES="$( awk -v version="$CAPROVER_VERSION" ' BEGIN { heading = "## [" version "]" } diff --git a/release/dockerfile.edge b/release/dockerfile.edge index 96e873c2..aec8e782 100644 --- a/release/dockerfile.edge +++ b/release/dockerfile.edge @@ -10,7 +10,8 @@ RUN npm ci && \ npm run build && \ npm ci --omit=dev && \ npm cache clean --force && \ - mv ./edge-override.json ./config-override.json + . ./release/release.conf && \ + printf '{"publishedNameOnDockerHub":"%s","version":"%s"}\n' "$EDGE_IMAGE_NAME" "$EDGE_VERSION" > ./config-override.json # Final stage uses the target platform's Node.js runtime FROM node:24-alpine @@ -26,4 +27,4 @@ ENV NODE_ENV production ENV PORT 3000 EXPOSE 3000 -CMD ["node" , "./built/server.js"] \ No newline at end of file +CMD ["node" , "./built/server.js"] diff --git a/release/release.conf b/release/release.conf new file mode 100644 index 00000000..06afcab1 --- /dev/null +++ b/release/release.conf @@ -0,0 +1,7 @@ +CAPROVER_VERSION=1.15.4 +CAPROVER_IMAGE_NAME=caprover/caprover +EDGE_IMAGE_NAME=caprover/caprover-edge +EDGE_VERSION=0.0.1 +FRONTEND_REPOSITORY=https://github.com/githubsaturn/caprover-frontend.git +RELEASE_FRONTEND_COMMIT=c9005cc2e5ac1b6816cb983d2d3732338c546a94 +EDGE_FRONTEND_COMMIT= diff --git a/release/validate-version.sh b/release/validate-version.sh index 325df303..be161026 100755 --- a/release/validate-version.sh +++ b/release/validate-version.sh @@ -3,74 +3,32 @@ set -e set -o pipefail -IMAGE_NAME="${1:-}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. "$SCRIPT_DIR/release.conf" -if [ "$#" -ne 1 ] || [ -z "$IMAGE_NAME" ]; then - echo "Usage: $0 " >&2 +if ! command -v curl >/dev/null 2>&1; then + echo "curl is required to validate the release version." >&2 exit 1 fi -if ! command -v curl >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then - echo "curl and jq are required to validate the release version." >&2 - exit 1 -fi - -CAPROVER_VERSION="$(sed -n "s/^[[:space:]]*version: '\([^']*\)',/\1/p" src/utils/CaptainConstants.ts)" - if [[ ! "$CAPROVER_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Invalid CapRover version: $CAPROVER_VERSION" >&2 exit 1 fi -version_is_greater() { - local left_major left_minor left_patch - local right_major right_minor right_patch +TAG_URL="https://hub.docker.com/v2/repositories/${CAPROVER_IMAGE_NAME}/tags/${CAPROVER_VERSION}" +HTTP_STATUS="$(curl --silent --show-error --location --output /dev/null --write-out '%{http_code}' "$TAG_URL")" - IFS=. read -r left_major left_minor left_patch <<< "$1" - IFS=. read -r right_major right_minor right_patch <<< "$2" - - if ((10#$left_major != 10#$right_major)); then - ((10#$left_major > 10#$right_major)) - return - fi - - if ((10#$left_minor != 10#$right_minor)); then - ((10#$left_minor > 10#$right_minor)) - return - fi - - ((10#$left_patch > 10#$right_patch)) -} - -TAGS_URL="https://hub.docker.com/v2/repositories/${IMAGE_NAME}/tags?page_size=100" -HIGHEST_TAG='' - -while [ -n "$TAGS_URL" ]; do - TAGS_RESPONSE="$(curl --fail --silent --show-error --location "$TAGS_URL")" - - if ! jq -e '.results | type == "array"' >/dev/null 2>&1 <<< "$TAGS_RESPONSE"; then - echo "Invalid response while fetching tags from Docker Hub." >&2 +case "$HTTP_STATUS" in + 200) + echo "Version $CAPROVER_VERSION already exists on Docker Hub." >&2 exit 1 - fi - - while IFS= read -r TAG; do - if [[ "$TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && \ - { [ -z "$HIGHEST_TAG" ] || version_is_greater "$TAG" "$HIGHEST_TAG"; }; then - HIGHEST_TAG="$TAG" - fi - done < <(jq -r '.results[]?.name // empty' <<< "$TAGS_RESPONSE") - - TAGS_URL="$(jq -r '.next // empty' <<< "$TAGS_RESPONSE")" -done - -if [ -z "$HIGHEST_TAG" ]; then - echo "No published CapRover versions were found on Docker Hub." >&2 - exit 1 -fi - -if ! version_is_greater "$CAPROVER_VERSION" "$HIGHEST_TAG"; then - echo "The version you are pushing is not valid: $CAPROVER_VERSION (latest published: $HIGHEST_TAG)" >&2 - exit 1 -fi - -printf '%s\n' "$CAPROVER_VERSION" + ;; + 404) + printf '%s\n' "$CAPROVER_VERSION" + ;; + *) + echo "Docker Hub returned HTTP $HTTP_STATUS while validating version $CAPROVER_VERSION." >&2 + exit 1 + ;; +esac diff --git a/src/utils/CaptainConstants.ts b/src/utils/CaptainConstants.ts index bd1b21b6..3094efc7 100644 --- a/src/utils/CaptainConstants.ts +++ b/src/utils/CaptainConstants.ts @@ -2,6 +2,21 @@ import fs = require('fs-extra') import path = require('path') import EnvVars from './EnvVars' +const RELEASE_CONFIG_CONTENT = fs.readFileSync( + path.join(__dirname, '../../release/release.conf'), + 'utf8' +) + +function getReleaseConfigValue(key: string) { + const match = new RegExp(`^${key}=([^\\r\\n]+)$`, 'm').exec( + RELEASE_CONFIG_CONTENT + ) + if (!match) { + throw new Error(`Missing release config value: ${key}`) + } + return match[1] +} + const CAPTAIN_BASE_DIRECTORY = EnvVars.CAPTAIN_BASE_DIRECTORY || '/captain' const CAPTAIN_DATA_DIRECTORY = CAPTAIN_BASE_DIRECTORY + '/data' // data that sits here can be backed up const CAPTAIN_ROOT_DIRECTORY_TEMP = CAPTAIN_BASE_DIRECTORY + '/temp' @@ -15,9 +30,9 @@ const CONSTANT_FILE_OVERRIDE_USER = CAPTAIN_DATA_DIRECTORY + '/config-override.json' const configs = { - publishedNameOnDockerHub: 'caprover/caprover', + publishedNameOnDockerHub: getReleaseConfigValue('CAPROVER_IMAGE_NAME'), - version: '1.15.4', + version: getReleaseConfigValue('CAPROVER_VERSION'), defaultMaxLogSize: '512m',