231 lines
8.2 KiB
YAML
231 lines
8.2 KiB
YAML
name: 'Flutter Build Linux'
|
|
description: 'Installs GTK3/Linux build dependencies, builds Linux Flutter desktop apps, packages .tar.gz and .deb installers, and generates release metadata.'
|
|
inputs:
|
|
working_directory:
|
|
description: 'Path to the Flutter app package directory (e.g., packages/sfw_desktop)'
|
|
required: false
|
|
default: '.'
|
|
arch:
|
|
description: 'Target Linux architecture (amd64 / x64 or arm64)'
|
|
required: false
|
|
default: 'amd64'
|
|
build_args:
|
|
description: 'Extra arguments passed to flutter build linux (e.g., --dart-define=...)'
|
|
required: false
|
|
default: ''
|
|
install_deps:
|
|
description: 'Install Linux GTK3 & CMake build dependencies via apt-get'
|
|
required: false
|
|
default: 'true'
|
|
auto_create_linux_runner:
|
|
description: 'Automatically run flutter create --platforms=linux . if linux/ directory is missing'
|
|
required: false
|
|
default: 'true'
|
|
output_dir:
|
|
description: 'Output directory for packaged .deb and .tar.gz archives'
|
|
required: false
|
|
default: 'dist'
|
|
package_script:
|
|
description: 'Optional custom packaging script in repository (e.g., scripts/package_linux.sh)'
|
|
required: false
|
|
default: 'scripts/package_linux.sh'
|
|
app_name:
|
|
description: 'Application display name for .desktop entry (used if package_script is not present)'
|
|
required: false
|
|
default: 'Slides for Worship'
|
|
package_name:
|
|
description: 'Debian package slug (e.g., slides-for-worship)'
|
|
required: false
|
|
default: 'slides-for-worship'
|
|
binary_name:
|
|
description: 'Compiled Linux executable name inside bundle (auto-detected if empty)'
|
|
required: false
|
|
default: ''
|
|
icon_path:
|
|
description: 'Path to app icon PNG relative to working_directory'
|
|
required: false
|
|
default: 'assets/icon.png'
|
|
maintainer:
|
|
description: 'Debian package maintainer string'
|
|
required: false
|
|
default: 'Rody Davis <rody.davis.jr@gmail.com>'
|
|
description:
|
|
description: 'Debian package description'
|
|
required: false
|
|
default: 'Professional worship slide production and presentation studio.'
|
|
generate_metadata_json:
|
|
description: 'Whether to generate linux_<arch>_metadata.json'
|
|
required: false
|
|
default: 'false'
|
|
|
|
outputs:
|
|
version:
|
|
description: 'Resolved package version from pubspec.yaml'
|
|
value: ${{ steps.build.outputs.version }}
|
|
deb_path:
|
|
description: 'Path to generated .deb package'
|
|
value: ${{ steps.package.outputs.deb_path }}
|
|
tar_path:
|
|
description: 'Path to generated .tar.gz archive'
|
|
value: ${{ steps.package.outputs.tar_path }}
|
|
metadata_path:
|
|
description: 'Path to generated linux_<arch>_metadata.json'
|
|
value: ${{ steps.package.outputs.metadata_path }}
|
|
|
|
runs:
|
|
using: 'composite'
|
|
steps:
|
|
- name: Install Linux Build Dependencies
|
|
if: inputs.install_deps == 'true' && runner.os == 'Linux'
|
|
shell: bash
|
|
run: |
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
SUDO=""
|
|
if [ "$(id -u)" -ne 0 ] && command -v sudo >/dev/null 2>&1; then
|
|
SUDO="sudo"
|
|
fi
|
|
$SUDO apt-get update
|
|
$SUDO apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev dpkg-dev
|
|
fi
|
|
|
|
- name: Build Linux Release
|
|
id: build
|
|
shell: bash
|
|
env:
|
|
WORK_DIR: ${{ inputs.working_directory }}
|
|
ARCH: ${{ inputs.arch }}
|
|
BUILD_ARGS: ${{ inputs.build_args }}
|
|
AUTO_CREATE: ${{ inputs.auto_create_linux_runner }}
|
|
run: |
|
|
ROOT_DIR="$(pwd)"
|
|
VERSION=$(grep '^version: ' "$WORK_DIR/pubspec.yaml" | head -n 1 | cut -d ' ' -f 2 | tr -d '\r')
|
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
|
|
cd "$WORK_DIR"
|
|
flutter config --enable-linux-desktop
|
|
|
|
if [ ! -d "linux" ] && [ "$AUTO_CREATE" = "true" ]; then
|
|
echo "Notice: '$WORK_DIR/linux' directory not found. Scaffolding Linux runner via 'flutter create --platforms=linux .'..."
|
|
flutter create --platforms=linux .
|
|
fi
|
|
|
|
if [ "$ARCH" = "arm64" ] || [ "$ARCH" = "aarch64" ]; then
|
|
# shellcheck disable=SC2086
|
|
flutter build linux --release --target-platform=linux-arm64 $BUILD_ARGS
|
|
else
|
|
# shellcheck disable=SC2086
|
|
flutter build linux --release $BUILD_ARGS
|
|
fi
|
|
cd "$ROOT_DIR"
|
|
|
|
- name: Package Linux Installers (.deb & .tar.gz) & Metadata
|
|
id: package
|
|
shell: bash
|
|
env:
|
|
WORK_DIR: ${{ inputs.working_directory }}
|
|
ARCH_INPUT: ${{ inputs.arch }}
|
|
OUT_DIR: ${{ inputs.output_dir }}
|
|
PKG_SCRIPT: ${{ inputs.package_script }}
|
|
APP_NAME: ${{ inputs.app_name }}
|
|
PKG_NAME: ${{ inputs.package_name }}
|
|
BIN_NAME: ${{ inputs.binary_name }}
|
|
ICON_REL: ${{ inputs.icon_path }}
|
|
MAINTAINER: ${{ inputs.maintainer }}
|
|
DESC: ${{ inputs.description }}
|
|
VERSION: ${{ steps.build.outputs.version }}
|
|
GEN_META: ${{ inputs.generate_metadata_json }}
|
|
run: |
|
|
ROOT_DIR="$(pwd)"
|
|
if [ "$ARCH_INPUT" = "arm64" ] || [ "$ARCH_INPUT" = "aarch64" ]; then
|
|
DEB_ARCH="arm64"
|
|
BUNDLE_DIR="$WORK_DIR/build/linux/arm64/release/bundle"
|
|
else
|
|
DEB_ARCH="amd64"
|
|
BUNDLE_DIR="$WORK_DIR/build/linux/x64/release/bundle"
|
|
fi
|
|
|
|
mkdir -p "$OUT_DIR"
|
|
|
|
if [ -n "$PKG_SCRIPT" ] && [ -f "$PKG_SCRIPT" ]; then
|
|
echo "Running repository packaging script: $PKG_SCRIPT..."
|
|
bash "$PKG_SCRIPT" "$VERSION" "$DEB_ARCH" "$BUNDLE_DIR"
|
|
else
|
|
echo "Packaging .tar.gz and .deb directly..."
|
|
TAR_NAME="${PKG_NAME}-linux-${DEB_ARCH}.tar.gz"
|
|
tar -czf "$OUT_DIR/$TAR_NAME" -C "$BUNDLE_DIR" .
|
|
|
|
DEB_DIR="$WORK_DIR/build/deb_pkg_${DEB_ARCH}"
|
|
rm -rf "$DEB_DIR"
|
|
mkdir -p "$DEB_DIR/DEBIAN"
|
|
mkdir -p "$DEB_DIR/usr/bin"
|
|
mkdir -p "$DEB_DIR/usr/share/${PKG_NAME}"
|
|
mkdir -p "$DEB_DIR/usr/share/applications"
|
|
mkdir -p "$DEB_DIR/usr/share/icons/hicolor/512x512/apps"
|
|
|
|
cp -r "$BUNDLE_DIR"/* "$DEB_DIR/usr/share/${PKG_NAME}/"
|
|
|
|
if [ -z "$BIN_NAME" ]; then
|
|
BIN_NAME=$(grep '^name: ' "$WORK_DIR/pubspec.yaml" | head -n 1 | cut -d ' ' -f 2 | tr -d '\r')
|
|
fi
|
|
ln -sf "/usr/share/${PKG_NAME}/${BIN_NAME}" "$DEB_DIR/usr/bin/${PKG_NAME}"
|
|
|
|
if [ -f "$WORK_DIR/$ICON_REL" ]; then
|
|
cp "$WORK_DIR/$ICON_REL" "$DEB_DIR/usr/share/icons/hicolor/512x512/apps/${PKG_NAME}.png"
|
|
fi
|
|
|
|
cat <<EOF > "$DEB_DIR/usr/share/applications/${PKG_NAME}.desktop"
|
|
[Desktop Entry]
|
|
Name=$APP_NAME
|
|
Comment=$DESC
|
|
Exec=/usr/bin/$PKG_NAME
|
|
Icon=$PKG_NAME
|
|
Terminal=false
|
|
Type=Application
|
|
Categories=AudioVideo;Presentation;Utility;
|
|
EOF
|
|
|
|
CLEAN_VERSION=$(echo "$VERSION" | cut -d'+' -f1)
|
|
cat <<EOF > "$DEB_DIR/DEBIAN/control"
|
|
Package: $PKG_NAME
|
|
Version: $CLEAN_VERSION
|
|
Section: utils
|
|
Priority: optional
|
|
Architecture: $DEB_ARCH
|
|
Maintainer: $MAINTAINER
|
|
Description: $APP_NAME
|
|
$DESC
|
|
EOF
|
|
|
|
dpkg-deb --build "$DEB_DIR" "$OUT_DIR/${PKG_NAME}-linux-${DEB_ARCH}.deb"
|
|
fi
|
|
|
|
DEB_FILE=$(find "$OUT_DIR" -name "*-linux-${DEB_ARCH}.deb" 2>/dev/null | head -n 1 || true)
|
|
TAR_FILE=$(find "$OUT_DIR" -name "*-linux-${DEB_ARCH}.tar.gz" 2>/dev/null | head -n 1 || true)
|
|
echo "deb_path=$DEB_FILE" >> "$GITHUB_OUTPUT"
|
|
echo "tar_path=$TAR_FILE" >> "$GITHUB_OUTPUT"
|
|
|
|
if [ "$GEN_META" = "true" ]; then
|
|
PRIMARY_FILE="${DEB_FILE:-$TAR_FILE}"
|
|
SIZE="0"
|
|
FILENAME="${PKG_NAME}-linux-${DEB_ARCH}.deb"
|
|
if [ -n "$PRIMARY_FILE" ] && [ -f "$PRIMARY_FILE" ]; then
|
|
SIZE=$(stat -c%s "$PRIMARY_FILE" 2>/dev/null || stat -f%z "$PRIMARY_FILE" 2>/dev/null || echo "0")
|
|
FILENAME=$(basename "$PRIMARY_FILE")
|
|
fi
|
|
|
|
META_FILE="linux_${DEB_ARCH}_metadata.json"
|
|
cat <<EOF > "$META_FILE"
|
|
{
|
|
"version": "$VERSION",
|
|
"platform": "linux",
|
|
"arch": "$DEB_ARCH",
|
|
"filename": "$FILENAME",
|
|
"size": $SIZE,
|
|
"signature": "",
|
|
"signatureType": "none"
|
|
}
|
|
EOF
|
|
cat "$META_FILE"
|
|
echo "metadata_path=$META_FILE" >> "$GITHUB_OUTPUT"
|
|
fi
|