test(e2e): initial implementation #1075
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: | |
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@v4 | |
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: Set up Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version-file: .nvmrc | |
- name: Cache node modules | |
uses: actions/cache@v4 | |
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: 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@v4 | |
- name: Set .env | |
run: | |
echo "MAPBOX_TOKEN=${{ secrets.MAPBOX_TOKEN }}" >> .env | |
- name: Set local.properties | |
run: | |
echo "MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_TOKEN }}" >> android/local.properties | |
- name: Gradle Wrapper Validation | |
uses: gradle/actions/wrapper-validation@v3 | |
- name: Setup Ruby | |
uses: ruby/setup-ruby@v1 | |
with: | |
bundler-cache: true # runs 'bundle install' and caches installed gems automatically | |
- name: Set up Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version-file: .nvmrc | |
- name: Cache node modules | |
uses: actions/cache@v4 | |
with: | |
path: ./node_modules | |
key: ${{ runner.os }}-npm-${{ hashFiles('./package-lock.json') }} | |
- name: Cache Gradle artifacts | |
uses: actions/cache@v4 | |
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: 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: | |
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 }} | |
SUPPLY_GOOGLE_SERVICE_INFO_PLIST_PATH: "./GoogleService-Info.plist" | |
needs: configure | |
runs-on: [macos-latest] | |
steps: | |
- name: Select Xcode | |
uses: maxim-lobanov/setup-xcode@v1 | |
with: | |
xcode-version: '15' | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Set .env | |
run: | |
echo "MAPBOX_TOKEN=${{ secrets.MAPBOX_TOKEN }}" >> .env | |
- name: Set .netrc | |
run: | | |
echo "machine api.mapbox.com | |
login mapbox | |
password ${{ secrets.MAPBOX_TOKEN }} | |
" > ~/.netrc | |
chmod 600 ~/.netrc | |
- name: Setup Ruby | |
uses: ruby/setup-ruby@v1 | |
with: | |
bundler-cache: true # runs 'bundle install' and caches installed gems automatically | |
- name: Set up Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version-file: .nvmrc | |
- name: Cache node modules | |
uses: actions/cache@v4 | |
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: Cache pods | |
uses: actions/cache@v4 | |
with: | |
path: ./ios/Pods | |
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} | |
- name: Install npm dependencies | |
run: npm install | |
- name: Ensure pods installed | |
working-directory: ./ios | |
run: bundle exec pod install | |
- name: Prepare fastlane | |
working-directory: ./ios | |
run: | | |
echo "${{ secrets.MATCH_GIT_AUTH_PK }}" > ${MATCH_GIT_PRIVATE_KEY} | |
chmod 600 ${MATCH_GIT_PRIVATE_KEY} | |
echo "${{ secrets.SUPPLY_GOOGLE_SERVICE_INFO_PLIST }}" | base64 -d > ${SUPPLY_GOOGLE_SERVICE_INFO_PLIST_PATH} | |
chmod 600 ${MATCH_GIT_PRIVATE_KEY} ${SUPPLY_GOOGLE_SERVICE_INFO_PLIST_PATH} | |
- 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@v4 | |
- 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 |