frosty/.github/workflows/gh-release.yml

152 lines
5.5 KiB
YAML

# Drafts a GitHub release with the signed release APK attached.
name: Draft GitHub release
on:
workflow_dispatch:
inputs:
tag:
description: Release tag to publish, such as glacier-v5.0.5
required: true
push:
tags:
- glacier-v*.*.*
permissions:
contents: write
jobs:
android:
name: Draft release and attach APK
runs-on: ubuntu-latest
environment: release-android
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
CLIENT_ID: ${{ secrets.CLIENT_ID }}
SECRET: ${{ secrets.SECRET }}
CAST_RECEIVER_APP_ID: ${{ secrets.CAST_RECEIVER_APP_ID }}
UPLOAD_KEYSTORE: ${{ secrets.UPLOAD_KEYSTORE }}
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: recursive
- name: Set up Java
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.44.1'
channel: stable
cache: true
- name: Validate release version
id: release_info
shell: bash
run: |
if ! [[ "$RELEASE_TAG" =~ ^glacier-v[0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)?$ ]]; then
echo "::error::Release tag must look like glacier-v5.0.5 or glacier-v5.0.5+1, got $RELEASE_TAG"
exit 1
fi
VERSION_WITH_PREFIX="${RELEASE_TAG#glacier-}"
APP_VERSION="${VERSION_WITH_PREFIX#v}"
BASE_VERSION="${APP_VERSION%%+*}"
PUBSPEC_VERSION=$(grep '^version:' pubspec.yaml | awk '{print $2}' | cut -d+ -f1)
APK_NAME="glacier-android-${VERSION_WITH_PREFIX}.apk"
if [ "$PUBSPEC_VERSION" != "$BASE_VERSION" ]; then
echo "::error::Tag $RELEASE_TAG does not match pubspec.yaml version $PUBSPEC_VERSION"
exit 1
fi
echo "version=$VERSION_WITH_PREFIX" >> "$GITHUB_OUTPUT"
echo "base_version=$BASE_VERSION" >> "$GITHUB_OUTPUT"
echo "apk_name=$APK_NAME" >> "$GITHUB_OUTPUT"
- name: Verify required secrets
shell: bash
run: |
missing=0
for name in CLIENT_ID SECRET CAST_RECEIVER_APP_ID UPLOAD_KEYSTORE STORE_PASSWORD KEY_PASSWORD; do
if [ -z "${!name}" ]; then
echo "::error::$name secret is not set"
missing=1
fi
done
exit "$missing"
- name: Decode upload keystore
shell: bash
run: |
printf '%s' "$UPLOAD_KEYSTORE" | base64 --decode > android/upload-keystore.jks
- name: Create key.properties
shell: bash
run: |
printf 'storePassword=%s\nkeyPassword=%s\nkeyAlias=upload\nstoreFile=%s\n' "$STORE_PASSWORD" "$KEY_PASSWORD" "$GITHUB_WORKSPACE/android/upload-keystore.jks" > android/key.properties
- name: Install dependencies
run: flutter pub get
- name: Build release APK
shell: bash
run: |
flutter build apk --release --dart-define=CLIENT_ID="$CLIENT_ID" --dart-define=SECRET="$SECRET" --dart-define=CAST_RECEIVER_APP_ID="$CAST_RECEIVER_APP_ID"
mv build/app/outputs/flutter-apk/app-release.apk "${{ steps.release_info.outputs.apk_name }}"
- name: Extract release notes
id: release_notes
shell: bash
run: |
VERSION="$RELEASE_TAG"
RELEASE_NOTES_VERSION="v${{ steps.release_info.outputs.base_version }}"
RELEASE_NOTES_FILE="assets/release-notes.md"
NOTES=$(awk -v version="$RELEASE_NOTES_VERSION" '
BEGIN { found=0; output="" }
$0 ~ "^## " version "$" { found=1; next }
found && /^[A-Z][a-z]+ [0-9]+, [0-9]+$/ { next }
found && /^---$/ { exit }
found && /^## v[0-9]+\.[0-9]+\.[0-9]+$/ { exit }
found { output = output $0 "\n" }
END { print output }
' "$RELEASE_NOTES_FILE")
NOTES=$(echo "$NOTES" | sed 's/ on GitHub)/)/')
NOTES=$(echo "$NOTES" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
if [ -n "$NOTES" ]; then
PREV_TAG=$(git describe --tags --match 'glacier-v*' --abbrev=0 "$VERSION^" 2>/dev/null || echo "")
echo "found=true" >> "$GITHUB_OUTPUT"
echo "body<<EOF_RELEASE_NOTES" >> "$GITHUB_OUTPUT"
echo "$NOTES" >> "$GITHUB_OUTPUT"
if [ -n "$PREV_TAG" ]; then
echo "" >> "$GITHUB_OUTPUT"
echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${VERSION}" >> "$GITHUB_OUTPUT"
fi
echo "EOF_RELEASE_NOTES" >> "$GITHUB_OUTPUT"
else
echo "found=false" >> "$GITHUB_OUTPUT"
echo "::warning::No release notes found for $VERSION in $RELEASE_NOTES_FILE"
fi
- name: Create draft release
uses: softprops/action-gh-release@v3
with:
draft: true
tag_name: ${{ env.RELEASE_TAG }}
name: Glacier ${{ steps.release_info.outputs.version }}
generate_release_notes: ${{ steps.release_notes.outputs.found != 'true' }}
body: ${{ steps.release_notes.outputs.found == 'true' && steps.release_notes.outputs.body || '' }}
files: ${{ steps.release_info.outputs.apk_name }}