Skip to content

Ci

Ci #100

Workflow file for this run

name: Flutter CI
env:
TZ: Asia/Taipei
SIGN_ON_PUSH_ANDROID: 'true'
SIGN_ON_PUSH_IOS: 'false'
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
workflow_dispatch:
inputs:
platform:
description: 'Which platform to build?'
required: true
default: 'both'
type: choice
options:
- android
- ios
- both
use_signing:
description: 'Attempt to code sign? (Requires secrets to be set)'
required: true
default: 'false'
type: choice
options:
- 'true'
- 'false'
jobs:
build-android:
name: Build Flutter (Android)
if: github.event_name != 'workflow_dispatch' || (inputs.platform == 'android' || inputs.platform == 'both')
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: '0'
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.x'
channel: 'stable'
cache: true
- name: Generate build timestamp
run: echo "BUILD_TIMESTAMP=$(date +'%Y%m%d-%H%M')" >> $GITHUB_ENV
- name: Install dependencies
run: flutter pub get
- name: update build numbers
run: |
dart ./scripts/update_version.dart --ci
- name: Get App Version
run: |
VERSION=$(grep '^version:' pubspec.yaml | cut -d ' ' -f 2)
BASE_VERSION=$(echo $VERSION | cut -d '+' -f 1)
BUILD_NUMBER=$(echo $VERSION | cut -d '+' -f 2)
echo "RELEASE_NAME=$BASE_VERSION ($BUILD_NUMBER)" >> $GITHUB_ENV
- name: Set Android Signing Flag
run: |
if [[ "${{ secrets.ANDROID_SIGNING_KEY_BASE64 }}" != "" && ( ("${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.use_signing }}" == "true") || ("${{ github.event_name }}" != "workflow_dispatch" && "${{ env.SIGN_ON_PUSH_ANDROID }}" == "true") ) ]]; then
echo "SHOULD_SIGN_ANDROID=true" >> $GITHUB_ENV
else
echo "SHOULD_SIGN_ANDROID=false" >> $GITHUB_ENV
fi
- name: Decode Android Keystore
if: env.SHOULD_SIGN_ANDROID == 'true'
run: |
echo "${{ secrets.ANDROID_SIGNING_KEY_BASE64 }}" | base64 --decode > android/app/upload-keystore.jks
- name: Create key.properties
if: env.SHOULD_SIGN_ANDROID == 'true'
run: |
echo "storeFile=upload-keystore.jks" > android/key.properties
echo "storePassword=${{ secrets.ANDROID_SIGNING_STORE_PASSWORD }}" >> android/key.properties
echo "keyAlias=${{ secrets.ANDROID_SIGNING_KEY_ALIAS }}" >> android/key.properties
echo "keyPassword=${{ secrets.ANDROID_SIGNING_KEY_PASSWORD }}" >> android/key.properties
- name: Build Android Appbundle
if: env.SHOULD_SIGN_ANDROID == 'true'
run: flutter build appbundle --release
- name: Deploy to Closed Beta
continue-on-error: true
if: env.SHOULD_SIGN_ANDROID == 'true'
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_API_KEY_JSON }}
packageName: club.ntut.npc.tat2
releaseFiles: build/app/outputs/bundle/release/app-release.aab
track: internal
releaseName: ${{ env.RELEASE_NAME }}
- name: Build Android APK
run: flutter build apk --debug
- name: Upload APK Artifact
uses: actions/upload-artifact@v4
with:
name: release-apk-${{ env.RELEASE_NAME }}-${{ env.BUILD_TIMESTAMP }}
path: build/app/outputs/flutter-apk/app-debug.apk
# - name: Create Pre-release and Upload Assets
# uses: softprops/action-gh-release@v1
# with:
# tag_name: "pre-release-${{ github.sha }}"
# name: "Pre-release ${{ github.sha }}"
# body: "Automated pre-release for commit ${{ github.sha }}"
# prerelease: true
# files: |
# build/app/outputs/flutter-apk/debug.apk
# env:
# GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
build-ios:
name: Build Flutter (iOS)
if: github.event_name != 'workflow_dispatch' || (inputs.platform == 'ios' || inputs.platform == 'both')
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.x'
channel: 'stable'
cache: true
- name: Generate build timestamp
run: echo "BUILD_TIMESTAMP=$(date +'%Y%m%d-%H%M')" >> $GITHUB_ENV
- name: Install dependencies
run: flutter pub get
- name: update build numbers
run: |
dart ./scripts/update_version.dart --ci
- name: Get App Version
run: |
VERSION=$(grep '^version:' pubspec.yaml | cut -d ' ' -f 2)
BASE_VERSION=$(echo $VERSION | cut -d '+' -f 1)
BUILD_NUMBER=$(echo $VERSION | cut -d '+' -f 2)
echo "RELEASE_NAME=$BASE_VERSION ($BUILD_NUMBER)" >> $GITHUB_ENV
# Updating pod files
- name: Pod file update
run: |
cd ios
pod repo update
rm -f Podfile.lock
pod install
cd ..
- name: Set iOS Signing Flag
run: |
if [[ "${{ secrets.IOS_BUILD_CERTIFICATE_BASE64 }}" != "" && ( ("${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.use_signing }}" == "true") || ("${{ github.event_name }}" != "workflow_dispatch" && "${{ env.SIGN_ON_PUSH_IOS }}" == "true") ) ]]; then
echo "SHOULD_SIGN_IOS=true" >> $GITHUB_ENV
else
echo "SHOULD_SIGN_IOS=false" >> $GITHUB_ENV
fi
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.IOS_BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.IOS_P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.IOS_BUILD_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.IOS_GITHUB_KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: Build iOS IPA
if: env.SHOULD_SIGN_IOS == 'false'
run: flutter build ipa --release --no-codesign
- name: Build iOS IPA (Code Sign)
if: env.SHOULD_SIGN_IOS == 'true'
run: flutter build ipa --release --export-options-plist=ios/ExportOptions.plist
# IPA file detection.
- name: Detect path for ipa file
if: env.SHOULD_SIGN_IOS == 'true'
run: |
echo "IPA_PATH=$(find build/ios/ipa -type f -name '*.ipa')" >> $GITHUB_ENV
- name: 'Upload app to TestFlight'
uses: apple-actions/upload-testflight-build@v3
with:
app-path: '${{ env.IPA_PATH }}'
issuer-id: ${{ secrets.IOS_APPSTORE_API_ISSUER_ID}}
api-key-id: ${{ secrets.IOS_APPSTORE_API_KEY_ID }}
api-private-key: ${{ secrets.IOS_APPSTORE_API_PRIVATE_KEY }}
- name: Upload IPA Artifact
if: env.SHOULD_SIGN_IOS == 'true'
uses: actions/upload-artifact@v4
with:
name: release-ipa--${{ env.RELEASE_NAME }}-${{ env.BUILD_TIMESTAMP }}
path: build/ios/ipa/*.ipa