mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-02-07 06:12:56 -05:00
feat(release): Automate changelog, asset updates, and tagging (#4407)
This commit is contained in:
13
.github/release.yml
vendored
13
.github/release.yml
vendored
@@ -19,16 +19,3 @@ changelog:
|
||||
- repo
|
||||
- automation
|
||||
- release
|
||||
|
||||
- title: 👷Dependencies
|
||||
labels:
|
||||
- dependencies
|
||||
|
||||
- title: 🧱Repo
|
||||
labels:
|
||||
- repo
|
||||
|
||||
- title: 🤖Automated
|
||||
labels:
|
||||
- automation
|
||||
- release
|
||||
|
||||
162
.github/workflows/create-or-promote-release.yml
vendored
162
.github/workflows/create-or-promote-release.yml
vendored
@@ -35,6 +35,7 @@ jobs:
|
||||
release_name: ${{ steps.calculate_tags.outputs.release_name }}
|
||||
final_tag: ${{ steps.calculate_tags.outputs.final_tag }}
|
||||
from_channel: ${{ steps.calculate_tags.outputs.from_channel }}
|
||||
commit_sha: ${{ steps.get_sha.outputs.commit_sha }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
@@ -105,21 +106,154 @@ jobs:
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Create and push new tag
|
||||
if: ${{ !inputs.dry_run }}
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
- name: Determine previous tag
|
||||
if: ${{ !inputs.dry_run && inputs.channel == 'internal' }}
|
||||
id: previous_tag
|
||||
run: |
|
||||
FINAL_TAG="${{ steps.calculate_tags.outputs.final_tag }}"
|
||||
if [[ "${{ inputs.channel }}" == "internal" ]]; then
|
||||
# For internal, tag the current HEAD. tag_to_process and final_tag are the same.
|
||||
git tag $FINAL_TAG
|
||||
# Find the tag reachable from the parent of the current HEAD
|
||||
# Exclude tags with hyphens to skip pre-releases
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 --exclude "*-*" HEAD 2>/dev/null || echo "")
|
||||
echo "Found previous tag: $PREV_TAG"
|
||||
echo "PREV_TAG=$PREV_TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update External Assets (Firmware, Hardware, Protos)
|
||||
if: ${{ !inputs.dry_run && inputs.channel == 'internal' }}
|
||||
run: |
|
||||
# Update Submodules (Protobufs)
|
||||
echo "Updating core/proto submodule..."
|
||||
git submodule update --init --remote core/proto
|
||||
|
||||
# Update Firmware List
|
||||
firmware_file_path="app/src/main/assets/firmware_releases.json"
|
||||
temp_firmware_file="/tmp/new_firmware_releases.json"
|
||||
|
||||
echo "Fetching latest firmware releases..."
|
||||
curl -s --fail https://api.meshtastic.org/github/firmware/list > "$temp_firmware_file"
|
||||
|
||||
if ! jq empty "$temp_firmware_file" 2>/dev/null; then
|
||||
echo "::error::Firmware API returned invalid JSON data. Aborting."
|
||||
exit 1
|
||||
else
|
||||
# For promotions, create the new tag pointing to the same commit as the old tag.
|
||||
TAG_TO_PROCESS="${{ steps.calculate_tags.outputs.tag_to_process }}"
|
||||
git tag $FINAL_TAG $TAG_TO_PROCESS
|
||||
if [ ! -f "$firmware_file_path" ] || ! jq --sort-keys . "$temp_firmware_file" | diff -q - <(jq --sort-keys . "$firmware_file_path"); then
|
||||
echo "Changes detected in firmware list or local file missing. Updating $firmware_file_path."
|
||||
cp "$temp_firmware_file" "$firmware_file_path"
|
||||
else
|
||||
echo "No changes detected in firmware list."
|
||||
fi
|
||||
fi
|
||||
git push origin $FINAL_TAG
|
||||
|
||||
# Update Hardware List
|
||||
hardware_file_path="app/src/main/assets/device_hardware.json"
|
||||
temp_hardware_file="/tmp/new_device_hardware.json"
|
||||
|
||||
echo "Fetching latest device hardware data..."
|
||||
curl -s --fail https://api.meshtastic.org/resource/deviceHardware > "$temp_hardware_file"
|
||||
|
||||
if ! jq empty "$temp_hardware_file" 2>/dev/null; then
|
||||
echo "::error::Hardware API returned invalid JSON data. Aborting."
|
||||
exit 1
|
||||
else
|
||||
if [ ! -f "$hardware_file_path" ] || ! jq --sort-keys . "$temp_hardware_file" | diff -q - <(jq --sort-keys . "$hardware_file_path"); then
|
||||
echo "Changes detected in hardware list or local file missing. Updating $hardware_file_path."
|
||||
cp "$temp_hardware_file" "$hardware_file_path"
|
||||
else
|
||||
echo "No changes detected in hardware list."
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Sync with Crowdin
|
||||
if: ${{ !inputs.dry_run && inputs.channel == 'internal' }}
|
||||
uses: crowdin/github-action@v2
|
||||
with:
|
||||
base_url: 'https://meshtastic.crowdin.com/api/v2'
|
||||
config: 'crowdin.yml'
|
||||
crowdin_branch_name: 'main'
|
||||
upload_sources: true
|
||||
upload_sources_args: '--preserve-hierarchy'
|
||||
upload_translations: false
|
||||
download_translations: true
|
||||
download_translations_args: '--preserve-hierarchy'
|
||||
create_pull_request: false
|
||||
push_translations: false
|
||||
push_sources: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
||||
- name: Generate Changelog Content
|
||||
if: ${{ !inputs.dry_run && inputs.channel == 'internal' && steps.previous_tag.outputs.PREV_TAG != '' }}
|
||||
uses: mikepenz/release-changelog-builder-action@v6
|
||||
id: build_changelog
|
||||
with:
|
||||
configuration: .github/release.yml
|
||||
fromTag: ${{ steps.previous_tag.outputs.PREV_TAG }}
|
||||
toTag: HEAD
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Commit Release Assets (Changelog, Translations, Data, Config)
|
||||
if: ${{ !inputs.dry_run && inputs.channel == 'internal' }}
|
||||
env:
|
||||
CHANGELOG: ${{ steps.build_changelog.outputs.changelog }}
|
||||
FINAL_TAG: ${{ steps.calculate_tags.outputs.final_tag }}
|
||||
run: |
|
||||
# Calculate Version Code
|
||||
OFFSET=$(grep '^VERSION_CODE_OFFSET=' config.properties | cut -d'=' -f2)
|
||||
COMMIT_COUNT=$(git rev-list --count HEAD)
|
||||
# +1 because we are about to add a commit
|
||||
VERSION_CODE=$((COMMIT_COUNT + OFFSET + 1))
|
||||
|
||||
echo "Calculated Version Code: $VERSION_CODE"
|
||||
|
||||
# Update VERSION_NAME_BASE in config.properties
|
||||
sed -i "s/^VERSION_NAME_BASE=.*/VERSION_NAME_BASE=${{ inputs.base_version }}/" config.properties
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Add changelog if generated
|
||||
if [ ! -z "$CHANGELOG" ]; then
|
||||
FILE_PATH="fastlane/metadata/android/en-US/changelogs/${VERSION_CODE}.txt"
|
||||
echo "$CHANGELOG" > "$FILE_PATH"
|
||||
git add "$FILE_PATH"
|
||||
fi
|
||||
|
||||
# Add updated data files
|
||||
git add config.properties
|
||||
git add app/src/main/assets/firmware_releases.json || true
|
||||
git add app/src/main/assets/device_hardware.json || true
|
||||
git add core/proto || true
|
||||
|
||||
# Add updated translations (fastlane metadata and strings)
|
||||
git add fastlane/metadata/android || true
|
||||
git add "**/strings.xml" || true
|
||||
|
||||
# Only commit if there are changes
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "chore(release): prepare $FINAL_TAG [skip ci]
|
||||
|
||||
- Bump base version to ${{ inputs.base_version }}
|
||||
- Add changelog for version code $VERSION_CODE
|
||||
- Sync translations and assets"
|
||||
git push
|
||||
else
|
||||
echo "No changes to commit."
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Get Commit SHA to Tag
|
||||
id: get_sha
|
||||
run: |
|
||||
if [[ "${{ inputs.channel }}" == "internal" ]]; then
|
||||
# Internal build uses the latest commit (including any asset updates)
|
||||
SHA=$(git rev-parse HEAD)
|
||||
else
|
||||
# Promotions use the SHA of the tag we are promoting
|
||||
TAG_TO_PROCESS="${{ steps.calculate_tags.outputs.tag_to_process }}"
|
||||
SHA=$(git rev-parse $TAG_TO_PROCESS)
|
||||
fi
|
||||
echo "commit_sha=$SHA" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
|
||||
call-release-workflow:
|
||||
@@ -127,7 +261,8 @@ jobs:
|
||||
needs: determine-tags
|
||||
uses: ./.github/workflows/release.yml
|
||||
with:
|
||||
tag_name: ${{ needs.determine-tags.outputs.tag_to_process }}
|
||||
tag_name: ${{ needs.determine-tags.outputs.final_tag }}
|
||||
commit_sha: ${{ needs.determine-tags.outputs.commit_sha }}
|
||||
channel: ${{ inputs.channel }}
|
||||
base_version: ${{ inputs.base_version }}
|
||||
secrets: inherit
|
||||
@@ -140,6 +275,7 @@ jobs:
|
||||
tag_name: ${{ needs.determine-tags.outputs.tag_to_process }}
|
||||
release_name: ${{ needs.determine-tags.outputs.release_name }}
|
||||
final_tag: ${{ needs.determine-tags.outputs.final_tag }}
|
||||
commit_sha: ${{ needs.determine-tags.outputs.commit_sha }}
|
||||
channel: ${{ inputs.channel }}
|
||||
base_version: ${{ inputs.base_version }}
|
||||
from_channel: ${{ needs.determine-tags.outputs.from_channel }}
|
||||
|
||||
20
.github/workflows/docs.yml
vendored
20
.github/workflows/docs.yml
vendored
@@ -3,12 +3,25 @@
|
||||
name: Deploy Documentation
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Runs at 00:00 UTC every Sunday
|
||||
- cron: '0 0 * * 0'
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'The branch, tag or SHA to checkout'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
# Allow this workflow to be called from other workflows
|
||||
workflow_call:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'The branch, tag or SHA to checkout'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
@@ -32,6 +45,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: 'recursive'
|
||||
ref: ${{ inputs.ref || '' }}
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v5
|
||||
|
||||
63
.github/workflows/promote.yml
vendored
63
.github/workflows/promote.yml
vendored
@@ -19,6 +19,10 @@ on:
|
||||
description: 'The final tag for the release'
|
||||
required: true
|
||||
type: string
|
||||
commit_sha:
|
||||
description: 'The commit SHA to tag'
|
||||
required: false
|
||||
type: string
|
||||
channel:
|
||||
description: 'The channel to promote to'
|
||||
required: true
|
||||
@@ -46,6 +50,8 @@ on:
|
||||
required: true
|
||||
GRADLE_ENCRYPTION_KEY:
|
||||
required: true
|
||||
DISCORD_WEBHOOK_ANDROID:
|
||||
required: false
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ inputs.tag_name }}
|
||||
@@ -67,7 +73,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.tag_name }}
|
||||
ref: ${{ inputs.commit_sha || inputs.tag_name }}
|
||||
fetch-depth: 0
|
||||
submodules: 'recursive'
|
||||
|
||||
@@ -111,9 +117,16 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit_sha || inputs.tag_name }}
|
||||
fetch-depth: 0
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Push Git Tag on Success
|
||||
if: ${{ inputs.commit_sha != '' }}
|
||||
run: |
|
||||
git tag ${{ inputs.final_tag }} ${{ inputs.commit_sha }}
|
||||
git push origin ${{ inputs.final_tag }}
|
||||
|
||||
- name: Update GitHub Release with gh CLI
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
@@ -122,3 +135,51 @@ jobs:
|
||||
--tag ${{ inputs.final_tag }} \
|
||||
--title "${{ inputs.release_name }} (${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }})" \
|
||||
--prerelease=${{ inputs.channel != 'production' }}
|
||||
|
||||
- name: Notify Discord
|
||||
if: ${{ inputs.channel != 'internal' }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_ANDROID }}
|
||||
VERSION: ${{ inputs.final_tag }}
|
||||
CHANNEL: ${{ inputs.channel }}
|
||||
run: |
|
||||
if [[ -z "$DISCORD_WEBHOOK" ]]; then
|
||||
echo "No Discord webhook provided. Skipping notification."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Determine Track Name for Display
|
||||
if [ "$CHANNEL" == "closed" ]; then TRACK="Alpha (Closed)"; fi
|
||||
if [ "$CHANNEL" == "open" ]; then TRACK="Beta (Open)"; fi
|
||||
if [ "$CHANNEL" == "production" ]; then TRACK="Production"; fi
|
||||
|
||||
# Construct JSON Payload
|
||||
PAYLOAD=$(cat <<EOF
|
||||
{
|
||||
"content": null,
|
||||
"embeds": [
|
||||
{
|
||||
"title": "🚀 New Android Release: $VERSION",
|
||||
"description": "A new build has been promoted to the **$TRACK** track.",
|
||||
"color": 5763719,
|
||||
"fields": [
|
||||
{
|
||||
"name": "Track",
|
||||
"value": "$TRACK",
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Version",
|
||||
"value": "$VERSION",
|
||||
"inline": true
|
||||
}
|
||||
],
|
||||
"url": "https://github.com/meshtastic/Meshtastic-Android/releases/tag/$VERSION"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
curl -H "Content-Type: application/json" -d "$PAYLOAD" "$DISCORD_WEBHOOK"
|
||||
|
||||
|
||||
59
.github/workflows/release.yml
vendored
59
.github/workflows/release.yml
vendored
@@ -11,6 +11,10 @@ on:
|
||||
description: 'The tag that triggered the release'
|
||||
required: true
|
||||
type: string
|
||||
commit_sha:
|
||||
description: 'The commit SHA to build and tag'
|
||||
required: false
|
||||
type: string
|
||||
channel:
|
||||
description: 'The channel to create a release for or promote to'
|
||||
required: true
|
||||
@@ -52,12 +56,19 @@ permissions:
|
||||
attestations: write
|
||||
|
||||
jobs:
|
||||
run-lint:
|
||||
uses: ./.github/workflows/reusable-lint.yml
|
||||
with:
|
||||
ref: ${{ inputs.commit_sha || inputs.tag_name }}
|
||||
secrets: inherit
|
||||
|
||||
prepare-build-info:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
APP_VERSION_NAME: ${{ steps.get_version_name.outputs.APP_VERSION_NAME }}
|
||||
APP_VERSION_CODE: ${{ steps.calculate_version_code.outputs.versionCode }}
|
||||
env:
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
|
||||
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
|
||||
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
|
||||
@@ -65,7 +76,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.tag_name }}
|
||||
ref: ${{ inputs.commit_sha || inputs.tag_name }}
|
||||
fetch-depth: 0
|
||||
submodules: 'recursive'
|
||||
- name: Set up JDK 17
|
||||
@@ -102,9 +113,10 @@ jobs:
|
||||
|
||||
release-google:
|
||||
runs-on: ubuntu-latest
|
||||
needs: prepare-build-info
|
||||
needs: [prepare-build-info, run-lint]
|
||||
environment: Release
|
||||
env:
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
|
||||
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
|
||||
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
|
||||
@@ -112,7 +124,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.tag_name }}
|
||||
ref: ${{ inputs.commit_sha || inputs.tag_name }}
|
||||
fetch-depth: 0
|
||||
submodules: 'recursive'
|
||||
- name: Set up JDK 17
|
||||
@@ -148,6 +160,27 @@ jobs:
|
||||
echo "MAPS_API_KEY=$GOOGLE_MAPS_API_KEY" >> ./secrets.properties
|
||||
echo "$GOOGLE_PLAY_JSON_KEY" > ./fastlane/play-store-credentials.json
|
||||
|
||||
- name: Determine previous tag
|
||||
id: previous_tag
|
||||
run: |
|
||||
CURRENT_TAG="${{ inputs.tag_name }}"
|
||||
# Find the tag reachable from the parent of the current tag
|
||||
# Exclude tags with hyphens to skip pre-releases (e.g. -internal, -beta)
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 --exclude "*-*" "$CURRENT_TAG^" 2>/dev/null || echo "")
|
||||
echo "Found previous tag: $PREV_TAG"
|
||||
echo "PREV_TAG=$PREV_TAG" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate Changelog for Play Store
|
||||
if: steps.previous_tag.outputs.PREV_TAG != ''
|
||||
uses: mikepenz/release-changelog-builder-action@v6
|
||||
id: build_changelog
|
||||
with:
|
||||
configuration: .github/release.yml
|
||||
fromTag: ${{ steps.previous_tag.outputs.PREV_TAG }}
|
||||
toTag: ${{ inputs.tag_name }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
@@ -158,7 +191,8 @@ jobs:
|
||||
env:
|
||||
VERSION_NAME: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
|
||||
VERSION_CODE: ${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }}
|
||||
run: bundle exec fastlane internal
|
||||
CHANGELOG: ${{ steps.build_changelog.outputs.changelog }}
|
||||
run: bundle exec fastlane internal changelog:"$CHANGELOG"
|
||||
|
||||
- name: Upload Google AAB artifact
|
||||
if: always()
|
||||
@@ -186,9 +220,10 @@ jobs:
|
||||
|
||||
release-fdroid:
|
||||
runs-on: ubuntu-latest
|
||||
needs: prepare-build-info
|
||||
needs: [prepare-build-info, run-lint]
|
||||
environment: Release
|
||||
env:
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
|
||||
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
|
||||
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
|
||||
@@ -196,7 +231,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.tag_name }}
|
||||
ref: ${{ inputs.commit_sha || inputs.tag_name }}
|
||||
fetch-depth: 0
|
||||
submodules: 'recursive'
|
||||
- name: Set up JDK 17
|
||||
@@ -249,6 +284,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [prepare-build-info, release-google, release-fdroid]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit_sha || inputs.tag_name }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Push Git Tag on Success
|
||||
if: ${{ inputs.commit_sha != '' }}
|
||||
run: |
|
||||
git tag ${{ inputs.tag_name }} ${{ inputs.commit_sha }}
|
||||
git push origin ${{ inputs.tag_name }}
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
|
||||
3
.github/workflows/reusable-android-test.yml
vendored
3
.github/workflows/reusable-android-test.yml
vendored
@@ -62,6 +62,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
env:
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
|
||||
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
|
||||
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
|
||||
@@ -137,7 +138,7 @@ jobs:
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
script: ./gradlew ${{ steps.test-tasks.outputs.tasks }} koverXmlReport -Pandroid.testInstrumentationRunnerArguments.numShards=${{ inputs.num_shards }} -Pandroid.testInstrumentationRunnerArguments.shardIndex=${{ matrix.shard }} --continue --scan && ( killall -INT crashpad_handler || true )
|
||||
script: ./gradlew ${{ steps.test-tasks.outputs.tasks }} koverXmlReport -Pci=true -Pandroid.testInstrumentationRunnerArguments.numShards=${{ inputs.num_shards }} -Pandroid.testInstrumentationRunnerArguments.shardIndex=${{ matrix.shard }} --continue --scan && ( killall -INT crashpad_handler || true )
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
9
.github/workflows/reusable-lint.yml
vendored
9
.github/workflows/reusable-lint.yml
vendored
@@ -2,6 +2,11 @@ name: Reusable Lint and Format Check
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'The branch, tag or SHA to checkout'
|
||||
required: false
|
||||
type: string
|
||||
secrets:
|
||||
GRADLE_ENCRYPTION_KEY:
|
||||
required: false
|
||||
@@ -17,6 +22,7 @@ jobs:
|
||||
runs-on: ubuntu-latest # Lint is fast, doesn't need large runner
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
|
||||
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
|
||||
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
|
||||
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
|
||||
@@ -25,6 +31,7 @@ jobs:
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ inputs.ref || '' }}
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v5
|
||||
@@ -44,4 +51,4 @@ jobs:
|
||||
add-job-summary: always
|
||||
|
||||
- name: Run Spotless and Detekt
|
||||
run: ./gradlew spotlessCheck detekt --scan
|
||||
run: ./gradlew spotlessCheck detekt -Pci=true --scan
|
||||
|
||||
@@ -11,9 +11,11 @@ The entire release process is managed by a single, manually-triggered GitHub Act
|
||||
1. `version`: The base version number you are releasing (e.g., `2.4.0`).
|
||||
2. `channel`: The release channel you are targeting (`internal`, `closed`, `open`, or `production`).
|
||||
- **Automation:** The workflow handles everything automatically:
|
||||
- Calculates the correct Git tag based on the channel (e.g., `v2.4.0-internal.1` or `v2.4.0`).
|
||||
- Pushes the new tag to the repository.
|
||||
- Calls a reusable workflow that builds the app, deploys it to the correct Google Play track, and attaches the artifacts (`.aab`/`.apk`) to a GitHub Release.
|
||||
- **Syncs Assets:** Fetches the latest firmware/hardware lists, protobuf definitions, and translations (Crowdin).
|
||||
- **Generates Changelog:** Creates a clean changelog from commits since the last production release and commits it to the repo.
|
||||
- **Updates Config:** Automatically bumps the `VERSION_NAME_BASE` in `config.properties`.
|
||||
- **Verifies & Tags:** Runs lint checks, builds the app, and *only* tags the release if successful.
|
||||
- **Deploys:** Uploads the build to the correct Google Play track and attaches artifacts (`.aab`/`.apk`) to a GitHub Release.
|
||||
- **Changelog:** Release notes are auto-generated from PR labels. Ensure PRs are labeled correctly to maintain an accurate changelog.
|
||||
|
||||
## Release Steps
|
||||
@@ -27,7 +29,11 @@ The entire release process is managed by a single, manually-triggered GitHub Act
|
||||
5. Select the `internal` channel.
|
||||
6. Click **"Run workflow"**.
|
||||
|
||||
The workflow will create an incremental internal tag (e.g., `v2.4.0-internal.1`) and publish a **draft** pre-release on GitHub.
|
||||
The workflow will:
|
||||
1. **Create a new commit** on the current branch containing updated assets, translations, and the new changelog.
|
||||
2. **Tag** that commit with an incremental internal tag (e.g., `v2.4.0-internal.1`).
|
||||
3. **Build & Deploy** the verified artifact to the Play Store Internal track.
|
||||
4. Publish a **draft** pre-release on GitHub.
|
||||
|
||||
### 2. Promote to the Next Channel
|
||||
|
||||
|
||||
@@ -17,17 +17,22 @@ default_platform(:android)
|
||||
|
||||
platform :android do
|
||||
desc "Deploy a new version to the internal track on Google Play"
|
||||
lane :internal do
|
||||
lane :internal do |options|
|
||||
aab_path = build_google_release
|
||||
|
||||
changelog = options[:changelog]
|
||||
skip_meta = changelog.to_s.empty?
|
||||
|
||||
upload_to_play_store(
|
||||
track: 'internal',
|
||||
aab: aab_path,
|
||||
release_status: 'completed',
|
||||
skip_upload_apk: true,
|
||||
skip_upload_metadata: true,
|
||||
skip_upload_changelogs: true,
|
||||
skip_upload_metadata: skip_meta,
|
||||
skip_upload_changelogs: skip_meta,
|
||||
skip_upload_images: true,
|
||||
skip_upload_screenshots: true,
|
||||
release_notes: skip_meta ? nil : { 'default' => changelog, 'en-US' => changelog }
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user