From beae0942a1150b0b46c88759765aee0006e1d0ad Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Thu, 12 Mar 2026 08:11:04 -0700 Subject: [PATCH] Add dynamic versioning with VERSION file and tag-based patch counting - Create VERSION file (currently `0.2`) as the single source of truth for major.minor - Add compute-version job that reads VERSION and counts commits since the last matching v{major.minor}.N tag to derive the patch number - Patch resets automatically when VERSION is bumped (no matching tags exist yet) - Add create-tag job that tags the repo after all platform builds succeed, so subsequent builds count from the new tag - All platform jobs now consume the shared version instead of computing their own - VERSION file changes trigger the build workflow Co-Authored-By: Claude Opus 4.6 --- .gitea/workflows/build-app.yml | 112 ++++++++++++++++++++++----------- VERSION | 1 + 2 files changed, 77 insertions(+), 36 deletions(-) create mode 100644 VERSION diff --git a/.gitea/workflows/build-app.yml b/.gitea/workflows/build-app.yml index c5dfe06..a19c7dd 100644 --- a/.gitea/workflows/build-app.yml +++ b/.gitea/workflows/build-app.yml @@ -5,11 +5,13 @@ on: branches: [main] paths: - "app/**" + - "VERSION" - ".gitea/workflows/build-app.yml" pull_request: branches: [main] paths: - "app/**" + - "VERSION" - ".gitea/workflows/build-app.yml" workflow_dispatch: @@ -18,10 +20,43 @@ env: REPO: ${{ gitea.repository }} jobs: - build-linux: + compute-version: runs-on: ubuntu-latest outputs: version: ${{ steps.version.outputs.VERSION }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Fetch all tags + run: git fetch --tags + + - name: Compute version from VERSION file and tags + id: version + run: | + MAJOR_MINOR=$(cat VERSION | tr -d '[:space:]') + echo "Major.Minor: ${MAJOR_MINOR}" + + # Find the latest tag matching v{MAJOR_MINOR}.N (exclude -mac, -win suffixes) + LATEST_TAG=$(git tag -l "v${MAJOR_MINOR}.*" --sort=-v:refname | grep -E "^v${MAJOR_MINOR}\.[0-9]+$" | head -1) + + if [ -n "$LATEST_TAG" ]; then + echo "Latest matching tag: ${LATEST_TAG}" + PATCH=$(git rev-list --count "${LATEST_TAG}..HEAD") + else + echo "No matching tag found for v${MAJOR_MINOR}.*, using total commit count" + PATCH=$(git rev-list --count HEAD) + fi + + VERSION="${MAJOR_MINOR}.${PATCH}" + echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT + echo "Computed version: ${VERSION}" + + build-linux: + runs-on: ubuntu-latest + needs: [compute-version] steps: - name: Install Node.js 22 run: | @@ -54,17 +89,9 @@ jobs: with: fetch-depth: 0 - - name: Compute version - id: version - run: | - COMMIT_COUNT=$(git rev-list --count HEAD) - VERSION="0.2.${COMMIT_COUNT}" - echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - echo "Computed version: ${VERSION}" - - name: Set app version run: | - VERSION="${{ steps.version.outputs.VERSION }}" + VERSION="${{ needs.compute-version.outputs.version }}" sed -i "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" app/src-tauri/tauri.conf.json sed -i "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" app/package.json sed -i "s/^version = \".*\"/version = \"${VERSION}\"/" app/src-tauri/Cargo.toml @@ -133,7 +160,7 @@ jobs: env: TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | - TAG="v${{ steps.version.outputs.VERSION }}" + TAG="v${{ needs.compute-version.outputs.version }}" # Create release curl -s -X POST \ -H "Authorization: token ${TOKEN}" \ @@ -156,6 +183,7 @@ jobs: build-macos: runs-on: macos-latest + needs: [compute-version] steps: - name: Install Node.js 22 run: | @@ -183,17 +211,9 @@ jobs: with: fetch-depth: 0 - - name: Compute version - id: version - run: | - COMMIT_COUNT=$(git rev-list --count HEAD) - VERSION="0.2.${COMMIT_COUNT}" - echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - echo "Computed version: ${VERSION}" - - name: Set app version run: | - VERSION="${{ steps.version.outputs.VERSION }}" + VERSION="${{ needs.compute-version.outputs.version }}" sed -i '' "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" app/src-tauri/tauri.conf.json sed -i '' "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" app/package.json sed -i '' "s/^version = \".*\"/version = \"${VERSION}\"/" app/src-tauri/Cargo.toml @@ -243,12 +263,12 @@ jobs: env: TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | - TAG="v${{ steps.version.outputs.VERSION }}-mac" + TAG="v${{ needs.compute-version.outputs.version }}-mac" # Create release curl -s -X POST \ -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ - -d "{\"tag_name\": \"${TAG}\", \"name\": \"Triple-C v${{ steps.version.outputs.VERSION }} (macOS)\", \"body\": \"Automated build from commit ${{ gitea.sha }}\"}" \ + -d "{\"tag_name\": \"${TAG}\", \"name\": \"Triple-C v${{ needs.compute-version.outputs.version }} (macOS)\", \"body\": \"Automated build from commit ${{ gitea.sha }}\"}" \ "${GITEA_URL}/api/v1/repos/${REPO}/releases" > release.json RELEASE_ID=$(cat release.json | grep -o '"id":[0-9]*' | head -1 | grep -o '[0-9]*') echo "Release ID: ${RELEASE_ID}" @@ -266,6 +286,7 @@ jobs: build-windows: runs-on: windows-latest + needs: [compute-version] defaults: run: shell: cmd @@ -275,18 +296,10 @@ jobs: with: fetch-depth: 0 - - name: Compute version - id: version - run: | - for /f %%i in ('git rev-list --count HEAD') do set "COMMIT_COUNT=%%i" - set "VERSION=0.2.%COMMIT_COUNT%" - echo VERSION=%VERSION%>> %GITHUB_OUTPUT% - echo Computed version: %VERSION% - - name: Set app version shell: powershell run: | - $version = "${{ steps.version.outputs.VERSION }}" + $version = "${{ needs.compute-version.outputs.version }}" (Get-Content app/src-tauri/tauri.conf.json) -replace '"version": ".*?"', "`"version`": `"$version`"" | Set-Content app/src-tauri/tauri.conf.json (Get-Content app/package.json) -replace '"version": ".*?"', "`"version`": `"$version`"" | Set-Content app/package.json (Get-Content app/src-tauri/Cargo.toml) -replace '^version = ".*?"', "version = `"$version`"" | Set-Content app/src-tauri/Cargo.toml @@ -367,9 +380,9 @@ jobs: TOKEN: ${{ secrets.REGISTRY_TOKEN }} COMMIT_SHA: ${{ gitea.sha }} run: | - set "TAG=v${{ steps.version.outputs.VERSION }}-win" + set "TAG=v${{ needs.compute-version.outputs.version }}-win" echo Creating release %TAG%... - curl -s -X POST -H "Authorization: token %TOKEN%" -H "Content-Type: application/json" -d "{\"tag_name\": \"%TAG%\", \"name\": \"Triple-C v${{ steps.version.outputs.VERSION }} (Windows)\", \"body\": \"Automated build from commit %COMMIT_SHA%\"}" "%GITEA_URL%/api/v1/repos/%REPO%/releases" > release.json + curl -s -X POST -H "Authorization: token %TOKEN%" -H "Content-Type: application/json" -d "{\"tag_name\": \"%TAG%\", \"name\": \"Triple-C v${{ needs.compute-version.outputs.version }} (Windows)\", \"body\": \"Automated build from commit %COMMIT_SHA%\"}" "%GITEA_URL%/api/v1/repos/%REPO%/releases" > release.json for /f "tokens=2 delims=:," %%a in ('findstr /c:"\"id\"" release.json') do set "RELEASE_ID=%%a" & goto :found :found echo Release ID: %RELEASE_ID% @@ -378,9 +391,36 @@ jobs: curl -s -X POST -H "Authorization: token %TOKEN%" -H "Content-Type: application/octet-stream" --data-binary "@%%f" "%GITEA_URL%/api/v1/repos/%REPO%/releases/%RELEASE_ID%/assets?name=%%~nxf" ) + create-tag: + runs-on: ubuntu-latest + needs: [compute-version, build-linux, build-macos, build-windows] + if: gitea.event_name == 'push' + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Create version tag + env: + TOKEN: ${{ secrets.REGISTRY_TOKEN }} + run: | + VERSION="${{ needs.compute-version.outputs.version }}" + TAG="v${VERSION}" + echo "Creating tag ${TAG}..." + + # Create annotated tag via Gitea API + curl -s -X POST \ + -H "Authorization: token ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\": \"${TAG}\", \"target\": \"${{ gitea.sha }}\", \"message\": \"Release ${TAG}\"}" \ + "${GITEA_URL}/api/v1/repos/${REPO}/tags" || echo "Tag may already exist (created by release)" + + echo "Tag ${TAG} created successfully" + sync-to-github: runs-on: ubuntu-latest - needs: [build-linux, build-macos, build-windows] + needs: [compute-version, build-linux, build-macos, build-windows] if: gitea.event_name == 'push' env: GH_PAT: ${{ secrets.GH_PAT }} @@ -389,7 +429,7 @@ jobs: - name: Download artifacts from Gitea releases env: TOKEN: ${{ secrets.REGISTRY_TOKEN }} - VERSION: ${{ needs.build-linux.outputs.version }} + VERSION: ${{ needs.compute-version.outputs.version }} run: | set -e mkdir -p artifacts @@ -418,7 +458,7 @@ jobs: - name: Create GitHub release and upload artifacts env: - VERSION: ${{ needs.build-linux.outputs.version }} + VERSION: ${{ needs.compute-version.outputs.version }} COMMIT_SHA: ${{ gitea.sha }} run: | set -e diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..2f45361 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.2 \ No newline at end of file