feat(ci): migrate to fastlane for release management (#3038)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
(cherry picked from commit 5cfa44cb64
)
pull/3042/head
|
@ -55,7 +55,7 @@ jobs:
|
||||||
# This will overflow Integer.MAX_VALUE in the year 6052, hopefully we'll have moved on by then.
|
# This will overflow Integer.MAX_VALUE in the year 6052, hopefully we'll have moved on by then.
|
||||||
run: echo "versionCode=$(( $(date +%s) / 60 ))" >> $GITHUB_OUTPUT
|
run: echo "versionCode=$(( $(date +%s) / 60 ))" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
build-fdroid:
|
release-google:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: prepare-build-info
|
needs: prepare-build-info
|
||||||
steps:
|
steps:
|
||||||
|
@ -79,54 +79,7 @@ jobs:
|
||||||
build-scan-terms-of-use-url: 'https://gradle.com/terms-of-service'
|
build-scan-terms-of-use-url: 'https://gradle.com/terms-of-service'
|
||||||
build-scan-terms-of-use-agree: 'yes'
|
build-scan-terms-of-use-agree: 'yes'
|
||||||
|
|
||||||
- name: Load Fdroid secrets
|
- name: Load secrets
|
||||||
run: |
|
|
||||||
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME
|
|
||||||
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
|
|
||||||
env:
|
|
||||||
KEYSTORE: ${{ secrets.KEYSTORE }}
|
|
||||||
KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }}
|
|
||||||
KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}
|
|
||||||
|
|
||||||
- name: Build F-Droid Release APK
|
|
||||||
run: |
|
|
||||||
./gradlew :app:assembleFdroidRelease --parallel --continue --scan
|
|
||||||
env:
|
|
||||||
VERSION_NAME: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
|
|
||||||
VERSION_CODE: ${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }}
|
|
||||||
|
|
||||||
- name: Upload F-Droid APK artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: fdroid-apk
|
|
||||||
path: app/build/outputs/apk/fdroid/release/app-fdroid-release.apk
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
build-google:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: prepare-build-info
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v5
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
submodules: 'recursive'
|
|
||||||
|
|
||||||
- name: Set up JDK 21
|
|
||||||
uses: actions/setup-java@v5
|
|
||||||
with:
|
|
||||||
java-version: '21'
|
|
||||||
distribution: 'jetbrains'
|
|
||||||
|
|
||||||
- name: Setup Gradle
|
|
||||||
uses: gradle/actions/setup-gradle@v4
|
|
||||||
with:
|
|
||||||
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
|
||||||
build-scan-publish: true
|
|
||||||
build-scan-terms-of-use-url: 'https://gradle.com/terms-of-service'
|
|
||||||
build-scan-terms-of-use-agree: 'yes'
|
|
||||||
|
|
||||||
- name: Load Google secrets
|
|
||||||
env:
|
env:
|
||||||
GSERVICES: ${{ secrets.GSERVICES }}
|
GSERVICES: ${{ secrets.GSERVICES }}
|
||||||
KEYSTORE: ${{ secrets.KEYSTORE }}
|
KEYSTORE: ${{ secrets.KEYSTORE }}
|
||||||
|
@ -135,6 +88,7 @@ jobs:
|
||||||
DATADOG_APPLICATION_ID: ${{ secrets.DATADOG_APPLICATION_ID }}
|
DATADOG_APPLICATION_ID: ${{ secrets.DATADOG_APPLICATION_ID }}
|
||||||
DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }}
|
DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }}
|
||||||
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
|
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
|
||||||
|
GOOGLE_PLAY_JSON_KEY: ${{ secrets.GOOGLE_PLAY_JSON_KEY }}
|
||||||
run: |
|
run: |
|
||||||
rm -f ./app/google-services.json # Ensure clean state
|
rm -f ./app/google-services.json # Ensure clean state
|
||||||
echo $GSERVICES > ./app/google-services.json
|
echo $GSERVICES > ./app/google-services.json
|
||||||
|
@ -143,13 +97,33 @@ jobs:
|
||||||
echo "datadogApplicationId=$DATADOG_APPLICATION_ID" >> ./secrets.properties
|
echo "datadogApplicationId=$DATADOG_APPLICATION_ID" >> ./secrets.properties
|
||||||
echo "datadogClientToken=$DATADOG_CLIENT_TOKEN" >> ./secrets.properties
|
echo "datadogClientToken=$DATADOG_CLIENT_TOKEN" >> ./secrets.properties
|
||||||
echo "MAPS_API_KEY=$GOOGLE_MAPS_API_KEY" >> ./secrets.properties
|
echo "MAPS_API_KEY=$GOOGLE_MAPS_API_KEY" >> ./secrets.properties
|
||||||
|
echo "$GOOGLE_PLAY_JSON_KEY" > ./fastlane/play-store-credentials.json
|
||||||
|
|
||||||
- name: Build Google Release Artifacts (AAB and APK)
|
- name: Setup Fastlane
|
||||||
|
uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: '3.2'
|
||||||
|
bundler-cache: true
|
||||||
|
|
||||||
|
- name: Determine Fastlane Lane
|
||||||
|
id: fastlane_lane
|
||||||
run: |
|
run: |
|
||||||
./gradlew :app:bundleGoogleRelease :app:assembleGoogleRelease --parallel --continue --scan
|
TAG_NAME="${{ github.ref_name }}"
|
||||||
|
if [[ "$TAG_NAME" == *"-internal"* ]]; then
|
||||||
|
echo "lane=internal" >> $GITHUB_OUTPUT
|
||||||
|
elif [[ "$TAG_NAME" == *"-closed"* ]]; then
|
||||||
|
echo "lane=closed" >> $GITHUB_OUTPUT
|
||||||
|
elif [[ "$TAG_NAME" == *"-open"* ]]; then
|
||||||
|
echo "lane=open" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "lane=production" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build and Deploy Google Play Tracks with Fastlane
|
||||||
env:
|
env:
|
||||||
VERSION_NAME: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
|
VERSION_NAME: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
|
||||||
VERSION_CODE: ${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }}
|
VERSION_CODE: ${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }}
|
||||||
|
run: bundle exec fastlane ${{ steps.fastlane_lane.outputs.lane }}
|
||||||
|
|
||||||
- name: Upload Google AAB artifact
|
- name: Upload Google AAB artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
@ -165,21 +139,9 @@ jobs:
|
||||||
path: app/build/outputs/apk/google/release/app-google-release.apk
|
path: app/build/outputs/apk/google/release/app-google-release.apk
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
- name: Upload Mapping File
|
release-fdroid:
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: mapping
|
|
||||||
path: app/build/outputs/mapping/googleRelease/mapping.txt
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
publish-release:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [prepare-build-info, build-fdroid, build-google]
|
needs: prepare-build-info
|
||||||
outputs:
|
|
||||||
RELEASE_UPLOAD_URL: ${{ steps.create_gh_release.outputs.upload_url }}
|
|
||||||
CHANGELOG: ${{ steps.generate_changelog.outputs.changelog }}
|
|
||||||
APP_VERSION_NAME: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
|
|
||||||
APP_VERSION_CODE: ${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
@ -187,34 +149,69 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
|
||||||
- name: Download F-Droid APK
|
- name: Set up JDK 21
|
||||||
uses: actions/download-artifact@v5
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
java-version: '21'
|
||||||
|
distribution: 'jetbrains'
|
||||||
|
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@v4
|
||||||
|
with:
|
||||||
|
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
|
||||||
|
build-scan-publish: true
|
||||||
|
build-scan-terms-of-use-url: 'https://gradle.com/terms-of-service'
|
||||||
|
build-scan-terms-of-use-agree: 'yes'
|
||||||
|
|
||||||
|
- name: Load secrets
|
||||||
|
env:
|
||||||
|
KEYSTORE: ${{ secrets.KEYSTORE }}
|
||||||
|
KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }}
|
||||||
|
KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}
|
||||||
|
run: |
|
||||||
|
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME
|
||||||
|
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
|
||||||
|
|
||||||
|
- name: Setup Fastlane
|
||||||
|
uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: '3.2'
|
||||||
|
bundler-cache: true
|
||||||
|
|
||||||
|
- name: Build F-Droid with Fastlane
|
||||||
|
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 fdroid_build
|
||||||
|
|
||||||
|
- name: Upload F-Droid APK artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: fdroid-apk
|
name: fdroid-apk
|
||||||
path: ./build-artifacts/fdroid
|
path: app/build/outputs/apk/fdroid/release/app-fdroid-release.apk
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
finalize-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [release-google, release-fdroid]
|
||||||
|
steps:
|
||||||
- name: Download Google AAB
|
- name: Download Google AAB
|
||||||
uses: actions/download-artifact@v5
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: google-aab
|
name: google-aab
|
||||||
path: ./build-artifacts/google/bundle
|
path: ./google/bundle
|
||||||
|
|
||||||
- name: Download Google APK
|
- name: Download Google APK
|
||||||
uses: actions/download-artifact@v5
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: google-apk
|
name: google-apk
|
||||||
path: ./build-artifacts/google/apk
|
path: ./google/apk
|
||||||
|
|
||||||
- name: Download Mapping File
|
- name: Download F-Droid APK
|
||||||
uses: actions/download-artifact@v5
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: mapping
|
name: fdroid-apk
|
||||||
path: ./build-artifacts/google/mapping
|
path: ./fdroid
|
||||||
|
|
||||||
- name: Create version_info.txt
|
|
||||||
run: |
|
|
||||||
echo "versionNameBase=${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}" > ./version_info.txt
|
|
||||||
echo "versionCode=${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }}" >> ./version_info.txt
|
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
id: create_gh_release
|
id: create_gh_release
|
||||||
|
@ -224,56 +221,10 @@ jobs:
|
||||||
name: Release ${{ github.ref_name }}
|
name: Release ${{ github.ref_name }}
|
||||||
generate_release_notes: true
|
generate_release_notes: true
|
||||||
files: |
|
files: |
|
||||||
./build-artifacts/google/bundle/app-google-release.aab
|
./google/bundle/app-google-release.aab
|
||||||
./build-artifacts/google/apk/app-google-release.apk
|
./google/apk/app-google-release.apk
|
||||||
./build-artifacts/fdroid/app-fdroid-release.apk
|
./fdroid/app-fdroid-release.apk
|
||||||
./version_info.txt
|
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: ${{ contains(github.ref_name, '-internal') || contains(github.ref_name, '-closed') || contains(github.ref_name, '-open') }}
|
prerelease: ${{ contains(github.ref_name, '-internal') || contains(github.ref_name, '-closed') || contains(github.ref_name, '-open') }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Create Play Store whatsnew File
|
|
||||||
run: |
|
|
||||||
mkdir -p whatsnew
|
|
||||||
echo "For detailed release notes, please visit: ${{ steps.create_gh_release.outputs.url }}" > whatsnew/whatsnew-en-US
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
# Attest the build artifacts for supply chain security.
|
|
||||||
# See: https://github.com/meshtastic/Meshtastic-Android/attestations
|
|
||||||
- name: Attest Build Provenance
|
|
||||||
uses: actions/attest-build-provenance@v3
|
|
||||||
with:
|
|
||||||
subject-path: |
|
|
||||||
./build-artifacts/google/bundle/app-google-release.aab
|
|
||||||
./build-artifacts/google/apk/app-google-release.apk
|
|
||||||
./build-artifacts/fdroid/app-fdroid-release.apk
|
|
||||||
|
|
||||||
- name: Determine Play Store Track
|
|
||||||
id: play_track
|
|
||||||
run: |
|
|
||||||
TAG_NAME="${{ github.ref_name }}"
|
|
||||||
if [[ "$TAG_NAME" == *"-internal"* ]]; then
|
|
||||||
echo "track=internal" >> $GITHUB_OUTPUT
|
|
||||||
elif [[ "$TAG_NAME" == *"-closed"* ]]; then
|
|
||||||
echo "track=NewAlpha" >> $GITHUB_OUTPUT
|
|
||||||
elif [[ "$TAG_NAME" == *"-open"* ]]; then
|
|
||||||
echo "track=beta" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "track=production" >> $GITHUB_OUTPUT
|
|
||||||
echo "user_fraction=0.1" >> $GITHUB_OUTPUT
|
|
||||||
echo "status=inProgress" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Upload to Google Play
|
|
||||||
if: success() && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
|
||||||
uses: r0adkll/upload-google-play@v1.1.3
|
|
||||||
with:
|
|
||||||
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_JSON_KEY }}
|
|
||||||
packageName: com.geeksville.mesh
|
|
||||||
releaseFiles: ./build-artifacts/google/bundle/app-google-release.aab
|
|
||||||
track: ${{ steps.play_track.outputs.track }}
|
|
||||||
status: ${{ steps.play_track.outputs.status || (steps.play_track.outputs.track == 'internal' && 'completed' || 'draft') }}
|
|
||||||
userFraction: ${{ steps.play_track.outputs.userFraction }}
|
|
||||||
whatsNewDirectory: ./whatsnew/
|
|
||||||
mappingFile: ./build-artifacts/google/mapping/mapping.txt
|
|
||||||
|
|
|
@ -32,3 +32,5 @@ keystore.properties
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
/secrets.properties
|
/secrets.properties
|
||||||
|
/fastlane/play-store-credentials.json
|
||||||
|
/fastlane/report.xml
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
3.2
|
|
@ -0,0 +1,3 @@
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "fastlane"
|
|
@ -0,0 +1,229 @@
|
||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
CFPropertyList (3.0.7)
|
||||||
|
base64
|
||||||
|
nkf
|
||||||
|
rexml
|
||||||
|
addressable (2.8.7)
|
||||||
|
public_suffix (>= 2.0.2, < 7.0)
|
||||||
|
artifactory (3.0.17)
|
||||||
|
atomos (0.1.3)
|
||||||
|
aws-eventstream (1.4.0)
|
||||||
|
aws-partitions (1.1157.0)
|
||||||
|
aws-sdk-core (3.232.0)
|
||||||
|
aws-eventstream (~> 1, >= 1.3.0)
|
||||||
|
aws-partitions (~> 1, >= 1.992.0)
|
||||||
|
aws-sigv4 (~> 1.9)
|
||||||
|
base64
|
||||||
|
bigdecimal
|
||||||
|
jmespath (~> 1, >= 1.6.1)
|
||||||
|
logger
|
||||||
|
aws-sdk-kms (1.112.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.231.0)
|
||||||
|
aws-sigv4 (~> 1.5)
|
||||||
|
aws-sdk-s3 (1.199.0)
|
||||||
|
aws-sdk-core (~> 3, >= 3.231.0)
|
||||||
|
aws-sdk-kms (~> 1)
|
||||||
|
aws-sigv4 (~> 1.5)
|
||||||
|
aws-sigv4 (1.12.1)
|
||||||
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
|
babosa (1.0.4)
|
||||||
|
base64 (0.3.0)
|
||||||
|
bigdecimal (3.2.3)
|
||||||
|
claide (1.1.0)
|
||||||
|
colored (1.2)
|
||||||
|
colored2 (3.1.2)
|
||||||
|
commander (4.6.0)
|
||||||
|
highline (~> 2.0.0)
|
||||||
|
declarative (0.0.20)
|
||||||
|
digest-crc (0.7.0)
|
||||||
|
rake (>= 12.0.0, < 14.0.0)
|
||||||
|
domain_name (0.6.20240107)
|
||||||
|
dotenv (2.8.1)
|
||||||
|
emoji_regex (3.2.3)
|
||||||
|
excon (0.112.0)
|
||||||
|
faraday (1.10.4)
|
||||||
|
faraday-em_http (~> 1.0)
|
||||||
|
faraday-em_synchrony (~> 1.0)
|
||||||
|
faraday-excon (~> 1.1)
|
||||||
|
faraday-httpclient (~> 1.0)
|
||||||
|
faraday-multipart (~> 1.0)
|
||||||
|
faraday-net_http (~> 1.0)
|
||||||
|
faraday-net_http_persistent (~> 1.0)
|
||||||
|
faraday-patron (~> 1.0)
|
||||||
|
faraday-rack (~> 1.0)
|
||||||
|
faraday-retry (~> 1.0)
|
||||||
|
ruby2_keywords (>= 0.0.4)
|
||||||
|
faraday-cookie_jar (0.0.7)
|
||||||
|
faraday (>= 0.8.0)
|
||||||
|
http-cookie (~> 1.0.0)
|
||||||
|
faraday-em_http (1.0.0)
|
||||||
|
faraday-em_synchrony (1.0.1)
|
||||||
|
faraday-excon (1.1.0)
|
||||||
|
faraday-httpclient (1.0.1)
|
||||||
|
faraday-multipart (1.1.1)
|
||||||
|
multipart-post (~> 2.0)
|
||||||
|
faraday-net_http (1.0.2)
|
||||||
|
faraday-net_http_persistent (1.2.0)
|
||||||
|
faraday-patron (1.0.0)
|
||||||
|
faraday-rack (1.0.0)
|
||||||
|
faraday-retry (1.0.3)
|
||||||
|
faraday_middleware (1.2.1)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
fastimage (2.4.0)
|
||||||
|
fastlane (2.228.0)
|
||||||
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
|
addressable (>= 2.8, < 3.0.0)
|
||||||
|
artifactory (~> 3.0)
|
||||||
|
aws-sdk-s3 (~> 1.0)
|
||||||
|
babosa (>= 1.0.3, < 2.0.0)
|
||||||
|
bundler (>= 1.12.0, < 3.0.0)
|
||||||
|
colored (~> 1.2)
|
||||||
|
commander (~> 4.6)
|
||||||
|
dotenv (>= 2.1.1, < 3.0.0)
|
||||||
|
emoji_regex (>= 0.1, < 4.0)
|
||||||
|
excon (>= 0.71.0, < 1.0.0)
|
||||||
|
faraday (~> 1.0)
|
||||||
|
faraday-cookie_jar (~> 0.0.6)
|
||||||
|
faraday_middleware (~> 1.0)
|
||||||
|
fastimage (>= 2.1.0, < 3.0.0)
|
||||||
|
fastlane-sirp (>= 1.0.0)
|
||||||
|
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||||
|
google-apis-androidpublisher_v3 (~> 0.3)
|
||||||
|
google-apis-playcustomapp_v1 (~> 0.1)
|
||||||
|
google-cloud-env (>= 1.6.0, < 2.0.0)
|
||||||
|
google-cloud-storage (~> 1.31)
|
||||||
|
highline (~> 2.0)
|
||||||
|
http-cookie (~> 1.0.5)
|
||||||
|
json (< 3.0.0)
|
||||||
|
jwt (>= 2.1.0, < 3)
|
||||||
|
mini_magick (>= 4.9.4, < 5.0.0)
|
||||||
|
multipart-post (>= 2.0.0, < 3.0.0)
|
||||||
|
naturally (~> 2.2)
|
||||||
|
optparse (>= 0.1.1, < 1.0.0)
|
||||||
|
plist (>= 3.1.0, < 4.0.0)
|
||||||
|
rubyzip (>= 2.0.0, < 3.0.0)
|
||||||
|
security (= 0.1.5)
|
||||||
|
simctl (~> 1.6.3)
|
||||||
|
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||||
|
terminal-table (~> 3)
|
||||||
|
tty-screen (>= 0.6.3, < 1.0.0)
|
||||||
|
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||||
|
word_wrap (~> 1.0.0)
|
||||||
|
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||||
|
xcpretty (~> 0.4.1)
|
||||||
|
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
|
||||||
|
fastlane-sirp (1.0.0)
|
||||||
|
sysrandom (~> 1.0)
|
||||||
|
gh_inspector (1.1.3)
|
||||||
|
google-apis-androidpublisher_v3 (0.54.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-core (0.11.3)
|
||||||
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
httpclient (>= 2.8.1, < 3.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
representable (~> 3.0)
|
||||||
|
retriable (>= 2.0, < 4.a)
|
||||||
|
rexml
|
||||||
|
google-apis-iamcredentials_v1 (0.17.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-playcustomapp_v1 (0.13.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-apis-storage_v1 (0.31.0)
|
||||||
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
|
google-cloud-core (1.8.0)
|
||||||
|
google-cloud-env (>= 1.0, < 3.a)
|
||||||
|
google-cloud-errors (~> 1.0)
|
||||||
|
google-cloud-env (1.6.0)
|
||||||
|
faraday (>= 0.17.3, < 3.0)
|
||||||
|
google-cloud-errors (1.5.0)
|
||||||
|
google-cloud-storage (1.47.0)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
digest-crc (~> 0.4)
|
||||||
|
google-apis-iamcredentials_v1 (~> 0.1)
|
||||||
|
google-apis-storage_v1 (~> 0.31.0)
|
||||||
|
google-cloud-core (~> 1.6)
|
||||||
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
|
mini_mime (~> 1.0)
|
||||||
|
googleauth (1.8.1)
|
||||||
|
faraday (>= 0.17.3, < 3.a)
|
||||||
|
jwt (>= 1.4, < 3.0)
|
||||||
|
multi_json (~> 1.11)
|
||||||
|
os (>= 0.9, < 2.0)
|
||||||
|
signet (>= 0.16, < 2.a)
|
||||||
|
highline (2.0.3)
|
||||||
|
http-cookie (1.0.8)
|
||||||
|
domain_name (~> 0.5)
|
||||||
|
httpclient (2.9.0)
|
||||||
|
mutex_m
|
||||||
|
jmespath (1.6.2)
|
||||||
|
json (2.13.2)
|
||||||
|
jwt (2.10.2)
|
||||||
|
base64
|
||||||
|
logger (1.7.0)
|
||||||
|
mini_magick (4.13.2)
|
||||||
|
mini_mime (1.1.5)
|
||||||
|
multi_json (1.17.0)
|
||||||
|
multipart-post (2.4.1)
|
||||||
|
mutex_m (0.3.0)
|
||||||
|
nanaimo (0.4.0)
|
||||||
|
naturally (2.3.0)
|
||||||
|
nkf (0.2.0)
|
||||||
|
optparse (0.6.0)
|
||||||
|
os (1.1.4)
|
||||||
|
plist (3.7.2)
|
||||||
|
public_suffix (6.0.2)
|
||||||
|
rake (13.3.0)
|
||||||
|
representable (3.2.0)
|
||||||
|
declarative (< 0.1.0)
|
||||||
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
|
uber (< 0.2.0)
|
||||||
|
retriable (3.1.2)
|
||||||
|
rexml (3.4.3)
|
||||||
|
rouge (3.28.0)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
|
rubyzip (2.4.1)
|
||||||
|
security (0.1.5)
|
||||||
|
signet (0.21.0)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
faraday (>= 0.17.5, < 3.a)
|
||||||
|
jwt (>= 1.5, < 4.0)
|
||||||
|
multi_json (~> 1.10)
|
||||||
|
simctl (1.6.10)
|
||||||
|
CFPropertyList
|
||||||
|
naturally
|
||||||
|
sysrandom (1.0.5)
|
||||||
|
terminal-notifier (2.0.0)
|
||||||
|
terminal-table (3.0.2)
|
||||||
|
unicode-display_width (>= 1.1.1, < 3)
|
||||||
|
trailblazer-option (0.1.2)
|
||||||
|
tty-cursor (0.7.1)
|
||||||
|
tty-screen (0.8.2)
|
||||||
|
tty-spinner (0.9.3)
|
||||||
|
tty-cursor (~> 0.7)
|
||||||
|
uber (0.1.0)
|
||||||
|
unicode-display_width (2.6.0)
|
||||||
|
word_wrap (1.0.0)
|
||||||
|
xcodeproj (1.27.0)
|
||||||
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
|
atomos (~> 0.1.3)
|
||||||
|
claide (>= 1.0.2, < 2.0)
|
||||||
|
colored2 (~> 3.1)
|
||||||
|
nanaimo (~> 0.4.0)
|
||||||
|
rexml (>= 3.3.6, < 4.0)
|
||||||
|
xcpretty (0.4.1)
|
||||||
|
rouge (~> 3.28.0)
|
||||||
|
xcpretty-travis-formatter (1.0.1)
|
||||||
|
xcpretty (~> 0.2, >= 0.0.7)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
arm64-darwin-24
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
fastlane
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.6.9
|
|
@ -1,92 +1,131 @@
|
||||||
# Meshtastic-Android Release Process
|
# Meshtastic-Android Release Process
|
||||||
|
|
||||||
This document outlines the steps for releasing a new version of the Meshtastic-Android application. Adhering to this process ensures consistency and helps manage the release lifecycle, leveraging automation via the `release.yml` GitHub Action.
|
This document outlines the steps for releasing a new version of the Meshtastic-Android application. The process is heavily automated using GitHub Actions and Fastlane, triggered by pushing a Git tag from a `release/*` branch.
|
||||||
|
|
||||||
**Note on Automation:** The `release.yml` GitHub Action is primarily triggered by **pushing a Git tag** matching the pattern `v*` (e.g., `v1.2.3`, `v1.2.3-open.1`). It can also be manually triggered via `workflow_dispatch` from the GitHub Actions UI.
|
## High-Level Overview
|
||||||
|
|
||||||
The workflow uses a simple and robust **"upload-only"** model. It automatically:
|
The automation is designed to be safe, repeatable, and efficient. When a new tag matching the `v*` pattern is pushed from a release branch, the `release.yml` GitHub Action workflow will:
|
||||||
* Determines a `versionName` from the Git tag.
|
|
||||||
* Generates a unique, always-increasing `versionCode` based on the number of minutes since the Unix epoch. This prevents `versionCode` conflicts and will not overflow until the year 6052.
|
|
||||||
* Builds fresh F-Droid (APK) and Google (AAB, APK) artifacts for every run.
|
|
||||||
* Creates a **draft GitHub Release** and attaches the artifacts.
|
|
||||||
* Attests build provenance for the artifacts.
|
|
||||||
* **Uploads** the newly built AAB directly to the appropriate track in the Google Play Console based on the tag.
|
|
||||||
|
|
||||||
There is no promotion of builds between tracks; every release is a new, independent upload. Finalizing and publishing the GitHub Release and the Google Play Store submission remain **manual steps**.
|
1. **Determine Versioning:** A `versionName` is derived from the Git tag, and a unique, always-increasing `versionCode` is generated from the current timestamp.
|
||||||
|
2. **Build in Parallel:** Two jobs run simultaneously to build the `google` and `fdroid` flavors of the app.
|
||||||
|
3. **Deploy to Google Play:** The `google` build job uses Fastlane to automatically upload the Android App Bundle (AAB) to the correct track on the Google Play Console, based on the tag name.
|
||||||
|
4. **Create a Draft GitHub Release:** After both builds are complete, a final job gathers the artifacts (AAB, Google APK, and F-Droid APK) and creates a single, consolidated **draft** release on GitHub.
|
||||||
|
|
||||||
## Prerequisites
|
Finalizing and publishing the release on both GitHub and the Google Play Console are the only **manual steps**.
|
||||||
|
|
||||||
Before initiating the release process, ensure the following are completed:
|
## Versioning and Tagging Strategy
|
||||||
|
|
||||||
1. **Main Branch Stability:** The `main` branch (or your chosen release branch) must be stable, with all features and bug fixes intended for the release merged and thoroughly tested.
|
The entire process is driven by your Git tagging strategy. Tags **must** start with `v` and should follow Semantic Versioning. Use the correct suffix for the desired release track:
|
||||||
2. **Automated Testing:** All automated tests must be passing.
|
|
||||||
3. **Versioning and Tagging Strategy:**
|
|
||||||
* Tags **must** start with `v` and follow Semantic Versioning (e.g., `vX.X.X`).
|
|
||||||
* Use the correct suffixes for the desired release track:
|
|
||||||
* **Internal/QA:** `vX.X.X-internal.Y`
|
|
||||||
* **Closed Alpha:** `vX.X.X-closed.Y`
|
|
||||||
* **Open Alpha/Beta:** `vX.X.X-open.Y`
|
|
||||||
* **Production:** `vX.X.X` (no suffix)
|
|
||||||
* **Recommendation:** Before tagging, update `VERSION_NAME_BASE` in `buildSrc/src/main/kotlin/Configs.kt` to match the `X.X.X` part of your tag. This ensures consistency for local development builds.
|
|
||||||
|
|
||||||
## Core Release Workflow: Triggering via Tag Push
|
* **Internal Track:** `vX.X.X-internal.Y` (e.g., `v2.3.5-internal.1`)
|
||||||
|
* **Closed Track:** `vX.X.X-closed.Y` (e.g., `v2.3.5-closed.1`)
|
||||||
|
* **Open Track:** `vX.X.X-open.Y` (e.g., `v2.3.5-open.1`)
|
||||||
|
* **Production Track:** `vX.X.X` (e.g., `v2.3.5`)
|
||||||
|
|
||||||
1. **Create and push a tag for the desired release track.**
|
The `.Y` suffix is for iterations. If you find a bug in `v2.3.5-closed.1`, you would fix it on the release branch and tag the new commit as `v2.3.5-closed.2`.
|
||||||
```bash
|
|
||||||
# This build will be uploaded and rolled out on the 'internal' track
|
|
||||||
git tag v1.2.3-internal.1
|
|
||||||
git push origin v1.2.3-internal.1
|
|
||||||
```
|
|
||||||
2. **Wait for the workflow to complete.**
|
|
||||||
3. **Verify the build** in the Google Play Console and with testers.
|
|
||||||
4. When ready to advance to the next track, create and push a new tag.
|
|
||||||
```bash
|
|
||||||
# This will create and upload a NEW build to the 'NewAlpha' (closed alpha) track
|
|
||||||
git tag v1.2.3-closed.1
|
|
||||||
git push origin v1.2.3-closed.1
|
|
||||||
```
|
|
||||||
|
|
||||||
## Iterating on a Bad Build
|
## Core Release Workflow
|
||||||
|
|
||||||
If you discover a critical bug in a build, the process is simple:
|
The entire release process happens on a dedicated release branch, allowing `main` to remain open for new feature development.
|
||||||
|
|
||||||
1. **Fix the Code:** Merge the necessary bug fixes into your main branch.
|
### 1. Creating the Release Branch
|
||||||
2. **Create a New Iteration Tag:** Create a new tag for the same release phase, simply incrementing the final number.
|
First, create a `release/X.X.X` branch from a stable `main`. This branch is now "feature frozen." Only critical bug fixes should be added.
|
||||||
```bash
|
|
||||||
# If v1.2.3-internal.1 was bad, the new build is v1.2.3-internal.2
|
|
||||||
git tag v1.2.3-internal.2
|
|
||||||
git push origin v1.2.3-internal.2
|
|
||||||
```
|
|
||||||
3. **A New Build is Uploaded:** The workflow will run, generate a new epoch-minute-based `versionCode`, and upload a fresh build to the `internal` track. There is no risk of a `versionCode` collision.
|
|
||||||
|
|
||||||
## Managing Different Release Phases (Manual Steps Post-Workflow)
|
As a housekeeping step, it's recommended to update the `VERSION_NAME_BASE` in `buildSrc/src/main/kotlin/Configs.kt` on this new branch. While the final release version is set by the Git tag in CI, this ensures local development builds have a sensible version name.
|
||||||
|
|
||||||
After the `release.yml` workflow completes, manual actions are needed on GitHub and in the Google Play Console.
|
```bash
|
||||||
|
git checkout main
|
||||||
|
git pull origin main
|
||||||
|
git checkout -b release/2.3.5
|
||||||
|
# (Now, update the version in buildSrc, commit the change, and then push)
|
||||||
|
git push origin release/2.3.5
|
||||||
|
```
|
||||||
|
|
||||||
### Phase 1: Internal / QA Release
|
### 2. Testing and Iterating on a Track
|
||||||
* **Tag format:** `vX.X.X-internal.Y`
|
Start by deploying to the `internal` track to begin testing.
|
||||||
* **Automated Action:** The AAB is **uploaded** to the `internal` track and rolled out automatically.
|
|
||||||
* **Manual Steps:**
|
|
||||||
1. **GitHub:** Find the **draft release**, verify artifacts, and publish it if desired.
|
|
||||||
2. **Google Play Console:** Verify the release has been successfully rolled out to internal testers.
|
|
||||||
|
|
||||||
### Phase 2: Closed Alpha Release
|
**A. Create and Push a Tag:**
|
||||||
* **Tag format:** `vX.X.X-closed.Y`
|
Tag a commit on the release branch to trigger the automation.
|
||||||
* **Automated Action:** A new AAB is built and **uploaded** as a **draft** to the `NewAlpha` track.
|
```bash
|
||||||
* **Manual Steps:**
|
# Ensure you are on the release branch
|
||||||
1. **GitHub:** Find and publish the **draft release**.
|
git checkout release/2.3.5
|
||||||
2. **Google Play Console:** Manually review the draft release and submit it for your closed alpha testers.
|
|
||||||
|
|
||||||
### Phase 3: Open Alpha / Beta Release
|
# Tag for the "Internal" track
|
||||||
* **Tag format:** `vX.X.X-open.Y`
|
git tag v2.3.5-internal.1
|
||||||
* **Automated Action:** A new AAB is built and **uploaded** as a **draft** to the `beta` track.
|
git push origin v2.3.5-internal.1
|
||||||
* **Manual Steps:**
|
```
|
||||||
1. **GitHub:** Find and publish the **draft pre-release**.
|
|
||||||
2. **Google Play Console:** Manually review the draft, add release notes, and submit it.
|
|
||||||
|
|
||||||
### Phase 4: Production Release
|
**B. Monitor and Verify:**
|
||||||
* **Tag format:** `vX.X.X`
|
Monitor the workflow in GitHub Actions. Once complete, verify the build in the Google Play Console and with your internal testers.
|
||||||
* **Automated Action:** A new AAB is built and **uploaded** to the `production` track. By default, it is configured for a 10% staged rollout.
|
|
||||||
* **Manual Steps:**
|
**C. Apply Fixes (If Necessary):**
|
||||||
1. **GitHub:** Find the **draft release**. **Crucially, uncheck "This is a pre-release"** before publishing.
|
If a bug is found, commit the fix to the release branch. Remember to also cherry-pick or merge this fix back to `main`. Then, create an iterated tag.
|
||||||
2. **Google Play Console:** Manually review the release, add release notes, and **start the staged rollout**.
|
```bash
|
||||||
|
# Assuming you've committed a fix
|
||||||
|
git tag v2.3.5-internal.2
|
||||||
|
git push origin v2.3.5-internal.2
|
||||||
|
```
|
||||||
|
This will upload a new, fixed build to the same `internal` track. Repeat this process until the build is stable.
|
||||||
|
|
||||||
|
### 3. Promoting to the Next Track
|
||||||
|
Once you are confident that a build is stable, you can "promote" it to a wider audience by tagging the **exact same commit** for the next track.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# The commit tagged as v2.3.5-internal.2 is stable and ready for the "Closed" track
|
||||||
|
git tag v2.3.5-closed.1
|
||||||
|
git push origin v2.3.5-closed.1
|
||||||
|
```
|
||||||
|
This triggers the workflow again, but this time it will send the build to the `NewAlpha` track for your closed testers. You can then continue the cycle of testing, fixing, and promoting all the way to production.
|
||||||
|
|
||||||
|
### 4. Merging Back to `main`
|
||||||
|
After the final production release is complete and verified, merge the release branch back into `main` to ensure any hotfixes are included. Then, delete the release branch.
|
||||||
|
```bash
|
||||||
|
git checkout main
|
||||||
|
git pull origin main
|
||||||
|
git merge release/2.3.5
|
||||||
|
git push origin main
|
||||||
|
git branch -d release/2.3.5
|
||||||
|
git push origin --delete release/2.3.5
|
||||||
|
```
|
||||||
|
|
||||||
|
## Manual Finalization Steps
|
||||||
|
|
||||||
|
### For Internal Releases
|
||||||
|
|
||||||
|
* **Automated Action:** The AAB is uploaded to the `internal` track and is **rolled out to 100% of testers automatically**.
|
||||||
|
* **Your Manual Step:**
|
||||||
|
1. **Verify the build** in the Google Play Console and with your internal testers.
|
||||||
|
|
||||||
|
### For Closed Releases
|
||||||
|
|
||||||
|
* **Automated Action:** The AAB is uploaded to the `NewAlpha` track and is **rolled out to 100% of testers automatically**.
|
||||||
|
* **Your Manual Step:**
|
||||||
|
1. **Verify the build** in the Google Play Console and with your closed track testers.
|
||||||
|
|
||||||
|
### For Open Releases
|
||||||
|
|
||||||
|
* **Automated Action:** The AAB is uploaded to the `beta` track and begins a **staged rollout to 25% of your open track testers automatically**.
|
||||||
|
* **Your Manual Steps:**
|
||||||
|
1. **Verify the build** in the Google Play Console.
|
||||||
|
2. **(Optional)** Go to the GitHub "Releases" page, find the **draft release**, and publish it so your open track testers can see the official release notes.
|
||||||
|
|
||||||
|
### For Production Releases
|
||||||
|
|
||||||
|
* **Automated Action:**
|
||||||
|
* The AAB is uploaded to the `production` track in a **draft** state. It is **not** rolled out to any users.
|
||||||
|
* A corresponding **draft** release is created on GitHub with all build artifacts.
|
||||||
|
* **Your Manual Steps:**
|
||||||
|
1. **Publish on GitHub First:** Go to the GitHub "Releases" page and find the draft. Review the release notes and artifacts, then **Publish release**. This makes the release notes publicly visible.
|
||||||
|
2. **Promote on Google Play Second:** *After* publishing on GitHub, go to your Google Play Console. Find the draft release, review it, and then proceed to **start the rollout to production**.
|
||||||
|
|
||||||
|
## Monitoring the Release
|
||||||
|
|
||||||
|
After a release has been rolled out to users (especially for Open and Production), it is crucial to monitor its performance.
|
||||||
|
|
||||||
|
* **Google Play Console:** Keep a close eye on the **Vitals** section for your app. Pay special attention to the crash rate and ANR (Application Not Responding) rate. A sudden spike in these numbers is a strong indicator of a problem.
|
||||||
|
* **Datadog:** Check your Datadog dashboards for any unusual trends or new errors that may have been introduced with the release.
|
||||||
|
* **Crashlytics:** Review crash reports in Firebase Crashlytics to identify any new issues that users may be experiencing.
|
||||||
|
* **User Reviews:** Monitor user reviews on the Google Play Store for any negative feedback or reports of bugs.
|
||||||
|
* **Community Feedback:** Monitor Discord, GitHub Issues, and community forums for feedback from users who have received the update.
|
||||||
|
|
||||||
|
If you identify a critical issue, be prepared to halt the rollout in the Google Play Console and tag a new, fixed version.
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
This is a beta release of the meshtastic.org project. We'd love you to try it and tell us what you think. You'll need to buy an inexpensive ($30ish) radio from a variety of vendors to use this application, see our website for details. We don't make these devices.
|
|
||||||
|
|
||||||
***Please*** if you encounter problems or have questions: post on our forum at https://github.com/orgs/meshtastic/discussions and we'll work together to fix them (we are volunteer hobbyists). We would really appreciate good Google reviews if you think this is a good project.
|
|
Przed Szerokość: | Wysokość: | Rozmiar: 16 KiB |
|
@ -1 +0,0 @@
|
||||||
An inexpensive open-source GPS mesh radio for hiking, skiing, flying, marching.
|
|
|
@ -1 +0,0 @@
|
||||||
Meshtastic
|
|
|
@ -1 +0,0 @@
|
||||||
For more information visit <a href="https://meshtastic.org">meshtastic.org</a>. This application is made by volunteers. We are friendly and actively respond to forum posts with any questions you have. Post at <a href="https://github.com/orgs/meshtastic/discussions">https://github.com/orgs/meshtastic/discussions</a> and we'll help.
|
|
|
@ -1 +0,0 @@
|
||||||
For more information visit <a href="https://meshtastic.org">meshtastic.org</a>. This application is made by volunteers. We are friendly and actively respond to forum posts with any questions you have. Post at <a href="https://github.com/orgs/meshtastic/discussions">https://github.com/orgs/meshtastic/discussions</a> and we'll help.
|
|
|
@ -1 +0,0 @@
|
||||||
An internal build
|
|
|
@ -1 +0,0 @@
|
||||||
For more information visit <a href="https://meshtastic.org">meshtastic.org</a>. This application is made by volunteers. We are friendly and actively respond to forum posts with any questions you have. Post at <a href="https://github.com/orgs/meshtastic/discussions">https://github.com/orgs/meshtastic/discussions</a> and we'll help.
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
json_key_file("./fastlane/play-store-credentials.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
|
||||||
|
package_name("com.geeksville.mesh") # e.g. com.krausefx.app
|
|
@ -0,0 +1,86 @@
|
||||||
|
# This file contains the fastlane.tools configuration
|
||||||
|
# You can find the documentation at https://docs.fastlane.tools
|
||||||
|
#
|
||||||
|
# For a list of all available actions, check out
|
||||||
|
#
|
||||||
|
# https://docs.fastlane.tools/actions
|
||||||
|
#
|
||||||
|
# For a list of all available plugins, check out
|
||||||
|
#
|
||||||
|
# https://docs.fastlane.tools/plugins/available-plugins
|
||||||
|
#
|
||||||
|
|
||||||
|
# Uncomment the line if you want fastlane to automatically update itself
|
||||||
|
# update_fastlane
|
||||||
|
|
||||||
|
default_platform(:android)
|
||||||
|
|
||||||
|
platform :android do
|
||||||
|
desc "Runs all the tests"
|
||||||
|
lane :test do
|
||||||
|
gradle(task: "test")
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Deploy a new version to the internal track on Google Play"
|
||||||
|
lane :internal do
|
||||||
|
aab_path = build_google_release
|
||||||
|
upload_to_play_store(
|
||||||
|
track: 'internal',
|
||||||
|
aab: aab_path,
|
||||||
|
release_status: 'completed'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Deploy a new version to the closed track on Google Play"
|
||||||
|
lane :closed do
|
||||||
|
aab_path = build_google_release
|
||||||
|
upload_to_play_store(
|
||||||
|
track: 'NewAlpha',
|
||||||
|
aab: aab_path,
|
||||||
|
release_status: 'completed'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Deploy a new version to the open track on Google Play"
|
||||||
|
lane :open do
|
||||||
|
aab_path = build_google_release
|
||||||
|
upload_to_play_store(
|
||||||
|
track: 'beta',
|
||||||
|
aab: aab_path,
|
||||||
|
release_status: 'inProgress',
|
||||||
|
rollout: '0.25'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Deploy a new version to the production track on Google Play"
|
||||||
|
lane :production do
|
||||||
|
aab_path = build_google_release
|
||||||
|
upload_to_play_store(
|
||||||
|
track: 'production',
|
||||||
|
aab: aab_path,
|
||||||
|
release_status: 'draft'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Build the F-Droid release"
|
||||||
|
lane :fdroid_build do
|
||||||
|
gradle(
|
||||||
|
task: "clean assembleFdroidRelease",
|
||||||
|
properties: {
|
||||||
|
"android.injected.version.name" => ENV['VERSION_NAME'],
|
||||||
|
"android.injected.version.code" => ENV['VERSION_CODE']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private_lane :build_google_release do
|
||||||
|
gradle(
|
||||||
|
task: "clean bundleGoogleRelease assembleGoogleRelease",
|
||||||
|
print_command: false,
|
||||||
|
properties: {
|
||||||
|
"android.injected.version.name" => ENV['VERSION_NAME'],
|
||||||
|
"android.injected.version.code" => ENV['VERSION_CODE']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,48 @@
|
||||||
|
fastlane documentation
|
||||||
|
----
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
Make sure you have the latest version of the Xcode command line tools installed:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
|
||||||
|
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
|
||||||
|
|
||||||
|
# Available Actions
|
||||||
|
|
||||||
|
## Android
|
||||||
|
|
||||||
|
### android test
|
||||||
|
|
||||||
|
```sh
|
||||||
|
[bundle exec] fastlane android test
|
||||||
|
```
|
||||||
|
|
||||||
|
Runs all the tests
|
||||||
|
|
||||||
|
### android beta
|
||||||
|
|
||||||
|
```sh
|
||||||
|
[bundle exec] fastlane android beta
|
||||||
|
```
|
||||||
|
|
||||||
|
Submit a new Beta Build to Crashlytics Beta
|
||||||
|
|
||||||
|
### android deploy
|
||||||
|
|
||||||
|
```sh
|
||||||
|
[bundle exec] fastlane android deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy a new version to the Google Play
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
|
||||||
|
|
||||||
|
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
|
||||||
|
|
||||||
|
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
|
|
@ -0,0 +1 @@
|
||||||
|
For detailed release notes, please visit: https://github.com/meshtastic/Meshtastic-Android/releases/
|
|
@ -0,0 +1,21 @@
|
||||||
|
Meshtastic is a tool for using Android devices with open-source, off-grid mesh radios. This app is the main client for the Meshtastic project, allowing you to manage your mesh devices and communicate with other users.
|
||||||
|
|
||||||
|
For more information about the Meshtastic project, please visit our website: [meshtastic.org](https://www.meshtastic.org). The firmware that runs on the radio devices is a separate open-source project, which you can find here: [https://github.com/meshtastic/Meshtastic-device](https://github.com/meshtastic/Meshtastic-device).
|
||||||
|
|
||||||
|
**Community and Support**
|
||||||
|
|
||||||
|
This project is currently in beta. We would love to hear from you! If you have questions, feedback, or encounter any problems, please join our friendly and active community:
|
||||||
|
|
||||||
|
* **Discussion Forum:** [https://github.com/orgs/meshtastic/discussions](https://github.com/orgs/meshtastic/discussions)
|
||||||
|
* **Discord:** [https://discord.gg/meshtastic](https://discord.gg/meshtastic)
|
||||||
|
* **Report an Issue:** [https://github.com/meshtastic/Meshtastic-Android/issues](https://github.com/meshtastic/Meshtastic-Android/issues)
|
||||||
|
|
||||||
|
**Documentation**
|
||||||
|
|
||||||
|
To learn more about the features and capabilities of this app and Meshtastic, please view our official documentation:
|
||||||
|
[**View Documentation**](https://meshtastic.org/docs/)
|
||||||
|
|
||||||
|
**Translations**
|
||||||
|
|
||||||
|
You can help translate the app into your native language using Crowdin:
|
||||||
|
[https://crowdin.meshtastic.org/android](https://crowdin.meshtastic.org/android)
|
Przed Szerokość: | Wysokość: | Rozmiar: 67 KiB Po Szerokość: | Wysokość: | Rozmiar: 67 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 13 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 91 KiB Po Szerokość: | Wysokość: | Rozmiar: 91 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 108 KiB Po Szerokość: | Wysokość: | Rozmiar: 108 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 125 KiB Po Szerokość: | Wysokość: | Rozmiar: 125 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 2.0 MiB Po Szerokość: | Wysokość: | Rozmiar: 2.0 MiB |
Przed Szerokość: | Wysokość: | Rozmiar: 72 KiB Po Szerokość: | Wysokość: | Rozmiar: 72 KiB |
|
@ -0,0 +1 @@
|
||||||
|
The official app for Meshtastic, an open-source, off-grid, mesh GPS radio.
|
|
@ -0,0 +1 @@
|
||||||
|
Meshtastic
|