diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index d4fe794913..084ca38aca 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -17,6 +17,15 @@ on: description: 'Bump mobile build number' required: false type: boolean + rc: + description: 'Release candidate mode' + required: false + default: 'false' + type: choice + options: + - 'false' + - 'true' + - 'finalize' skipTranslations: description: 'Skip translations' required: false @@ -74,7 +83,8 @@ jobs: env: SERVER_BUMP: ${{ inputs.serverBump }} MOBILE_BUMP: ${{ inputs.mobileBump }} - run: misc/release/pump-version.sh -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}" + RC: ${{ inputs.rc }} + run: misc/release/pump-version.sh -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}" -r "${RC}" - id: output run: echo "version=$IMMICH_VERSION" >> $GITHUB_OUTPUT @@ -108,7 +118,7 @@ jobs: with: ref: ${{ needs.bump_version.outputs.ref }} - environment: production + environment: ${{ inputs.rc != 'false' && 'rc' || 'production' }} prepare_release: runs-on: ubuntu-latest @@ -140,6 +150,7 @@ jobs: uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2 with: draft: true + prerelease: ${{ contains(needs.bump_version.outputs.version, '-rc.') }} tag_name: ${{ needs.bump_version.outputs.version }} token: ${{ steps.generate-token.outputs.token }} generate_release_notes: true diff --git a/misc/release/pump-version.sh b/misc/release/pump-version.sh index 39a3364723..3a8721520b 100755 --- a/misc/release/pump-version.sh +++ b/misc/release/pump-version.sh @@ -3,21 +3,26 @@ # # Pump one or both of the server/mobile versions in appropriate files # -# usage: './scripts/pump-version.sh -s <-m> +# usage: './scripts/pump-version.sh -s <-m> <-r> # # examples: # ./scripts/pump-version.sh -s major # 1.0.0+50 => 2.0.0+50 # ./scripts/pump-version.sh -s minor -m true # 1.0.0+50 => 1.1.0+51 # ./scripts/pump-version.sh -m true # 1.0.0+50 => 1.0.0+51 +# ./scripts/pump-version.sh -s minor -m true -r true # 3.0.0 => 3.1.0-rc.1 (start RC) +# ./scripts/pump-version.sh -m true -r true # 3.1.0-rc.1 => 3.1.0-rc.2 (iterate RC) +# ./scripts/pump-version.sh -m true -r finalize # 3.1.0-rc.2 => 3.1.0 (finalize RC) # SERVER_PUMP="false" MOBILE_PUMP="false" +RC="false" -while getopts 's:m:' flag; do +while getopts 's:m:r:' flag; do case "${flag}" in s) SERVER_PUMP=${OPTARG} ;; m) MOBILE_PUMP=${OPTARG} ;; + r) RC=${OPTARG} ;; *) echo "Invalid args" exit 1 @@ -25,10 +30,51 @@ while getopts 's:m:' flag; do esac done +if [[ "$RC" != "true" && "$RC" != "false" && "$RC" != "finalize" ]]; then + echo "Expected for the -r argument" + exit 1 +fi + CURRENT_SERVER=$(jq -r '.version' server/package.json) -MAJOR=$(echo "$CURRENT_SERVER" | cut -d '.' -f1) -MINOR=$(echo "$CURRENT_SERVER" | cut -d '.' -f2) -PATCH=$(echo "$CURRENT_SERVER" | cut -d '.' -f3) + +if [[ "$CURRENT_SERVER" == *-rc.* ]]; then + CURRENT_BASE="${CURRENT_SERVER%-rc.*}" + CURRENT_RC_NUM="${CURRENT_SERVER##*-rc.}" +else + CURRENT_BASE="$CURRENT_SERVER" + CURRENT_RC_NUM="" +fi + +# Validate RC/server-bump combinations against current version state +if [[ -n "$CURRENT_RC_NUM" ]]; then + # Currently on an RC + if [[ "$RC" == "false" ]]; then + echo "Current version $CURRENT_SERVER is a release candidate. Pass -r true to iterate the RC or -r finalize to finalize the release." + exit 1 + fi + if [[ "$RC" == "true" && "$SERVER_PUMP" != "false" ]]; then + echo "Cannot start a new RC while still on an RC; finalize first." + exit 1 + fi + if [[ "$RC" == "finalize" && "$SERVER_PUMP" != "false" ]]; then + echo "Finalize takes no server bump." + exit 1 + fi +else + # Not currently on an RC + if [[ "$RC" == "true" && "$SERVER_PUMP" == "false" ]]; then + echo "Starting an RC requires a server bump." + exit 1 + fi + if [[ "$RC" == "finalize" ]]; then + echo "Nothing to finalize." + exit 1 + fi +fi + +MAJOR=$(echo "$CURRENT_BASE" | cut -d '.' -f1) +MINOR=$(echo "$CURRENT_BASE" | cut -d '.' -f2) +PATCH=$(echo "$CURRENT_BASE" | cut -d '.' -f3) if [[ $SERVER_PUMP == "major" ]]; then MAJOR=$((MAJOR + 1)) @@ -46,7 +92,22 @@ else exit 1 fi -NEXT_SERVER=$MAJOR.$MINOR.$PATCH +NEXT_BASE=$MAJOR.$MINOR.$PATCH + +if [[ "$RC" == "true" ]]; then + if [[ -n "$CURRENT_RC_NUM" ]]; then + # Iterate existing RC + NEXT_RC_NUM=$((CURRENT_RC_NUM + 1)) + NEXT_SERVER="${NEXT_BASE}-rc.${NEXT_RC_NUM}" + else + # Start new RC after server bump + NEXT_SERVER="${NEXT_BASE}-rc.1" + fi +elif [[ "$RC" == "finalize" ]]; then + NEXT_SERVER="$NEXT_BASE" +else + NEXT_SERVER="$NEXT_BASE" +fi CURRENT_MOBILE=$(grep "^version: .*+[0-9]\+$" mobile/pubspec.yaml | cut -d "+" -f2) NEXT_MOBILE=$CURRENT_MOBILE @@ -72,9 +133,12 @@ if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then # copy version to open-api spec mise run //:open-api - uv version --directory machine-learning "$NEXT_SERVER" + NEXT_PY="${NEXT_SERVER//-rc./rc}" + uv version --directory machine-learning "$NEXT_PY" - ./misc/release/archive-version.js "$NEXT_SERVER" + if [[ "$NEXT_SERVER" != *-rc.* ]]; then + ./misc/release/archive-version.js "$NEXT_SERVER" + fi fi if [ "$CURRENT_MOBILE" != "$NEXT_MOBILE" ]; then @@ -84,7 +148,9 @@ fi sed -i "s/\"android\.injected\.version\.name\" => \"$CURRENT_SERVER\",/\"android\.injected\.version\.name\" => \"$NEXT_SERVER\",/" mobile/android/fastlane/Fastfile sed -i "s/\"android\.injected\.version\.code\" => $CURRENT_MOBILE,/\"android\.injected\.version\.code\" => $NEXT_MOBILE,/" mobile/android/fastlane/Fastfile sed -i "s/^version: $CURRENT_SERVER+$CURRENT_MOBILE$/version: $NEXT_SERVER+$NEXT_MOBILE/" mobile/pubspec.yaml -perl -i -p0e "s/(CFBundleShortVersionString<\/key>\s*)$CURRENT_SERVER(<\/string>)/\${1}$NEXT_SERVER\${2}/s" mobile/ios/Runner/Info.plist +# iOS marketing version cannot contain a pre-release suffix; strip -rc.N before writing the plist. +IOS_NEXT="${NEXT_SERVER%-rc.*}" +perl -i -p0e "s/(CFBundleShortVersionString<\/key>\s*)$CURRENT_SERVER(<\/string>)/\${1}$IOS_NEXT\${2}/s" mobile/ios/Runner/Info.plist echo "IMMICH_VERSION=v$NEXT_SERVER" >>"$GITHUB_ENV"