Skip to content

Build and Release App #5

Build and Release App

Build and Release App #5

name: Build and Release App
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
inputs:
release_type:
description: "Release type"
required: true
default: "release"
type: choice
options:
- release
- prerelease
workflow_run:
workflows: ["Bump Version & Release"]
types:
- completed
jobs:
get-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
prerelease: ${{ steps.get_version.outputs.prerelease }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Get version
id: get_version
run: |
VERSION=$(cat pubspec.yaml | grep version: | awk '{print $2}')
VERSION="v$VERSION"
if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.release_type }}" == "prerelease" ]]; then
PRERELEASE=true
else
PRERELEASE=false
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "prerelease=$PRERELEASE" >> $GITHUB_OUTPUT
build:
needs: get-version
runs-on: ${{ matrix.os }}
strategy:
# One platform failing should not hide whether the others work.
fail-fast: false
matrix:
include:
- platform: android
os: ubuntu-latest
artifact: android
- platform: windows
os: windows-latest
artifact: windows
- platform: macos
os: macos-latest
artifact: macos-arm64
- platform: macos
os: macos-26-intel
artifact: macos-x64
- platform: linux
os: ubuntu-latest
artifact: linux-amd64
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: 3.47.0
# Flutter's Linux build needs the GTK toolchain, which the runner image
# does not carry by default.
- name: Install Linux build dependencies
if: matrix.platform == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev
- name: Install dependencies
run: flutter pub get
- name: Build Android
if: matrix.platform == 'android'
run: >-
flutter build apk --release
--dart-define=ADMINCRAFT_GOOGLE_WEB_CLIENT_ID=${{ vars.ADMINCRAFT_GOOGLE_WEB_CLIENT_ID }}
- name: Build Windows
if: matrix.platform == 'windows'
run: >-
flutter build windows --release
--dart-define=ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_ID=${{ vars.ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_ID }}
--dart-define=ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_SECRET=${{ secrets.ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_SECRET }}
- name: Build macOS
if: matrix.platform == 'macos'
run: >-
flutter build macos --release
--dart-define=ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_ID=${{ vars.ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_ID }}
--dart-define=ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_SECRET=${{ secrets.ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_SECRET }}
- name: Build Linux
if: matrix.platform == 'linux'
run: >-
flutter build linux --release
--dart-define=ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_ID=${{ vars.ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_ID }}
--dart-define=ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_SECRET=${{ secrets.ADMINCRAFT_GOOGLE_DESKTOP_CLIENT_SECRET }}
- name: Package Android
if: matrix.platform == 'android'
shell: bash
run: |
mkdir -p dist
mv build/app/outputs/flutter-apk/app-release.apk "dist/admincraft-${VERSION}-android.apk"
env:
VERSION: ${{ needs.get-version.outputs.version }}
# Portable zip plus an Inno Setup installer, so the download page offers
# the same pair as every other desktop platform.
- name: Package Windows
if: matrix.platform == 'windows'
shell: bash
run: |
mkdir -p dist
DIST="$PWD/dist"
RELEASE_DIR="$PWD/build/windows/x64/runner/Release"
( cd "$RELEASE_DIR" && 7z a -tzip "$DIST/admincraft-${VERSION}-windows-portable.zip" ./* )
# Inno Setup ships on the runner image, but the path has moved between
# image versions, so look for it before falling back to installing it.
ISCC=""
for candidate in "/c/Program Files (x86)/Inno Setup 6/ISCC.exe" "/c/Program Files/Inno Setup 6/ISCC.exe"; do
[ -x "$candidate" ] && ISCC="$candidate" && break
done
if [ -z "$ISCC" ]; then
choco install innosetup -y --no-progress
ISCC="/c/Program Files (x86)/Inno Setup 6/ISCC.exe"
fi
echo "Using $ISCC"
"$ISCC" "//DAppVersion=${VERSION#v}" "//DSourceDir=${RELEASE_DIR}" "//DOutputDir=${DIST}" windows/packaging/admincraft.iss
mv dist/admincraft-setup.exe "dist/admincraft-${VERSION}-windows-installer.exe"
env:
VERSION: ${{ needs.get-version.outputs.version }}
# Unsigned: without an Apple Developer certificate Gatekeeper asks the user
# to allow the app on first launch. Signing would need a MAC_CSC_LINK
# secret and an Apple Developer account.
- name: Package macOS
if: matrix.platform == 'macos'
shell: bash
run: |
mkdir -p dist
APP=build/macos/Build/Products/Release/admincraft.app
BASE="dist/admincraft-${VERSION}-${{ matrix.artifact }}"
ditto -c -k --keepParent "$APP" "${BASE}-portable.zip"
hdiutil create -volname Admincraft -srcfolder "$APP" -ov -format UDZO "${BASE}-installer.dmg"
env:
VERSION: ${{ needs.get-version.outputs.version }}
- name: Package Linux
if: matrix.platform == 'linux'
shell: bash
run: |
linux/packaging/build-packages.sh "$VERSION" build/linux/x64/release/bundle dist
env:
VERSION: ${{ needs.get-version.outputs.version }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: admincraft-${{ needs.get-version.outputs.version }}-${{ matrix.artifact }}
path: dist/*
if-no-files-found: error
release:
needs: [get-version, build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
# Collected by pattern rather than one step per platform, so adding a
# platform to the matrix above needs no change here.
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
pattern: admincraft-${{ needs.get-version.outputs.version }}-*
path: dist
merge-multiple: true
- name: List collected files
run: ls -lh dist
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ needs.get-version.outputs.version }}
name: Release ${{ needs.get-version.outputs.version }}
prerelease: ${{ needs.get-version.outputs.prerelease }}
generate_release_notes: true
files: dist/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Delete build artifacts from GitHub
uses: geekyeggo/delete-artifact@v5
with:
name: admincraft-${{ needs.get-version.outputs.version }}-*