Files
guangya_flutter/.github/workflows/build.yml
T

213 lines
8.5 KiB
YAML

name: Build and Release
on:
workflow_dispatch:
inputs:
platform:
description: Build target
required: true
default: all
type: choice
options: [all, quality, android, ios, macos, windows]
push:
tags: ['*']
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: write
env:
FLUTTER_VERSION: '3.41.9'
RELEASE_TAG: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || github.sha }}
jobs:
quality:
name: Analyze and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- run: flutter pub get
- run: flutter analyze
- run: flutter test
android:
name: Android release
needs: quality
if: github.event_name != 'workflow_dispatch' || inputs.platform == 'all' || inputs.platform == 'android'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
cache: gradle
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Restore Android release keystore
shell: bash
env:
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
run: |
set -euo pipefail
test -n "$KEYSTORE_BASE64" && test -n "$KEYSTORE_PASSWORD" && test -n "$KEY_PASSWORD" && test -n "$KEY_ALIAS"
printf '%s' "$KEYSTORE_BASE64" | base64 --decode > android/app/release.jks
cat > android/key.properties <<EOF
storePassword=$KEYSTORE_PASSWORD
keyPassword=$KEY_PASSWORD
keyAlias=$KEY_ALIAS
storeFile=release.jks
EOF
- run: flutter pub get
- run: flutter build apk --release --split-per-abi
- name: Package Android arm64 APK
run: cp build/app/outputs/flutter-apk/app-arm64-v8a-release.apk guangya_flutter-${{ env.RELEASE_TAG }}-android-arm64.apk
- uses: actions/upload-artifact@v4
with:
name: android-arm64
path: guangya_flutter-*-android-arm64.apk
- name: Publish Android release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: guangya_flutter-*-android-arm64.apk
ios:
name: iOS release
needs: quality
if: github.event_name != 'workflow_dispatch' || inputs.platform == 'all' || inputs.platform == 'ios'
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Install iOS release certificate and profile
shell: bash
env:
CERTIFICATE_BASE64: ${{ secrets.IOS_CERTIFICATE_BASE64 }}
CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
PROFILE_BASE64: ${{ secrets.IOS_PROVISIONING_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }}
EXPORT_OPTIONS_BASE64: ${{ secrets.IOS_EXPORT_OPTIONS_PLIST_BASE64 }}
run: |
set -euo pipefail
test -n "$CERTIFICATE_BASE64" && test -n "$CERTIFICATE_PASSWORD" && test -n "$PROFILE_BASE64" && test -n "$KEYCHAIN_PASSWORD" && test -n "$EXPORT_OPTIONS_BASE64"
CERT_PATH="$RUNNER_TEMP/ios-release.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/ios-signing.keychain-db"
PROFILE_PATH="$RUNNER_TEMP/Guangya.mobileprovision"
printf '%s' "$CERTIFICATE_BASE64" | base64 --decode > "$CERT_PATH"
printf '%s' "$PROFILE_BASE64" | base64 --decode > "$PROFILE_PATH"
printf '%s' "$EXPORT_OPTIONS_BASE64" | base64 --decode > ios/ExportOptions.plist
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "$CERT_PATH" -P "$CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
UUID=$(security cms -D -i "$PROFILE_PATH" | plutil -extract UUID raw -)
cp "$PROFILE_PATH" ~/Library/MobileDevice/Provisioning\ Profiles/$UUID.mobileprovision
- run: flutter pub get
- run: flutter build ipa --release --export-options-plist=ios/ExportOptions.plist
- run: cp build/ios/ipa/*.ipa guangya_flutter-${{ env.RELEASE_TAG }}-ios.ipa
- uses: actions/upload-artifact@v4
with:
name: ios-ipa
path: guangya_flutter-*-ios.ipa
- name: Publish iOS release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: guangya_flutter-*-ios.ipa
macos:
name: macOS release
needs: quality
if: github.event_name != 'workflow_dispatch' || inputs.platform == 'all' || inputs.platform == 'macos'
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Install macOS Developer ID certificate
shell: bash
env:
CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE_BASE64 }}
CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
run: |
set -euo pipefail
test -n "$CERTIFICATE_BASE64" && test -n "$CERTIFICATE_PASSWORD" && test -n "$KEYCHAIN_PASSWORD"
CERT_PATH="$RUNNER_TEMP/macos-release.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/macos-signing.keychain-db"
printf '%s' "$CERTIFICATE_BASE64" | base64 --decode > "$CERT_PATH"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "$CERT_PATH" -P "$CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
- run: flutter pub get
- run: flutter build macos --release
- name: Sign and package macOS app
shell: bash
env:
SIGNING_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }}
run: |
set -euo pipefail
test -n "$SIGNING_IDENTITY"
APP=build/macos/Build/Products/Release/小黄鸭.app
test -d "$APP"
codesign --force --deep --options runtime --timestamp --sign "$SIGNING_IDENTITY" "$APP"
ditto -c -k --sequesterRsrc --keepParent "$APP" guangya_flutter-${{ env.RELEASE_TAG }}-macos.zip
- uses: actions/upload-artifact@v4
with:
name: macos-app
path: guangya_flutter-*-macos.zip
- name: Publish macOS release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: guangya_flutter-*-macos.zip
windows:
name: Windows release
needs: quality
if: github.event_name != 'workflow_dispatch' || inputs.platform == 'all' || inputs.platform == 'windows'
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- run: flutter pub get
- run: flutter build windows --release
- name: Package Windows release
shell: pwsh
run: Compress-Archive -Path build/windows/x64/runner/Release/* -DestinationPath guangya_flutter-${{ env.RELEASE_TAG }}-windows-x64.zip
- uses: actions/upload-artifact@v4
with:
name: windows-x64
path: guangya_flutter-*-windows-x64.zip
- name: Publish Windows release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: guangya_flutter-*-windows-x64.zip