Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 19 additions & 93 deletions .github/workflows/build-release.yaml
Original file line number Diff line number Diff line change
@@ -1,105 +1,31 @@
# DEPRECATED: This workflow is being replaced by:
# - ci-tests.yml (for PR/push testing)
# - ci-build.yml (for unsigned build artifacts)
# - release.yml (for tag-triggered signed releases)
# DEPRECATED: This workflow has been replaced by the new CI/CD architecture:
# - build.yml (unsigned builds for all environments)
# - sign-test.yml (signs untrusted PR builds with test key)
# - sign-release.yml (signs production builds with release key)
#
# This workflow is kept temporarily for backward compatibility.
# For new releases, use 'git tag v*.*.*' and push the tag.
# This workflow is kept temporarily for backward compatibility and will be removed.
# See docs/VERSIONING.md for the new signing architecture documentation.

name: Build and Publish Android App (Legacy)
name: Build and Publish Android App (Legacy) [DEPRECATED]

on:
push:
branches: [master]
# Disabled - replaced by build.yml + sign-release.yml
workflow_dispatch: {}

permissions:
contents: read

jobs:
build_sign_release:
name: Build, Sign, and Release Android App
permissions:
contents: write
deprecated:
name: Deprecated Workflow
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for version calculation

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'

- name: Calculate version
id: version
- name: Notice
run: |
# Get the latest v*.*.* tag
LATEST_TAG=$(git describe --tags --abbrev=0 --match "v*.*.*" 2>/dev/null || echo "v0.0.0")
echo "Latest tag: $LATEST_TAG"

# Parse version components
VERSION_REGEX="^v([0-9]+)\.([0-9]+)\.([0-9]+)$"
if [[ $LATEST_TAG =~ $VERSION_REGEX ]]; then
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
PATCH="${BASH_REMATCH[3]}"
else
MAJOR=0
MINOR=0
PATCH=0
fi

# Count commits since the last tag
BUILD_COUNT=$(git rev-list --count HEAD "^${LATEST_TAG}" 2>/dev/null || echo "0")

# For beta builds, increment patch by 1 so betas are HIGHER than previous stable
# Example: after v5.4.3, betas are v5.4.4-beta.X (not v5.4.3-beta.X)
if [[ "$BUILD_COUNT" -gt 0 ]]; then
PATCH=$((PATCH + 1))
fi

echo "VERSION_MAJOR=$MAJOR" >> $GITHUB_OUTPUT
echo "VERSION_MINOR=$MINOR" >> $GITHUB_OUTPUT
echo "VERSION_PATCH=$PATCH" >> $GITHUB_OUTPUT
echo "VERSION_BUILD_COUNT=$BUILD_COUNT" >> $GITHUB_OUTPUT
echo "VERSION_NAME=v${MAJOR}.${MINOR}.${PATCH}-beta.${BUILD_COUNT}" >> $GITHUB_OUTPUT
echo "Version: v${MAJOR}.${MINOR}.${PATCH}-beta.${BUILD_COUNT}"

- name: Run tests before release
run: ./gradlew --no-daemon testDebugUnitTest
env:
VERSION_MAJOR: ${{ steps.version.outputs.VERSION_MAJOR }}
VERSION_MINOR: ${{ steps.version.outputs.VERSION_MINOR }}
VERSION_PATCH: ${{ steps.version.outputs.VERSION_PATCH }}
VERSION_BUILD_COUNT: ${{ steps.version.outputs.VERSION_BUILD_COUNT }}
VERSION_STABLE: 'false'

- name: Decode and Import Keystore
run: |
echo "$ANDROID_KEYSTORE_BASE64" | base64 -d > $GITHUB_WORKSPACE/keystore.jks
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}

- name: Build and Sign the App
run: ./gradlew --no-daemon app:assembleRelease
env:
ANDROID_KEYSTORE: ${{ github.workspace }}/keystore.jks
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASS }}
ANDROID_KEY_ALIAS: android
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASS }}
VERSION_MAJOR: ${{ steps.version.outputs.VERSION_MAJOR }}
VERSION_MINOR: ${{ steps.version.outputs.VERSION_MINOR }}
VERSION_PATCH: ${{ steps.version.outputs.VERSION_PATCH }}
VERSION_BUILD_COUNT: ${{ steps.version.outputs.VERSION_BUILD_COUNT }}
VERSION_STABLE: 'false'

- name: Create a GitHub Release
uses: softprops/action-gh-release@v2
with:
prerelease: true
files: app/build/outputs/apk/release/app-release.apk
tag_name: ${{ steps.version.outputs.VERSION_NAME }}
echo "This workflow is deprecated and has been replaced by:"
echo " - build.yml (unsigned builds)"
echo " - sign-test.yml (test signing)"
echo " - sign-release.yml (production signing)"
echo ""
echo "For new releases, push a git tag matching v*.*.* pattern."
exit 1
127 changes: 127 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Build Workflow - Builds unsigned APKs for all environments
#
# This workflow builds APKs but NEVER signs them. It has no access to signing secrets.
# The appropriate version naming is baked into the binary based on CI_BUILD_TYPE:
# - release: v1.2.3
# - prerelease: v1.2.3-dev.X+<sha>
# - test: ci-test-untrusted-1.2.3-dev.X+<sha>
#
# Artifacts are uploaded for downstream signing workflows.

name: Build

on:
push:
branches: ["master"]
tags: ["v*"]
pull_request:
branches: ["master"]

permissions:
contents: read

jobs:
build:
name: Build Unsigned APKs
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for version calculation

- name: Determine Build Type
id: build-type
run: |
if [[ $GITHUB_REF == refs/tags/v* ]]; then
echo "CI_BUILD_TYPE=release" >> $GITHUB_ENV
echo "build_type=release" >> $GITHUB_OUTPUT
elif [[ $GITHUB_REF == refs/heads/master ]]; then
echo "CI_BUILD_TYPE=prerelease" >> $GITHUB_ENV
echo "build_type=prerelease" >> $GITHUB_OUTPUT
else
echo "CI_BUILD_TYPE=test" >> $GITHUB_ENV
echo "build_type=test" >> $GITHUB_OUTPUT
fi

- name: Calculate Version
id: version
run: |
# Get the latest v*.*.* tag
LATEST_TAG=$(git describe --tags --abbrev=0 --match "v*.*.*" 2>/dev/null || echo "v0.0.0")
echo "Latest tag: $LATEST_TAG"

# Parse version components
VERSION_REGEX="^v([0-9]+)\.([0-9]+)\.([0-9]+)$"
if [[ $LATEST_TAG =~ $VERSION_REGEX ]]; then
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
PATCH="${BASH_REMATCH[3]}"
else
MAJOR=0
MINOR=0
PATCH=0
fi

# Count commits since the last tag
BUILD_COUNT=$(git rev-list --count HEAD "^${LATEST_TAG}" 2>/dev/null || echo "0")

echo "VERSION_MAJOR=$MAJOR" >> $GITHUB_OUTPUT
echo "VERSION_MINOR=$MINOR" >> $GITHUB_OUTPUT
echo "VERSION_PATCH=$PATCH" >> $GITHUB_OUTPUT
echo "VERSION_BUILD_COUNT=$BUILD_COUNT" >> $GITHUB_OUTPUT
echo "Version: ${MAJOR}.${MINOR}.${PATCH} (build count: ${BUILD_COUNT})"

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
cache: gradle

# Build untrusted flavor for test builds (PRs)
- name: Build Untrusted APK (for test signing)
if: steps.build-type.outputs.build_type == 'test'
run: ./gradlew --no-daemon :app:assembleUntrustedRelease
env:
VERSION_MAJOR: ${{ steps.version.outputs.VERSION_MAJOR }}
VERSION_MINOR: ${{ steps.version.outputs.VERSION_MINOR }}
VERSION_PATCH: ${{ steps.version.outputs.VERSION_PATCH }}
VERSION_BUILD_COUNT: ${{ steps.version.outputs.VERSION_BUILD_COUNT }}
VERSION_STABLE: 'false'
CI_BUILD_TYPE: test

# Build prod flavor for pre-release and release builds
- name: Build Prod APK (for release signing)
if: steps.build-type.outputs.build_type != 'test'
run: ./gradlew --no-daemon :app:assembleProdRelease
env:
VERSION_MAJOR: ${{ steps.version.outputs.VERSION_MAJOR }}
VERSION_MINOR: ${{ steps.version.outputs.VERSION_MINOR }}
VERSION_PATCH: ${{ steps.version.outputs.VERSION_PATCH }}
VERSION_BUILD_COUNT: ${{ steps.version.outputs.VERSION_BUILD_COUNT }}
VERSION_STABLE: ${{ steps.build-type.outputs.build_type == 'release' && 'true' || 'false' }}
CI_BUILD_TYPE: ${{ steps.build-type.outputs.build_type }}

