]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Add GitHub Actions workflow for release automation release-workflow
authorshamoon <4887959+shamoon@users.noreply.github.com>
Wed, 3 Sep 2025 23:53:17 +0000 (16:53 -0700)
committershamoon <4887959+shamoon@users.noreply.github.com>
Wed, 3 Sep 2025 23:53:17 +0000 (16:53 -0700)
.github/workflows/release.yml [new file with mode: 0644]

diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644 (file)
index 0000000..6cf50e5
--- /dev/null
@@ -0,0 +1,135 @@
+name: Paperless-ngx Release
+on:
+  workflow_dispatch:
+    inputs:
+      version:
+        description: "Release version (e.g., 2.18.3)"
+        required: true
+        type: string
+permissions:
+  contents: write
+  actions: read
+concurrency:
+  group: release-main
+  cancel-in-progress: false
+jobs:
+  release:
+    runs-on: ubuntu-24.04
+    steps:
+      - name: Checkout (full)
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+      - name: Configure git
+        run: |
+          git config user.name  "${{ github.actor }}"
+          git config user.email "${{ github.actor }}@users.noreply.github.com"
+      - name: Sanitize & validate input
+        id: ver
+        shell: bash
+        run: |
+          RAW="${{ github.event.inputs.version }}"
+          # trim spaces + strip leading 'v' if present
+          RAW="${RAW//[[:space:]]/}"
+          RAW="${RAW#v}"
+
+          # basic semver X.Y.Z
+          if [[ ! "$RAW" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+            echo "❌ Invalid version: '$RAW' (expected X.Y.Z or vX.Y.Z)"; exit 1
+          fi
+
+          MAJOR="${RAW%%.*}"
+          REST="${RAW#*.}"
+          MINOR="${REST%%.*}"
+          PATCH="${REST#*.}"
+
+          echo "version=$RAW"   >> "$GITHUB_OUTPUT"
+          echo "major=$MAJOR"   >> "$GITHUB_OUTPUT"
+          echo "minor=$MINOR"   >> "$GITHUB_OUTPUT"
+          echo "patch=$PATCH"   >> "$GITHUB_OUTPUT"
+
+          echo "✅ Using version $RAW"
+      - name: Ensure tag does not already exist
+        run: |
+          git fetch --tags
+          if git rev-parse "v${{ steps.ver.outputs.version }}" >/dev/null 2>&1; then
+            echo "❌ Tag v${{ steps.ver.outputs.version }} already exists"; exit 1
+          fi
+      - name: Update local branches
+        run: |
+          git fetch origin main dev
+      - name: Fast-forward main to dev (no merge commits)
+        run: |
+          # Reset local main to remote, then try fast-forward to dev.
+          git checkout main
+          git reset --hard origin/main
+          # --ff-only ensures the workflow fails if the branches diverged.
+          git merge --ff-only origin/dev
+          echo "✅ main fast-forwarded to dev at $(git rev-parse --short HEAD)"
+      - name: Bump versions in files
+        shell: bash
+        run: |
+          VER="${{ steps.ver.outputs.version }}"
+          MAJ="${{ steps.ver.outputs.major }}"
+          MIN="${{ steps.ver.outputs.minor }}"
+          PAT="${{ steps.ver.outputs.patch }}"
+
+          # 1) pyproject.toml: [project] version = "X.Y.Z"
+          sed -i -E 's/^version = "[0-9]+\.[0-9]+\.[0-9]+"/version = "'"$VER"'"/' pyproject.toml
+
+          # 2) src-ui/package.json: "version": "X.Y.Z"
+          # Use jq if available; otherwise sed fallback.
+          if command -v jq >/dev/null 2>&1; then
+            tmp=$(mktemp)
+            jq --arg v "$VER" '.version=$v' src-ui/package.json > "$tmp" && mv "$tmp" src-ui/package.json
+          else
+            sed -i -E 's/"version": "[0-9]+\.[0-9]+\.[0-9]+"/"version": "'"$VER"'"/' src-ui/package.json
+          fi
+
+          # 3) src-ui/src/environments/environment.prod.ts: version: 'X.Y.Z'
+          sed -i -E "s/version: '[0-9]+\.[0-9]+\.[0-9]+'/version: '$VER'/" src-ui/src/environments/environment.prod.ts
+
+          # 4) src/paperless/version.py: __version__ = (X, Y, Z)
+          sed -i -E "s/__version__:\s*Final\[tuple\[int,\s*int,\s*int\]\]\s*=\s*\([0-9]+,\s*[0-9]+,\s*[0-9]+\)/__version__: Final[tuple[int, int, int]] = ($MAJ, $MIN, $PAT)/" src/paperless/version.py
+
+          # 5) uv.lock: in the [[package]] name = "paperless-ngx" block, set version = "X.Y.Z"
+          # This awk edits only the block for paperless-ngx.
+          awk -v ver="$VER" '
+            BEGIN{inpkg=0}
+            /^\[\[package\]\]/{inpkg=0}
+            /^\[\[package\]\]/{print; next}
+            {print > "/dev/stdout"}
+          ' uv.lock >/dev/null 2>&1 # noop to ensure awk exists
+
+          # More robust in-place edit with awk:
+          awk -v ver="$VER" '
+            BEGIN{inpkg=0}
+            /^\[\[package\]\]/{inpkg=0; print; next}
+            /^name = "paperless-ngx"/{inpkg=1; print; next}
+            inpkg && /^version = "/{
+              sub(/version = "[0-9]+\.[0-9]+\.[0-9]+"/, "version = \"" ver "\"")
+              print; next
+            }
+            {print}
+          ' uv.lock > uv.lock.new && mv uv.lock.new uv.lock
+
+          echo "✅ Files updated to $VER"
+      - name: Commit bump (if changes)
+        run: |
+          if git diff --quiet; then
+            echo "ℹ️ No changes to commit (versions may already match)";
+          else
+            git add pyproject.toml src-ui/package.json src-ui/src/environments/environment.prod.ts src/paperless/version.py uv.lock
+            git commit -m "Bump version to ${{ steps.ver.outputs.version }}"
+          fi
+      - name: Push main
+        run: |
+          # Push branch (even if no commit, ensures remote main == local)
+          git push origin HEAD:main
+      - name: Create and push tag
+        run: |
+          VER="${{ steps.ver.outputs.version }}"
+          git tag -a "v${VER}" -m "Release v${VER}"
+          git push origin "v${VER}"
+      - name: Done
+        run: echo "🎉 Release v${{ steps.ver.outputs.version }} created and pushed."