Skip to content

Instantly share code, notes, and snippets.

@codemem
Created August 28, 2021 09:42
Show Gist options
  • Save codemem/85ebb8cd52ea8b90f9adab1b85f76e21 to your computer and use it in GitHub Desktop.
Save codemem/85ebb8cd52ea8b90f9adab1b85f76e21 to your computer and use it in GitHub Desktop.
Build and Publish React Native Project to Testflight and Google Play
# Sources:
# https://blog.usejournal.com/automate-react-native-builds-with-github-actions-af54212d26dc
# https://zach.codes/ios-builds-using-github-actions-without-fastlane/
# https://stackoverflow.com/questions/16550594/jenkins-xcode-build-works-codesign-fails/19550453#19550453
# https://www.valueof.io/blog/deploying-to-google-play-using-github-actions
name: Build and Publish Test Builds
on:
push:
branches:
- master
jobs:
build-bump:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache JS dependencies
uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install JS dependencies
run: yarn --frozen-lockfile
- name: Increment build number
run: |
npx react-native-version -b --never-amend
VERSION=$(grep "versionCode " $BUILD_GRADLE | awk '{print $2}')
npx json -I -f package.json -e "this.build=\"${VERSION}\""
env:
BUILD_GRADLE: "android/app/build.gradle"
- name: Commit build number
run: |
BUILD_NUMBER=$(grep "versionCode " $BUILD_GRADLE | awk '{print $2}')
git config --local user.email "[email protected]"
git config --local user.name "Planning Center Bot"
git add package.json
git add ios/PlanningCenter/Info.plist
git add ios/PlanningCenter.xcodeproj/project.pbxproj
git add android/app/build.gradle
git commit -m "Bump build to ${BUILD_NUMBER}"
git push "https://${GITHUB_TOKEN}:[email protected]/${GITHUB_REPOSITORY}.git" HEAD:master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_PERSONAL_ACCESS_TOKEN }}
BUILD_GRADLE: "android/app/build.gradle"
build-ios:
needs: build-bump
runs-on: macos-10.15
steps:
- uses: actions/checkout@v2
- name: Get build bump
run: git pull
- name: Switch Xcode Version
run: sudo xcode-select -s /Applications/Xcode_11.5.app
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache JS dependencies
uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install JS dependencies
run: yarn --frozen-lockfile
- name: Cache Pod dependencies
uses: actions/cache@v1
with:
path: ios/Pods
key: ${{ runner.OS }}-pods-cache-${{ hashFiles('**/ios/Podfile.lock') }}
restore-keys: |
${{ runner.OS }}-pods-cache-
- name: Install Pod dependencies
run: |
cd ios
pod install
shell: bash
- name: Patch Flipper-Folly
run: cd ios && sed -i '' 's/ __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0/ __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_12_0/' Pods/Flipper-Folly/folly/portability/Time.h
- name: Setup provisioning profile and certificate
run: |
aws s3 cp s3://${AWS_BUCKET}/ios/${PROVISIONING_PROFILE_UUID}.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/${PROVISIONING_PROFILE_UUID}.mobileprovision
aws s3 cp s3://${AWS_BUCKET}/ios/Certificates.p12 ./Certificates.p12
security create-keychain -p "" build.keychain
security import ./Certificates.p12 -t agg -k ~/Library/Keychains/build.keychain -P "" -A
security list-keychains -s ~/Library/Keychains/build.keychain
security default-keychain -s ~/Library/Keychains/build.keychain
security set-keychain-settings ~/Library/Keychains/build.keychain
security unlock-keychain -p "" ~/Library/Keychains/build.keychain
security set-key-partition-list -S apple-tool:,apple: -s -k "" ~/Library/Keychains/build.keychain
env:
AWS_REGION: ${{ secrets.CODESIGN_AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.CODESIGN_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CODESIGN_AWS_SECRET_ACCESS_KEY }}
AWS_BUCKET: ${{ secrets.CODESIGN_AWS_BUCKET }}
PROVISIONING_PROFILE_UUID: ${{ secrets.CODESIGN_PROVISIONING_PROFILE_UUID }}
- name: Compile archive
run: |
cd ios && xcodebuild archive \
-workspace PlanningCenter.xcworkspace \
-scheme PlanningCenter \
-sdk iphoneos13.5 \
-configuration Release \
-archivePath $PWD/build/PlanningCenter.xcarchive \
IPHONEOS_DEPLOYMENT_TARGET=11.4
PROVISIONING_PROFILE="${PROVISIONING_PROFILE_UUID}" \
CODE_SIGN_IDENTITY="Apple Distribution: Planning Center (12345)"
env:
PROVISIONING_PROFILE_UUID: ${{ secrets.CODESIGN_PROVISIONING_PROFILE_UUID }}
- name: Export archive
run: |
cd ios && xcodebuild \
-exportArchive \
-archivePath $PWD/build/PlanningCenter.xcarchive \
-exportOptionsPlist $PWD/exportOptions.plist \
-exportPath $PWD/build
- name: Upload source maps to Bugsnag
run: |
APP_BUNDLE_VERSION=$($PLB -c "Print CFBundleVersion" "$PLIST")
APP_VERSION=$($PLB -c "Print CFBundleShortVersionString" "$PLIST")
npx react-native bundle \
--platform ios \
--dev false \
--entry-file index.js \
--bundle-output ios-release.bundle \
--sourcemap-output ios-release.bundle.map
curl --http1.1 https://upload.bugsnag.com/react-native-source-map \
-F apiKey=${{ secrets.BUGSNAG_API_KEY }} \
-F appVersion=$APP_VERSION \
-F appBundleVersion=$APP_BUNDLE_VERSION \
-F dev=false \
-F platform=ios \
-F [email protected] \
-F [email protected] \
-F projectRoot=$PWD
rm ios-release.bundle.map
rm ios-release.bundle
env:
PLIST: "ios/PlanningCenter/Info.plist"
PLB: /usr/libexec/PlistBuddy
- name: Publish to TestFlight
run: |
cd ios && xcrun altool --upload-app -f build/PlanningCenter.ipa -u $USERNAME -p $PASSWORD
env:
USERNAME: ${{ secrets.APPLE_DEVELOPER_USERNAME }}
PASSWORD: ${{ secrets.APPLE_DEVELOPER_PASSWORD }}
build-android:
needs: build-bump
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Get build bump
run: git pull
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache JS dependencies
uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install JS dependencies
run: yarn --frozen-lockfile
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Assemble Release Bundle
run: |
cd android
./gradlew bundleRelease
- name: Sign Release
uses: r0adkll/sign-android-release@v1
with:
releaseDirectory: android/app/build/outputs/bundle/release
signingKeyBase64: ${{ secrets.RELEASE_STORE_FILE_BASE_64 }}
alias: ${{ secrets.RELEASE_KEY_ALIAS }}
keyStorePassword: ${{ secrets.RELEASE_STORE_PASSWORD }}
keyPassword: ${{ secrets.RELEASE_KEY_PASSWORD }}
- name: Upload Source Maps to Bugsnag
run: |
APP_VERSION=$(grep "versionName" $BUILD_GRADLE | awk '{print $2}' | tr -d \''"\')
APP_VERSION_CODE=$(grep "versionCode " $BUILD_GRADLE | awk '{print $2}')
npx react-native bundle \
--platform android \
--dev false \
--entry-file index.js \
--bundle-output android-release.bundle \
--sourcemap-output android-release.bundle.map
curl --http1.1 https://upload.bugsnag.com/react-native-source-map \
-F apiKey=${{ secrets.BUGSNAG_API_KEY }} \
-F appVersion=$APP_VERSION \
-F appVersionCode=$APP_VERSION_CODE \
-F dev=false \
-F platform=android \
-F [email protected] \
-F [email protected] \
-F projectRoot=$PWD
rm android-release.bundle.map
rm android-release.bundle
env:
BUILD_GRADLE: "android/app/build.gradle"
- name: Deploy to Alpha Track
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
packageName: com.planningcenter
releaseFile: android/app/build/outputs/bundle/release/app-release.aab
track: alpha
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment