Fastlane #517
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Fastlane | |
on: | |
push: | |
branches: | |
- main | |
tags: | |
- "v*" | |
pull_request: | |
types: | |
- opened | |
- reopened | |
- synchronize | |
workflow_dispatch: # allow manual run | |
inputs: | |
push_to_testflight: | |
type: boolean | |
description: Upload to TestFlight | |
required: true | |
default: false | |
push_to_playstore: | |
type: choice | |
description: Push to PlayStore | |
options: | |
- 'false' | |
- internal | |
- beta | |
- production | |
required: true | |
version: | |
type: string | |
description: App version (vXX.YY.ZZ) | |
required: true | |
default: LATEST | |
build_piece: | |
type: string | |
description: Build piece (last 2 digits of build_no) | |
required: true | |
jobs: | |
configure: | |
name: Configure | |
runs-on: ubuntu-latest | |
outputs: | |
version: ${{ steps.configure.outputs.version }} | |
build_no: ${{ steps.configure.outputs.build_no }} | |
push_to_testflight: ${{ steps.configure.outputs.push_to_testflight }} | |
push_to_playstore: ${{ steps.configure.outputs.push_to_playstore }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
with: | |
fetch-depth: 0 | |
- name: Get version from tag (new release) | |
id: tag_version | |
run: echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT | |
if: | | |
github.event_name == 'push' && | |
github.event.repository.full_name == github.repository && | |
github.ref_type == 'tag' | |
- name: Get version from last release | |
id: last_release | |
uses: pozetroninc/github-action-get-latest-release@master | |
with: | |
repository: ${{ github.repository }} | |
excludes: draft | |
token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Gather workflow info | |
id: configure | |
run: | | |
VERSION="" | |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
# On pull_request event, no need to publish | |
PUSH_TESTFLIGHT=false | |
PUSH_PLAYSTORE=false | |
elif [[ "${{ steps.tag_version.outputs.version }}" != "" ]]; then | |
# On tag push (release), we're in production | |
PUSH_TESTFLIGHT=true | |
PUSH_PLAYSTORE="${{ vars.PLAYSTORE_RELEASE_TRACK }}" | |
VERSION="${{ steps.tag_version.outputs.version }}" | |
BUILD_PIECE=0 | |
elif [[ "${{ github.event.inputs.version }}" != "" ]]; then | |
# On repo manual dispatch | |
PUSH_TESTFLIGHT="${{ github.event.inputs.push_to_testflight }}" | |
PUSH_PLAYSTORE="${{ github.event.inputs.push_to_playstore }}" | |
if [[ "${{ github.event.inputs.version }}" == "LATEST" && "${{ steps.last_release.outputs.release }}" != "" ]]; then | |
VERSION="${{ steps.last_release.outputs.release }}" | |
else | |
VERSION="${{ github.event.inputs.version }}" | |
fi | |
BUILD_PIECE="${{ github.event.inputs.build_piece }}" | |
elif [[ "${{ steps.last_release.outputs.release }}" != "" ]]; then | |
# we're supposed to be on push on main (e.g. pr merge) here | |
PUSH_TESTFLIGHT=true | |
PUSH_PLAYSTORE=beta | |
VERSION="${{ steps.last_release.outputs.release }}" | |
BUILD_PIECE=$(git rev-list $VERSION.. --count) | |
else | |
echo "UNHANDLED EVENT. CANNOT CONFIG SAFELY." | |
exit 1 | |
fi | |
if [[ "$BUILD_PIECE" != "" && ! "$BUILD_PIECE" =~ ^[0-9]{1,2}$ ]]; then | |
echo "INVALID BUILD PIECE FORMAT: $BUILD_PIECE" | |
exit 1 | |
fi | |
if [[ "$VERSION" =~ ^v([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})$ ]]; then | |
MAJOR=${BASH_REMATCH[1]} | |
MINOR=${BASH_REMATCH[2]} | |
SUBV=${BASH_REMATCH[3]} | |
BUILD_NO=$(( MAJOR*1000000 + MINOR*10000 + SUBV*100 + BUILD_PIECE )) | |
echo "build_no=$BUILD_NO" >> $GITHUB_OUTPUT | |
echo "version=$MAJOR.$MINOR.$SUBV" >> $GITHUB_OUTPUT | |
elif [[ "$VERSION" != "" ]]; then | |
echo "INVALID VERSION FORMAT: $VERSION" | |
exit 2 | |
fi | |
echo "push_to_playstore=$PUSH_PLAYSTORE" >> $GITHUB_OUTPUT | |
echo "push_to_testflight=$PUSH_TESTFLIGHT" >> $GITHUB_OUTPUT | |
echo "CONFIGURED:" | |
cat $GITHUB_OUTPUT | |
- name: Cache node modules | |
uses: actions/cache@v3 | |
with: | |
path: ./node_modules | |
key: ${{ runner.os }}-npm-${{ hashFiles('./package-lock.json') }} | |
- name: Setup .npmrc | |
run: printf '@polito:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}\n' > .npmrc | |
- name: Setup Mapbox | |
run: | | |
printf 'MAPBOX_TOKEN=${{ secrets.MAPBOX_TOKEN }}\n' >> .env | |
printf 'MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_TOKEN }}\n' >> android/local.properties | |
printf 'machine api.mapbox.com\n\tlogin mapbox\n\tpassword ${{ secrets.MAPBOX_TOKEN }}\n' > ~/.netrc | |
- name: Install npm dependencies | |
run: npm install | |
build-android: | |
name: ${{ needs.configure.outputs.push_to_playstore == 'false' && 'Build' || 'Build & Deploy' }} Android | |
needs: configure | |
runs-on: ubuntu-latest | |
env: | |
LANG: en_US.UTF-8 | |
CI: 'true' | |
BUILD_NO: ${{ needs.configure.outputs.build_no }} | |
APP_VERSION: ${{ needs.configure.outputs.version }} | |
SUPPLY_GOOGLE_JSON_PATH: './pc-api-secret.json' | |
KEYSTORE_PW: ${{ secrets.ANDROID_KEYSTORE_PW }} | |
KEYSTORE_PATH: './keystore.jks' | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Gradle Wrapper Validation | |
uses: gradle/wrapper-validation-action@v1 | |
- name: Setup Ruby | |
uses: ruby/setup-ruby@v1 | |
with: | |
working-directory: ./android | |
ruby-version: '2.7.6' | |
bundler-cache: true # runs 'bundle install' and caches installed gems automatically | |
- name: Set up Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: 16 | |
- name: Cache node modules | |
uses: actions/cache@v3 | |
with: | |
path: ./node_modules | |
key: ${{ runner.os }}-npm-${{ hashFiles('./package-lock.json') }} | |
- name: Cache Gradle artifacts | |
uses: actions/cache@v3 | |
with: | |
path: | | |
~/.gradle/caches | |
~/.gradle/wrapper | |
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
restore-keys: ${{ runner.os }}-gradle- | |
- name: Setup .npmrc | |
run: printf '@polito:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}\n' > .npmrc | |
- name: Setup Mapbox | |
run: | | |
printf 'MAPBOX_TOKEN=${{ secrets.MAPBOX_TOKEN }}\n' >> .env | |
printf 'MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_TOKEN }}\n' >> android/local.properties | |
printf 'machine api.mapbox.com\n\tlogin mapbox\n\tpassword ${{ secrets.MAPBOX_TOKEN }}\n' > ~/.netrc | |
- name: Install npm dependencies | |
run: npm install | |
- name: Prepare fastlane | |
working-directory: ./android | |
run: | | |
echo "${{ secrets.SUPPLY_GOOGLE_JSON_SECRET }}" | base64 -d > ${SUPPLY_GOOGLE_JSON_PATH} | |
echo "${{ secrets.ANDROID_KEYSTORE_B64 }}" | base64 -d > ${KEYSTORE_PATH} | |
chmod 600 ${KEYSTORE_PATH} ${SUPPLY_GOOGLE_JSON_PATH} | |
- name: Fastlane VERIFY lane | |
if: needs.configure.outputs.push_to_playstore == 'false' | |
working-directory: ./android | |
run: bundle exec fastlane verify | |
- name: Fastlane RELEASE lane | |
if: contains(fromJSON('["internal", "beta", "production"]'), needs.configure.outputs.push_to_playstore) | |
working-directory: ./android | |
env: | |
STORE_TRACK: ${{ needs.configure.outputs.push_to_playstore }} | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }} | |
SENTRY_ORG: ${{ vars.SENTRY_ORG }} | |
run: bundle exec fastlane release | |
- name: Fastlane APK lane | |
if: | | |
github.event_name == 'push' && | |
github.ref_type == 'tag' | |
run: bundle exec fastlane apk | |
working-directory: ./android | |
- name: Upload Artifacts | |
if: | | |
github.event_name == 'push' && | |
github.ref_type == 'tag' | |
uses: actions/upload-artifact@v3 | |
with: | |
name: android-release | |
path: android/app/build/outputs/apk/release/*.apk | |
build-ios: | |
name: ${{ needs.configure.outputs.push_to_testflight == 'false' && 'Build' || 'Build & Deploy' }} iOS | |
env: | |
ImageOS: macos12 | |
LANG: en_US.UTF-8 | |
CI: 'true' | |
BUILD_NO: ${{ needs.configure.outputs.build_no }} | |
APP_VERSION: ${{ needs.configure.outputs.version }} | |
MATCH_PASSWORD: ${{ secrets.FASTLANE_MATCH_KEY }} | |
MATCH_GIT_PRIVATE_KEY: "./github_access.pk" | |
FASTLANE_USERNAME: ${{ secrets.FASTLANE_POLI_MOBILE_USER }} | |
FASTLANE_PASSWORD: ${{ secrets.FASTLANE_POLI_MOBILE_PW }} | |
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_DEV_PW }} | |
needs: configure | |
runs-on: [self-hosted, macos-12] | |
steps: | |
- name: Select Xcode | |
uses: maxim-lobanov/setup-xcode@v1 | |
with: | |
xcode-version: '14' | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup Ruby | |
uses: ruby/setup-ruby@v1 | |
with: | |
working-directory: ./ios | |
ruby-version: '2.7.6' | |
bundler-cache: true # runs 'bundle install' and caches installed gems automatically | |
- name: Set up Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: 16 | |
- name: Cache node modules | |
uses: actions/cache@v3 | |
with: | |
path: ./node_modules | |
key: ${{ runner.os }}-npm-${{ hashFiles('./package-lock.json') }} | |
- name: Setup .npmrc | |
run: printf '@polito:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}\n' > .npmrc | |
- name: Setup Mapbox | |
run: | | |
printf 'MAPBOX_TOKEN=${{ secrets.MAPBOX_TOKEN }}\n' >> .env | |
printf 'MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_TOKEN }}\n' >> android/local.properties | |
printf 'machine api.mapbox.com\n\tlogin mapbox\n\tpassword ${{ secrets.MAPBOX_TOKEN }}\n' > ~/.netrc | |
- name: Install npm dependencies | |
run: npm install | |
- name: Cache pods | |
uses: actions/cache@v3 | |
with: | |
path: ./ios/Pods | |
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} | |
- name: Install pod dependencies | |
working-directory: ./ios | |
run: bundle exec pod install --repo-update | |
- name: Prepare fastlane | |
working-directory: ./ios | |
run: | | |
echo "${{ secrets.MATCH_GIT_AUTH_PK }}" > ${MATCH_GIT_PRIVATE_KEY} | |
chmod 600 ${MATCH_GIT_PRIVATE_KEY} | |
- name: Fastlane VERIFY lane | |
if: needs.configure.outputs.push_to_testflight == 'false' | |
working-directory: ./ios | |
run: | | |
bundle exec fastlane verify | |
- name: Fastlane RELEASE lane | |
if: needs.configure.outputs.push_to_testflight == 'true' | |
working-directory: ./ios | |
env: | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }} | |
SENTRY_ORG: ${{ vars.SENTRY_ORG }} | |
run: | | |
bundle exec fastlane release | |
create-release: | |
name: Create GitHub Release | |
permissions: | |
contents: write | |
if: | | |
github.event_name == 'push' && | |
github.event.repository.full_name == github.repository && | |
github.ref_type == 'tag' | |
needs: [build-android, build-ios] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Gather artifacts | |
uses: actions/download-artifact@v3 | |
with: | |
name: android-release | |
path: ./android-release | |
- name: Create release | |
uses: ncipollo/release-action@v1 | |
with: | |
generateReleaseNotes: true | |
skipIfReleaseExists: true | |
artifacts: ./android-release/*.apk |