Files
quik/.github/workflows/manual-release.yml
T
2026-01-25 06:34:58 -08:00

233 lines
7.2 KiB
YAML

name: Manual Release Prep
on:
workflow_dispatch:
inputs:
bump_component:
description: Which part of versionName should be bumped?
required: true
type: choice
options:
- patch
- minor
- major
jobs:
bump-version:
runs-on: ubuntu-latest
env:
GRADLE_FILE: presentation/build.gradle
outputs:
new_version_name: ${{ steps.bump.outputs.new_version_name }}
new_version_code: ${{ steps.bump.outputs.new_version_code }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Bump version in Gradle
id: bump
shell: bash
env:
BUMP_COMPONENT: ${{ inputs.bump_component }}
run: |
set -euo pipefail
python3 <<'PY'
import os
import pathlib
import re
import sys
gradle_file = pathlib.Path(os.environ["GRADLE_FILE"])
bump_component = os.environ["BUMP_COMPONENT"]
content = gradle_file.read_text()
code_pattern = re.compile(r"(^\s*versionCode\s+)(\d+)", re.MULTILINE)
name_pattern = re.compile(r"(^\s*versionName\s+['\"])(\d+\.\d+\.\d+)(['\"])", re.MULTILINE)
code_match = code_pattern.search(content)
name_match = name_pattern.search(content)
if not code_match or not name_match:
sys.stderr.write("Unable to locate versionCode or versionName in Gradle file.\n")
sys.exit(1)
current_code = int(code_match.group(2))
major, minor, patch = map(int, name_match.group(2).split("."))
if bump_component == "major":
major, minor, patch = major + 1, 0, 0
elif bump_component == "minor":
minor, patch = minor + 1, 0
elif bump_component == "patch":
patch += 1
else:
sys.stderr.write(f"Unsupported bump component: {bump_component}\n")
sys.exit(1)
new_name = f"{major}.{minor}.{patch}"
new_code = current_code + 1
content, code_count = code_pattern.subn(lambda m: f"{m.group(1)}{new_code}", content, count=1)
content, name_count = name_pattern.subn(lambda m: f"{m.group(1)}{new_name}{m.group(3)}", content, count=1)
if code_count != 1 or name_count != 1:
sys.stderr.write("Failed to update version fields uniquely.\n")
sys.exit(1)
gradle_file.write_text(content)
github_output = pathlib.Path(os.environ["GITHUB_OUTPUT"])
with github_output.open("a") as output_file:
output_file.write(f"new_version_name={new_name}\n")
output_file.write(f"new_version_code={new_code}\n")
PY
- name: Upload modified build.gradle
uses: actions/upload-artifact@v4
with:
name: version-bump-artifact
path: presentation/build.gradle
generate_release_notes:
needs: bump-version
uses: ./.github/workflows/generate-release-notes.yml
with:
version_name: ${{ needs.bump-version.outputs.new_version_name }}
generate_app_changelog:
needs: [bump-version, generate_release_notes]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- name: Prepare release notes
id: prepare_notes
env:
NOTES: ${{ needs.generate_release_notes.outputs.release_notes }}
run: |
set -euo pipefail
python3 <<'PY'
import os, re, pathlib
notes = os.environ.get("NOTES", "")
clean = re.sub(
r'(?im)^\s*by\s+\S+\s+in\s+.*$',
'',
re.sub(r'(?im)^\s*["\']?\*\*Full\s+Changelog\*\*\s*:\s*.*$', '', notes)
).rstrip()
pathlib.Path("sanitized_notes.txt").write_text(clean)
PY
{
echo "clean_notes<<EOF"
cat sanitized_notes.txt
echo ""
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Add to changelog.json
env:
VERSION_NAME: ${{ needs.bump-version.outputs.new_version_name }}
VERSION_CODE: ${{ needs.bump-version.outputs.new_version_code }}
CLEAN_NOTES: ${{ steps.prepare_notes.outputs.clean_notes }}
run: |
set -euo pipefail
python3 <<'PY'
import json
import os
from pathlib import Path
changelog_path = Path("data/src/main/assets/changelog.json")
version_name = os.environ["VERSION_NAME"]
version_code = int(os.environ["VERSION_CODE"])
notes_raw = os.environ.get("CLEAN_NOTES", "")
notes = [
line.strip()
for line in notes_raw.splitlines()
if line.strip()
]
if changelog_path.exists():
changelog = json.loads(changelog_path.read_text())
else:
changelog = []
new_entry = {
"versionCode": version_code,
"versionName": version_name,
"fixed": notes
}
changelog.insert(0, new_entry)
changelog_path.write_text(
json.dumps(changelog, indent=2, ensure_ascii=False) + "\n"
)
PY
- name: Upload changelog.json
uses: actions/upload-artifact@v4
with:
name: changelog-json-artifact
path: data/src/main/assets/changelog.json
open_release_pr:
needs: [bump-version, generate_release_notes, generate_app_changelog]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- name: Download modified build.gradle
uses: actions/download-artifact@v4
with:
name: version-bump-artifact
path: presentation/
- name: Download modified changelog
uses: actions/download-artifact@v4
with:
name: changelog-json-artifact
path: data/src/main/assets/
- name: Open release PR
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: release/v${{ needs.bump-version.outputs.new_version_name }}
delete-branch: false
commit-message: "chore: release v${{ needs.bump-version.outputs.new_version_name }} (${{ needs.bump-version.outputs.new_version_code }})"
title: Release v${{ needs.bump-version.outputs.new_version_name }} (${{ needs.bump-version.outputs.new_version_code }})
body: |
## Summary
- bump `versionName` to `${{ needs.bump-version.outputs.new_version_name }}`
- bump `versionCode` to `${{ needs.bump-version.outputs.new_version_code }}`
Triggered manually via the Manual Release Prep workflow with **${{ inputs.bump_component }}** bump.
## Auto-generated release notes
${{ needs.generate_release_notes.outputs.release_notes }}