- name: Upload Untrusted APK Artifact
if: steps.build-type.outputs.build_type == 'test'
uses: actions/upload-artifact@v4
with:
name: unsigned-untrusted-apk
path: app/build/outputs/apk/untrusted/release/*.apk
retention-days: 30

- name: Upload Prod APK Artifact
if: steps.build-type.outputs.build_type != 'test'
uses: actions/upload-artifact@v4
with:
name: unsigned-prod-apk
path: app/build/outputs/apk/prod/release/*.apk
retention-days: 30

outputs:
build_type: ${{ steps.build-type.outputs.build_type }}
version_major: ${{ steps.version.outputs.VERSION_MAJOR }}
version_minor: ${{ steps.version.outputs.VERSION_MINOR }}
version_patch: ${{ steps.version.outputs.VERSION_PATCH }}
version_build_count: ${{ steps.version.outputs.VERSION_BUILD_COUNT }}
86 changes: 20 additions & 66 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
@@ -1,77 +1,31 @@
name: CI - Build (Unsigned)
# DEPRECATED: This workflow has been replaced by the new CI/CD architecture:
# - build.yml (unsigned builds for all environments)
# - sign-test.yml (signs untrusted PR builds with test key)
# - sign-release.yml (signs production builds with release key)
#
# This workflow is kept temporarily for backward compatibility and will be removed.
# See docs/VERSIONING.md for the new signing architecture documentation.

name: CI - Build (Unsigned) [DEPRECATED]

on:
pull_request:
branches: [master]
push:
branches: [master]
# Disabled - replaced by build.yml
workflow_dispatch: {}

permissions:
contents: read

jobs:
build:
name: Build Unsigned APK
name: Build Unsigned APK (DEPRECATED)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for version calculation

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
cache: gradle

- name: Calculate version
id: version
- name: Notice
run: |
# Get the latest v*.*.* tag
LATEST_TAG=$(git describe --tags --abbrev=0 --match "v*.*.*" 2>/dev/null || echo "v0.0.0")
echo "Latest tag: $LATEST_TAG"

# Parse version components
VERSION_REGEX="^v([0-9]+)\.([0-9]+)\.([0-9]+)$"
if [[ $LATEST_TAG =~ $VERSION_REGEX ]]; then
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
PATCH="${BASH_REMATCH[3]}"
else
MAJOR=0
MINOR=0
PATCH=0
fi

# Count commits since the last tag
BUILD_COUNT=$(git rev-list --count HEAD "^${LATEST_TAG}" 2>/dev/null || echo "0")

# For beta builds, increment patch by 1 so betas are HIGHER than previous stable
# Example: after v5.4.3, betas are v5.4.4-beta.X (not v5.4.3-beta.X)
if [[ "$BUILD_COUNT" -gt 0 ]]; then
PATCH=$((PATCH + 1))
fi

echo "VERSION_MAJOR=$MAJOR" >> $GITHUB_OUTPUT
echo "VERSION_MINOR=$MINOR" >> $GITHUB_OUTPUT
echo "VERSION_PATCH=$PATCH" >> $GITHUB_OUTPUT
echo "VERSION_BUILD_COUNT=$BUILD_COUNT" >> $GITHUB_OUTPUT
echo "Version: v${MAJOR}.${MINOR}.${PATCH}-beta.${BUILD_COUNT}"

- name: Build debug APK
run: ./gradlew --no-daemon :app:assembleDebug
env:
VERSION_MAJOR: ${{ steps.version.outputs.VERSION_MAJOR }}
VERSION_MINOR: ${{ steps.version.outputs.VERSION_MINOR }}
VERSION_PATCH: ${{ steps.version.outputs.VERSION_PATCH }}
VERSION_BUILD_COUNT: ${{ steps.version.outputs.VERSION_BUILD_COUNT }}
VERSION_STABLE: 'false'

- name: Upload debug APK
uses: actions/upload-artifact@v4
with:
name: app-debug
path: app/build/outputs/apk/debug/app-debug.apk
retention-days: 30
echo "This workflow is deprecated and has been replaced by:"
echo " - build.yml (unsigned builds)"
echo " - sign-test.yml (test signing)"
echo " - sign-release.yml (production signing)"
echo ""
echo "Please update your references to use the new workflows."
exit 1
4 changes: 2 additions & 2 deletions .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
cache: gradle

- name: Run unit tests
run: ./gradlew --no-daemon testDebugUnitTest
run: ./gradlew --no-daemon testProdDebugUnitTest

- name: Upload test reports
if: failure()
Expand All @@ -54,7 +54,7 @@ jobs:
cache: gradle

- name: Run lint
run: ./gradlew --no-daemon lint
run: ./gradlew --no-daemon lintProdDebug

- name: Upload lint reports
if: failure()
Expand Down
Loading
Loading