Files
Meshtastic-Android/.github/workflows/release.yml

370 lines
12 KiB
YAML

name: Make Release
on:
workflow_call:
inputs:
base_version:
description: 'The base version for the release (e.g., 2.3.0)'
required: true
type: string
tag_name:
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
type: string
secrets:
GSERVICES:
required: true
KEYSTORE:
required: true
KEYSTORE_FILENAME:
required: true
KEYSTORE_PROPERTIES:
required: true
DATADOG_APPLICATION_ID:
required: true
DATADOG_CLIENT_TOKEN:
required: true
GOOGLE_MAPS_API_KEY:
required: true
GOOGLE_PLAY_JSON_KEY:
required: true
GRADLE_ENCRYPTION_KEY:
required: true
GRADLE_CACHE_URL:
required: false
GRADLE_CACHE_USERNAME:
required: false
GRADLE_CACHE_PASSWORD:
required: false
INTERNAL_BUILDS_HOST:
required: false
INTERNAL_BUILDS_HOST_PAT:
required: false
concurrency:
group: ${{ github.workflow }}-${{ inputs.tag_name }}
cancel-in-progress: true
permissions:
contents: write
pull-requests: read
id-token: write
attestations: write
jobs:
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_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ inputs.tag_name }}
fetch-depth: 0
submodules: 'recursive'
- name: Determine Version Name from Tag
id: get_version_name
run: echo "APP_VERSION_NAME=$(echo ${{ inputs.tag_name }} | sed 's/-.*//' | sed 's/v//')" >> $GITHUB_OUTPUT
- name: Extract VERSION_CODE_OFFSET from config.properties
id: get_version_code_offset
run: |
OFFSET=$(grep '^VERSION_CODE_OFFSET=' config.properties | cut -d'=' -f2)
echo "VERSION_CODE_OFFSET=$OFFSET" >> $GITHUB_OUTPUT
- name: Calculate Version Code from Git Commit Count
id: calculate_version_code
run: |
COMMIT_COUNT=$(git rev-list --count HEAD)
OFFSET=${{ steps.get_version_code_offset.outputs.VERSION_CODE_OFFSET }}
VERSION_CODE=$((COMMIT_COUNT + OFFSET))
echo "versionCode=$VERSION_CODE" >> $GITHUB_OUTPUT
shell: bash
release-google:
runs-on: ubuntu-latest
needs: [prepare-build-info]
environment: Release
env:
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ inputs.tag_name }}
fetch-depth: 0
submodules: 'recursive'
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'zulu'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
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:
GSERVICES: ${{ secrets.GSERVICES }}
KEYSTORE: ${{ secrets.KEYSTORE }}
KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }}
KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}
DATADOG_APPLICATION_ID: ${{ secrets.DATADOG_APPLICATION_ID }}
DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }}
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
GOOGLE_PLAY_JSON_KEY: ${{ secrets.GOOGLE_PLAY_JSON_KEY }}
run: |
rm -f ./app/google-services.json
echo $GSERVICES > ./app/google-services.json
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
echo "datadogApplicationId=$DATADOG_APPLICATION_ID" >> ./secrets.properties
echo "datadogClientToken=$DATADOG_CLIENT_TOKEN" >> ./secrets.properties
echo "MAPS_API_KEY=$GOOGLE_MAPS_API_KEY" >> ./secrets.properties
echo "$GOOGLE_PLAY_JSON_KEY" > ./fastlane/play-store-credentials.json
- name: Setup Fastlane
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4.9'
bundler-cache: true
- name: Export Full Library Licenses
run: ./gradlew exportLibraryDefinitions -Pci=true
- name: Build and Deploy Google Play to Internal Track 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 internal
- name: List outputs
run: ls -R app/build/outputs/
- name: Upload Google AAB artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: google-aab
path: app/build/outputs/bundle/googleRelease/app-google-release.aab
retention-days: 1
- name: Upload Google APK artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: google-apk
path: app/build/outputs/apk/google/release/*.apk
retention-days: 1
- name: Attest Google AAB provenance
if: success()
uses: actions/attest-build-provenance@v4
with:
subject-path: app/build/outputs/bundle/googleRelease/app-google-release.aab
- name: Attest Google APK provenance
if: success()
uses: actions/attest-build-provenance@v4
with:
subject-path: app/build/outputs/apk/google/release/*.apk
release-fdroid:
runs-on: ubuntu-latest
needs: [prepare-build-info]
environment: Release
env:
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ inputs.tag_name }}
fetch-depth: 0
submodules: 'recursive'
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'zulu'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
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.4.9'
bundler-cache: true
- name: Export Full Library Licenses
run: ./gradlew exportLibraryDefinitions -Pci=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: List outputs
run: ls -R app/build/outputs/
- name: Upload F-Droid APK artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: fdroid-apk
path: app/build/outputs/apk/fdroid/release/*.apk
retention-days: 1
- name: Attest F-Droid APK provenance
if: success()
uses: actions/attest-build-provenance@v4
with:
subject-path: app/build/outputs/apk/fdroid/release/*.apk
release-desktop:
runs-on: ${{ matrix.os }}
needs: [prepare-build-info]
environment: Release
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-22.04, ubuntu-22.04-arm]
env:
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }}
GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ inputs.tag_name }}
fetch-depth: 0
submodules: 'recursive'
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'zulu'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
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: Export Full Library Licenses
run: ./gradlew exportLibraryDefinitions -Pci=true
- name: Install dependencies for AppImage
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libfuse2
- name: Package Native Distributions
env:
ORG_GRADLE_PROJECT_appVersionName: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
APPIMAGE_EXTRACT_AND_RUN: 1
run: ./gradlew :desktop:packageReleaseDistributionForCurrentOS --no-daemon
- name: List Desktop Binaries
if: runner.os == 'Linux'
run: ls -R desktop/build/compose/binaries/main-release
- name: Upload Desktop Artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: desktop-${{ runner.os }}-${{ runner.arch }}
path: |
desktop/build/compose/binaries/main-release/*/*.dmg
desktop/build/compose/binaries/main-release/*/*.msi
desktop/build/compose/binaries/main-release/*/*.exe
desktop/build/compose/binaries/main-release/*/*.deb
desktop/build/compose/binaries/main-release/*/*.rpm
desktop/build/compose/binaries/main-release/*/*.AppImage
retention-days: 1
if-no-files-found: ignore
github-release:
runs-on: ubuntu-latest
needs: [prepare-build-info, release-google, release-fdroid, release-desktop]
env:
INTERNAL_BUILDS_HOST: ${{ secrets.INTERNAL_BUILDS_HOST }}
permissions:
contents: write
id-token: write
attestations: write
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ inputs.tag_name }}
- name: Download all artifacts
uses: actions/download-artifact@v8
with:
path: ./artifacts
- name: Create or Update GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ inputs.tag_name }}
target_commitish: ${{ inputs.commit_sha || github.sha }}
name: ${{ inputs.tag_name }} (${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }})
generate_release_notes: true
files: ./artifacts/**/*
draft: true
prerelease: true
- name: Create or Update internal GitHub Release
continue-on-error: true
if: ${{ env.INTERNAL_BUILDS_HOST != '' }}
uses: softprops/action-gh-release@v2
with:
repository: ${{ secrets.INTERNAL_BUILDS_HOST }}
token: ${{ secrets.INTERNAL_BUILDS_HOST_PAT }}
tag_name: ${{ inputs.tag_name }}
name: ${{ inputs.tag_name }} (${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }})
generate_release_notes: false
files: ./artifacts/**/*
draft: false
prerelease: true