From a5588e27a1d60620eba8b092f7911008de462e93 Mon Sep 17 00:00:00 2001 From: Remko Date: Thu, 19 Feb 2026 12:07:19 +0100 Subject: [PATCH] Fix unstable release --- .github/workflows/release-unstable.yaml | 4 +- .github/workflows/sync-dev.yaml | 4 +- WORKFLOW-UNSTABLE-RELEASE.md | 187 ++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 WORKFLOW-UNSTABLE-RELEASE.md diff --git a/.github/workflows/release-unstable.yaml b/.github/workflows/release-unstable.yaml index 0ec729f2..54b7a36c 100644 --- a/.github/workflows/release-unstable.yaml +++ b/.github/workflows/release-unstable.yaml @@ -30,7 +30,7 @@ jobs: unstable_counter=1 if [[ $current_version =~ -unstable\.([0-9]+)$ ]]; then - current_patch=$(echo $current_version | grep -oP '^[0-9]+\.[0-9]+\.(\d+)' | cut -d. -f3) + current_patch=$(echo $current_version | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+' | cut -d. -f3) if [ "$current_patch" -eq "$next_patch" ]; then unstable_counter=$((BASH_REMATCH[1] + 1)) fi @@ -50,6 +50,8 @@ jobs: run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" + + # Only commit if there are actual changes if git diff --quiet && git diff --cached --quiet; then echo "No changes to commit" else diff --git a/.github/workflows/sync-dev.yaml b/.github/workflows/sync-dev.yaml index 6b141154..e24e2379 100644 --- a/.github/workflows/sync-dev.yaml +++ b/.github/workflows/sync-dev.yaml @@ -52,8 +52,8 @@ jobs: sed -i "s|.*|${DEV_RELEASE_VERSION}|" appinfo/info.xml git add appinfo/info.xml git commit -m "${COMMIT_MSG} - - Restored development-release version to ${DEV_RELEASE_VERSION} [skip ci]" + + Restored development-release version to ${DEV_RELEASE_VERSION}" fi git push -f origin development-release diff --git a/WORKFLOW-UNSTABLE-RELEASE.md b/WORKFLOW-UNSTABLE-RELEASE.md new file mode 100644 index 00000000..18af4a1b --- /dev/null +++ b/WORKFLOW-UNSTABLE-RELEASE.md @@ -0,0 +1,187 @@ +# Unstable Release Workflow - Flow Documentation + +## Overview +This document explains how the unstable release workflow operates when you merge/push to the `development` branch. + +## Complete Flow + +### Step 1: Push to Development Branch +**Trigger:** Developer merges PR or pushes directly to `development` + +**What happens:** +- Changes are committed to `development` branch +- `sync-dev.yaml` workflow is triggered + +--- + +### Step 2: Sync to Development-Release (`sync-dev.yaml`) +**File:** `.github/workflows/sync-dev.yaml` + +**Process:** +1. Fetches all branches from remote +2. **Preserves** the existing version from `development-release` branch (if it exists) + - Example: If `development-release` has `0.1.140-unstable.2`, it stores this +3. Resets `development-release` to match `development` content (all files except version) +4. **Restores** the preserved version back to `appinfo/info.xml` +5. Commits with message: "Restored development-release version to X.X.X-unstable.X" +6. Force pushes to `development-release` + +**Key Point:** This workflow syncs all code changes but keeps the unstable version intact! + +--- + +### Step 3: Release Unstable (`release-unstable.yaml`) +**File:** `.github/workflows/release-unstable.yaml` +**Trigger:** Push to `development-release` branch (from step 2) + +**Version Calculation Logic:** + +```bash +# Example: main = 0.1.139, current = 0.1.138 +main_version = "0.1.139" +current_version = "0.1.138" # or "0.1.140-unstable.1" + +# Calculate next patch from main +next_patch = 139 + 1 = 140 + +# Check if current version already has unstable suffix +if current_version matches "-unstable.X": + extract current_patch from current_version + if current_patch == next_patch: + # Same base version, increment counter + unstable_counter = X + 1 + else: + # Different base version, reset counter + unstable_counter = 1 +else: + # No unstable suffix, start fresh + unstable_counter = 1 + +new_version = "0.1.{next_patch}-unstable.{unstable_counter}" +``` + +**Process:** +1. Fetches `main` branch to get stable version +2. Gets current version from `development-release` +3. Calculates new unstable version (see logic above) +4. Updates `appinfo/info.xml` with new version +5. Commits with `[skip ci]` to prevent infinite loop +6. Pushes version bump back to `development-release` +7. Builds the app (npm, composer) +8. Creates tarball and signs it +9. Creates GitHub prerelease with tag `vX.X.X-unstable.X` +10. Uploads to Nextcloud App Store as nightly build + +--- + +## Version Examples + +### Scenario 1: First Unstable Release +- **Main:** `0.1.139` +- **Current development-release:** `0.1.138` (no unstable suffix) +- **Result:** `0.1.140-unstable.1` ✓ + +### Scenario 2: Incrementing Unstable Counter +- **Main:** `0.1.139` +- **Current development-release:** `0.1.140-unstable.1` +- **Result:** `0.1.140-unstable.2` ✓ + +### Scenario 3: Multiple Increments +- **Main:** `0.1.139` +- **Current development-release:** `0.1.140-unstable.5` +- **Result:** `0.1.140-unstable.6` ✓ + +### Scenario 4: Main Version Bumped +- **Main:** `0.1.140` (was released to main) +- **Current development-release:** `0.1.140-unstable.3` +- **Result:** `0.1.141-unstable.1` ✓ (new series starts) + +--- + +## Key Fixes Applied + +### Fix 1: sync-dev.yaml (Line 56) +**Before:** +```yaml +Restored development-release version to ${DEV_RELEASE_VERSION} [skip ci] +``` + +**After:** +```yaml +Restored development-release version to ${DEV_RELEASE_VERSION} +``` + +**Reason:** Removed `[skip ci]` so the release workflow triggers properly + +--- + +### Fix 2: release-unstable.yaml (Line 33) +**Before:** +```bash +current_patch=$(echo $current_version | grep -oP '^[0-9]+\.[0-9]+\.(\d+)' | cut -d. -f3) +``` + +**After:** +```bash +current_patch=$(echo $current_version | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+' | cut -d. -f3) +``` + +**Reason:** The `\d+` pattern doesn't work in grep -P, changed to `[0-9]+` + +--- + +## Testing the Workflow + +To test locally (simulation only, no release): +```powershell +# Set test values +$mainVersion = "0.1.136" +$currentVersion = "0.1.137-unstable.1" + +# Extract parts +$parts = $mainVersion.Split('.') +$nextPatch = [int]$parts[2] + 1 + +# Check for unstable suffix +$unstableCounter = 1 +if ($currentVersion -match '-unstable\.(\d+)$') { + $currentPatch = ($currentVersion -split '\.')[2] -replace '-.*', '' + if ($currentPatch -eq $nextPatch) { + $unstableCounter = [int]$matches[1] + 1 + } +} + +$unstableVersion = "$($parts[0]).$($parts[1]).$nextPatch-unstable.$unstableCounter" +Write-Host "Next version: $unstableVersion" +``` + +--- + +## Important Notes + +1. **[skip ci] is required** in the version bump commit to prevent infinite loop +2. **Version preservation** in sync-dev ensures continuity across syncs +3. **Force push** is safe in sync-dev because development-release is a controlled branch +4. **Prerelease flag** marks GitHub releases as unstable +5. **Nightly flag** marks Nextcloud App Store uploads as development builds + +--- + +## Workflow Dependencies + +``` +development (push) + ↓ +sync-dev.yaml (syncs code, preserves version) + ↓ +development-release (updated) + ↓ +release-unstable.yaml (bumps version, builds, releases) + ↓ +GitHub Release (prerelease) +Nextcloud App Store (nightly) +``` + +--- + +Generated: 2026-02-19