From 63e26040fa3335326c5d6873b3544645fb03dc5f Mon Sep 17 00:00:00 2001 From: "markus.block" Date: Sun, 15 Mar 2026 12:05:52 +0100 Subject: [PATCH] release-process-improvements (#10) Reviewed-on: https://gitea.netzwissen.de/lxcafe/lxcafe/pulls/10 --- 01_prepare_release.sh | 128 +++++++++++++++++++++++++++++++++++++++++ 02_finalise_release.sh | 42 ++++++++++++++ README.md | 39 ++++++++----- release.sh | 92 ----------------------------- 4 files changed, 194 insertions(+), 107 deletions(-) create mode 100755 01_prepare_release.sh create mode 100755 02_finalise_release.sh delete mode 100755 release.sh diff --git a/01_prepare_release.sh b/01_prepare_release.sh new file mode 100755 index 0000000..0d6cc96 --- /dev/null +++ b/01_prepare_release.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash + +set -e + +question_answered_with_yes() { + local prompt="$1" + local ans + printf '%b\n Enter y or n and press Enter,\n abort with any other key ... [y/N]: ' "$prompt" + read -r ans + case "$ans" in + y|Y) return 0 ;; + n|N|"") return 1 ;; + *) echo "Aborted."; exit 1 ;; + esac +} + +if [ -n "$(git status --porcelain)" ]; then + echo "Error: You have uncommitted local changes." + echo "Please commit or stash them before releasing." + echo "" + echo "Uncommitted files:" + git status --short + exit 1 +fi + +echo "Fetching latest changes..." +git fetch origin + +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) +if [ "$CURRENT_BRANCH" = "main" ]; then + echo "Pulling latest from main..." + git pull origin main || true +else + echo "Error: You must be on the main branch to create a release." + echo "Current branch: $CURRENT_BRANCH" + exit 1 +fi + +VERSION_FILE="VERSION" +SCRIPT_FILE="post_installation_script/Nachinstallationsarbeiten_LC_Esslingen_XFCE.sh" + +if [ ! -f "$VERSION_FILE" ]; then + echo "Error: $VERSION_FILE not found" + exit 1 +fi + +CURRENT_VERSION=$(cat "$VERSION_FILE" | tr -d '\n') + +if [ ! -f "$SCRIPT_FILE" ]; then + echo "Error: $SCRIPT_FILE not found" + exit 1 +fi + +CURRENT_MAJOR=${CURRENT_VERSION#v} + +if ! [[ "$CURRENT_VERSION" =~ ^v[0-9]+$ ]]; then + echo "Error: Invalid version format in $VERSION_FILE. Expected v0, v1, v2, etc." + exit 1 +fi + +NEXT_VERSION=$((CURRENT_MAJOR + 1)) +NEXT_VERSION_STR="v$NEXT_VERSION" + +RELEASE_BRANCH="release/$NEXT_VERSION_STR" + +if git ls-remote --heads origin "$RELEASE_BRANCH" 2>/dev/null | grep -q .; then + echo "Error: Branch $RELEASE_BRANCH already exists on remote." + exit 1 +fi + +if git rev-parse "$RELEASE_BRANCH" >/dev/null 2>&1; then + echo "Branch $RELEASE_BRANCH exists locally." + if question_answered_with_yes "Delete local branch and continue?"; then + git branch -D "$RELEASE_BRANCH" + else + echo "Release aborted." + exit 0 + fi +fi + +echo "Current version: $CURRENT_VERSION" +echo "Proposed version: $NEXT_VERSION_STR" +echo "Release branch: $RELEASE_BRANCH" +echo "" + +if ! question_answered_with_yes "Confirm release version $NEXT_VERSION_STR?"; then + echo "Release aborted." + exit 0 +fi + +echo "Creating release branch $RELEASE_BRANCH..." +git checkout -b "$RELEASE_BRANCH" + +echo "$NEXT_VERSION_STR" > "$VERSION_FILE" + +sed -i.bak "s/^SCRIPT_VERSION=.*/SCRIPT_VERSION=\"$NEXT_VERSION_STR\"/" "$SCRIPT_FILE" +if [ -f "${SCRIPT_FILE}.bak" ]; then + rm "${SCRIPT_FILE}.bak" +fi + +git add "$VERSION_FILE" "$SCRIPT_FILE" +git commit -m "Release $NEXT_VERSION_STR" + +echo "" +echo "Release $NEXT_VERSION_STR prepared on branch $RELEASE_BRANCH." +if question_answered_with_yes "Push release branch to origin?"; then + git push -u origin "$RELEASE_BRANCH" + echo "" + echo "Branch pushed to origin." + echo "" + echo "Next steps:" + echo "1. Create a PR from $RELEASE_BRANCH to main" + echo " - Via web: Go to your git hosting and create a PR" + echo " - Or: gh pr create --base main --head $RELEASE_BRANCH" + echo "" + echo "2. After PR is merged, create a tag:" + echo " git checkout main && git pull" + echo " git tag -a $NEXT_VERSION_STR -m \"Release $NEXT_VERSION_STR\"" + echo " git push origin $NEXT_VERSION_STR" + echo "" + echo "3. Gitea will create a release from the tag" +else + echo "" + echo "Release prepared locally. Push manually with:" + echo " git push -u origin $RELEASE_BRANCH" + echo "" + echo "Then create a PR to main via your git hosting." +fi diff --git a/02_finalise_release.sh b/02_finalise_release.sh new file mode 100755 index 0000000..7168856 --- /dev/null +++ b/02_finalise_release.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +set -e + +question_answered_with_yes() { + local prompt="$1" + local ans + printf '%b\n Enter y or n and press Enter,\n abort with any other key ... [y/N]: ' "$prompt" + read -r ans + case "$ans" in + y|Y) return 0 ;; + n|N|"") return 1 ;; + *) echo "Aborted."; exit 1 ;; + esac +} + +echo "Fetching latest from origin..." +git fetch origin +git checkout main +git pull origin main + +VERSION_FILE="VERSION" +CURRENT_VERSION=$(cat "$VERSION_FILE" | tr -d '\n') + +echo "Finalising release of version: $CURRENT_VERSION" + +if ! question_answered_with_yes "Create tag $CURRENT_VERSION on main?"; then + echo "Tag creation aborted." + exit 0 +fi + +git tag -a "$CURRENT_VERSION" -m "Release $CURRENT_VERSION" + +if question_answered_with_yes "Push tag to origin?"; then + git push origin "$CURRENT_VERSION" + echo "" + echo "Tag $CURRENT_VERSION pushed to origin." + echo "Gitea will create a release from the tag." +else + echo "Tag created locally. Push manually with:" + echo " git push origin $CURRENT_VERSION" +fi diff --git a/README.md b/README.md index 04d62a2..68acc18 100644 --- a/README.md +++ b/README.md @@ -20,30 +20,39 @@ This way you can test the script multiple times without needing to reinstall Lin ## Release Process -This project uses a simple release process based on git tags. +This project uses a two-step release process. ### Versioning - Version is stored in `VERSION` file (format: v0, v1, v2, ...) -- Major version increments only (major-bugfix scheme) -- Script version is also stored in `SCRIPT_VERSION` variable within the main script to display version during script execution +- Major version increments only +- Script version stored in `SCRIPT_VERSION` variable -### Creating a Release -Run the release script from the repository root: +### Step 1: Prepare Release +- Make sure you are on main branch with no local changes. Script will abort otherwise +Run from repository root: ```bash -./release.sh +./01_prepare_release.sh ``` The script will: -1. Check for uncommitted local changes (exits if any exist) -2. Show current version and propose next version -3. Prompt for confirmation -4. Update VERSION file and SCRIPT_VERSION in the script -5. Create a git commit -6. Create an annotated tag -7. Prompt to push to origin (including tags) +- Update VERSION file and SCRIPT_VERSION in the script +- Create a release branch (e.g., `release/v1`) +- Push the release branch -### Gitea Integration -When a tag is pushed to the remote, Gitea automatically creates a release from it. +### After step 1 (manual) +- Create and merge PR from release branch to main + +### Step 2: Finalize Release (After PR Merged) +Run from repository root: +```bash +./02_finalise_release.sh +``` + +The script will: +- Create and push tag for release version to main + +### After step 2 (manual) +- Create a release in gitea ### Requirements - Clean working tree (no uncommitted changes) diff --git a/release.sh b/release.sh deleted file mode 100755 index 2e33b62..0000000 --- a/release.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if [ -n "$(git status --porcelain)" ]; then - echo "Error: You have uncommitted local changes." - echo "Please commit or stash them before releasing." - echo "" - echo "Uncommitted files:" - git status --short - exit 1 -fi - -CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) -if [ "$CURRENT_BRANCH" != "main" ]; then - echo "Error: You must be on the main branch to release." - echo "Current branch: $CURRENT_BRANCH" - exit 1 -fi - -VERSION_FILE="VERSION" -SCRIPT_FILE="post_installation_script/Nachinstallationsarbeiten_LC_Esslingen_XFCE.sh" - -if [ ! -f "$VERSION_FILE" ]; then - echo "Error: $VERSION_FILE not found" - exit 1 -fi - -CURRENT_VERSION=$(cat "$VERSION_FILE" | tr -d '\n') - -if [ ! -f "$SCRIPT_FILE" ]; then - echo "Error: $SCRIPT_FILE not found" - exit 1 -fi - -CURRENT_MAJOR=${CURRENT_VERSION#v} - -if ! [[ "$CURRENT_VERSION" =~ ^v[0-9]+$ ]]; then - echo "Error: Invalid version format in $VERSION_FILE. Expected v0, v1, v2, etc." - exit 1 -fi - -NEXT_VERSION=$((CURRENT_MAJOR + 1)) -NEXT_VERSION_STR="v$NEXT_VERSION" - -if git rev-parse "refs/tags/$NEXT_VERSION_STR" >/dev/null 2>&1; then - echo "Error: Tag $NEXT_VERSION_STR already exists locally." - exit 1 -fi - -if git remote get-url origin >/dev/null 2>&1; then - if git ls-remote --tags origin "$NEXT_VERSION_STR" 2>/dev/null | grep -q "$NEXT_VERSION_STR"; then - echo "Error: Tag $NEXT_VERSION_STR already exists on remote." - exit 1 - fi -else - echo "Warning: No remote configured. You can still create the release locally." -fi - -echo "Current version: $CURRENT_VERSION" -echo "Proposed version: $NEXT_VERSION_STR" -echo "" - -read -p "Confirm release version $NEXT_VERSION_STR? [y/N]: " confirm - -if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then - echo "Release aborted." - exit 0 -fi - -echo "$NEXT_VERSION_STR" > "$VERSION_FILE" - -sed -i.bak "s/^SCRIPT_VERSION=.*/SCRIPT_VERSION=\"$NEXT_VERSION_STR\"/" "$SCRIPT_FILE" -if [ -f "${SCRIPT_FILE}.bak" ]; then - rm "${SCRIPT_FILE}.bak" -fi - -git add "$VERSION_FILE" "$SCRIPT_FILE" -git commit -m "Release $NEXT_VERSION_STR" - -git tag -a "$NEXT_VERSION_STR" -m "Release $NEXT_VERSION_STR" - -echo "" -echo "Tag $NEXT_VERSION_STR created locally." -read -p "Push to origin (includes tags)? [y/N]: " push_confirm - -if [[ "$push_confirm" == "y" || "$push_confirm" == "Y" ]]; then - git push origin main --tags - echo "Done! Gitea will create release from tag $NEXT_VERSION_STR" -else - echo "Release prepared locally. Push manually with: git push origin main --tags" -fi