Files
Meshtastic-Android/.github/workflows/release.yml
renovate[bot] a54f8c8ea3 chore(deps): update actions/github-script action to v8 (#3165)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 15:32:39 +00:00

262 lines
9.0 KiB
YAML

name: Make Release
on:
workflow_dispatch:
push:
tags:
- 'v*'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
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 }}
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: Determine Version Name from Tag
id: get_version_name
run: echo "APP_VERSION_NAME=$(echo ${GITHUB_REF_NAME#v} | sed 's/-.*//')" >> $GITHUB_OUTPUT
- name: Calculate Version Code from Epoch
id: calculate_version_code
# We use epoch minutes to ensure a unique, always-incrementing version code.
# This is compatible with our release strategy of tagging the same commit for different
# channels (internal, closed, open, prod), as each build needs a unique code.
# 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
release-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
if: contains(github.ref_name, '-internal')
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:
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 # Ensure clean state
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.2'
bundler-cache: true
- name: Determine Fastlane Lane
id: fastlane_lane
run: |
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:
VERSION_NAME: ${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}
VERSION_CODE: ${{ needs.prepare-build-info.outputs.APP_VERSION_CODE }}
run: bundle exec fastlane ${{ steps.fastlane_lane.outputs.lane }}
- name: Upload Google AAB artifact
if: contains(github.ref_name, '-internal')
uses: actions/upload-artifact@v4
with:
name: google-aab
path: app/build/outputs/bundle/googleRelease/app-google-release.aab
retention-days: 1
- name: Upload Google APK artifact
if: contains(github.ref_name, '-internal')
uses: actions/upload-artifact@v4
with:
name: google-apk
path: app/build/outputs/apk/google/release/app-google-release.apk
retention-days: 1
release-fdroid:
if: contains(github.ref_name, '-internal')
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 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:
name: fdroid-apk
path: app/build/outputs/apk/fdroid/release/app-fdroid-release.apk
retention-days: 1
create-github-release:
if: contains(github.ref_name, '-internal')
runs-on: ubuntu-latest
needs: [release-google, release-fdroid]
steps:
- name: Download all artifacts
uses: actions/download-artifact@v5
with:
path: ./artifacts
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: Release ${{ github.ref_name }}
generate_release_notes: true
files: |
./artifacts/google-aab/app-google-release.aab
./artifacts/google-apk/app-google-release.apk
./artifacts/fdroid-apk/app-fdroid-release.apk
draft: true
prerelease: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
update-github-release:
if: "!contains(github.ref_name, '-internal')"
runs-on: ubuntu-latest
needs: [prepare-build-info, release-google]
steps:
- name: Update GitHub Release
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo } = context.repo;
const internal_tag = `v${{ needs.prepare-build-info.outputs.APP_VERSION_NAME }}-internal`;
const current_tag = "${{ github.ref_name }}";
try {
const release = await github.rest.repos.getReleaseByTag({
owner,
repo,
tag: internal_tag,
});
let draft = false;
let prerelease = !current_tag.match(/^v\d+\.\d+\.\d+$/); // Not a production tag
await github.rest.repos.updateRelease({
owner,
repo,
release_id: release.data.id,
name: `Release ${current_tag}`,
draft: draft,
prerelease: prerelease,
});
console.log(`Successfully updated release for tag ${internal_tag} to name="Release ${current_tag}", draft=${draft}, prerelease=${prerelease}`);
} catch (error) {
console.error(`Could not find and update the release for tag ${internal_tag}.`);
console.error(error);
core.setFailed(`Failed to update the GitHub release.`);
}