mirror of
https://github.com/FluxaMedia/fluxa-desktop.git
synced 2026-08-05 16:28:55 +00:00
Some checks failed
Warm Windows ANGLE Cache / warm-angle-cache (push) Has been cancelled
The Windows runner's redirect target served a 200 response with a 29KB error page instead of the real ~80MB archive. download.videolan.org is VideoLan's own origin, not the geo-mirror load balancer.
611 lines
25 KiB
YAML
611 lines
25 KiB
YAML
name: Build
|
|
|
|
on:
|
|
push:
|
|
tags: ["v*"]
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
NODE_VERSION: "22"
|
|
RUST_VERSION: "stable"
|
|
LIBMPV_TAG: "v0.41.0-gpu-next.17"
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
concurrency:
|
|
group: build-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
# Created up front so the three build jobs upload into one existing draft
|
|
# instead of racing to create it.
|
|
create-release:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
steps:
|
|
- name: Create draft release for the tag
|
|
if: github.event_name == 'push'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
gh release view "${{ github.ref_name }}" -R "${{ github.repository }}" >/dev/null 2>&1 || \
|
|
gh release create "${{ github.ref_name }}" -R "${{ github.repository }}" \
|
|
--draft --title "Fluxa Desktop ${{ github.ref_name }}" --notes ""
|
|
|
|
# libmpv + its MSYS2 runtime deps come prebuilt from KhooLy/mpv.
|
|
build-windows:
|
|
needs: create-release
|
|
runs-on: windows-latest
|
|
timeout-minutes: 120
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
repository: FluxaMedia/fluxa-core
|
|
path: fluxa-core
|
|
- name: Link sibling repos
|
|
shell: bash
|
|
run: |
|
|
PARENT="$(dirname "$GITHUB_WORKSPACE")"
|
|
cmd //c mklink //J "$PARENT\\fluxa-core" "$GITHUB_WORKSPACE\\fluxa-core"
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
cache: npm
|
|
|
|
- name: Set up Rust
|
|
uses: dtolnay/rust-toolchain@master
|
|
with:
|
|
toolchain: ${{ env.RUST_VERSION }}
|
|
|
|
- name: Cache Rust build
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: src-tauri
|
|
|
|
- name: Fetch libmpv (KhooLy/mpv gpu-next fork)
|
|
shell: bash
|
|
run: ./src-tauri/fetch-libmpv.sh "$LIBMPV_TAG"
|
|
|
|
# ANGLE (libEGL.dll/libGLESv2.dll) backs mpv's OpenGL render API with a
|
|
# real D3D11 device on Windows. Without it, D3D11VA hwdec has nothing to
|
|
# attach to and decode silently falls back to software on every vendor.
|
|
# VCPKG_INSTALLATION_ROOT is C:\vcpkg on windows runners; it is a machine
|
|
# env var, not visible to ${{ env.* }} expressions, so it is hardcoded.
|
|
- name: Cache vcpkg ANGLE build
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: |
|
|
C:\vcpkg\installed
|
|
C:\vcpkg\packages
|
|
key: vcpkg-angle-x64-windows-v1
|
|
|
|
- name: Build ANGLE via vcpkg
|
|
shell: bash
|
|
run: |
|
|
"$VCPKG_INSTALLATION_ROOT/vcpkg" install angle:x64-windows
|
|
mkdir -p src-tauri/lib
|
|
cp "$VCPKG_INSTALLATION_ROOT/installed/x64-windows/bin/"*.dll src-tauri/lib/
|
|
|
|
- name: Fetch libVLC runtime
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
$version = "3.0.23"
|
|
$archive = "$env:RUNNER_TEMP/vlc-win64.zip"
|
|
Invoke-WebRequest "https://download.videolan.org/pub/videolan/vlc/$version/win64/vlc-$version-win64.zip" -OutFile $archive
|
|
$extract = "$env:RUNNER_TEMP/vlc-win64"
|
|
Expand-Archive $archive -DestinationPath $extract
|
|
$root = Get-ChildItem $extract -Directory | Select-Object -First 1
|
|
New-Item -ItemType Directory -Force src-tauri/lib/vlc | Out-Null
|
|
Copy-Item "$($root.FullName)/libvlc.dll" src-tauri/lib/vlc/
|
|
Copy-Item "$($root.FullName)/libvlccore.dll" src-tauri/lib/vlc/
|
|
Copy-Item "$($root.FullName)/plugins" src-tauri/lib/vlc/plugins -Recurse
|
|
- name: Verify bundled DLLs are present
|
|
shell: bash
|
|
run: |
|
|
ls -l src-tauri/lib/
|
|
test -f src-tauri/lib/libEGL.dll
|
|
test -f src-tauri/lib/libGLESv2.dll
|
|
test -f src-tauri/lib/z.dll
|
|
ls src-tauri/lib/*mpv*.dll >/dev/null
|
|
test -f src-tauri/lib/vlc/libvlc.dll
|
|
test -d src-tauri/lib/vlc/plugins
|
|
|
|
- name: npm install
|
|
run: npm ci
|
|
|
|
- name: Build Tauri (Windows installer)
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
FLUXA_TRAKT_CLIENT_ID: ${{ secrets.FLUXA_TRAKT_CLIENT_ID }}
|
|
FLUXA_TRAKT_CLIENT_SECRET: ${{ secrets.FLUXA_TRAKT_CLIENT_SECRET }}
|
|
FLUXA_MAL_CLIENT_ID: ${{ secrets.FLUXA_MAL_CLIENT_ID }}
|
|
FLUXA_ANILIST_CLIENT_ID: ${{ secrets.FLUXA_ANILIST_CLIENT_ID }}
|
|
FLUXA_ANILIST_CLIENT_SECRET: ${{ secrets.FLUXA_ANILIST_CLIENT_SECRET }}
|
|
FLUXA_SIMKL_CLIENT_ID: ${{ secrets.FLUXA_SIMKL_CLIENT_ID }}
|
|
FLUXA_SIMKL_CLIENT_SECRET: ${{ secrets.FLUXA_SIMKL_CLIENT_SECRET }}
|
|
FLUXA_NUVIO_SUPABASE_URL: ${{ secrets.FLUXA_NUVIO_SUPABASE_URL }}
|
|
FLUXA_NUVIO_SUPABASE_KEY: ${{ secrets.FLUXA_NUVIO_SUPABASE_KEY }}
|
|
with:
|
|
tagName: ${{ github.event_name == 'push' && github.ref_name || '' }}
|
|
releaseName: ${{ github.event_name == 'push' && format('Fluxa Desktop {0}', github.ref_name) || '' }}
|
|
releaseDraft: true
|
|
args: --target x86_64-pc-windows-msvc
|
|
|
|
- name: Upload build artifacts (manual run)
|
|
if: github.event_name != 'push'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: fluxa-windows-x64
|
|
path: |
|
|
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*
|
|
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*
|
|
if-no-files-found: error
|
|
|
|
# libmpv comes prebuilt from KhooLy/mpv, already dylibbundler'd.
|
|
build-macos:
|
|
needs: create-release
|
|
runs-on: macos-latest
|
|
timeout-minutes: 90
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
repository: FluxaMedia/fluxa-core
|
|
path: fluxa-core
|
|
- name: Link sibling repos
|
|
run: ln -sfn "$GITHUB_WORKSPACE/fluxa-core" "$(dirname "$GITHUB_WORKSPACE")/fluxa-core"
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
cache: npm
|
|
|
|
- name: Set up Rust
|
|
uses: dtolnay/rust-toolchain@master
|
|
with:
|
|
toolchain: ${{ env.RUST_VERSION }}
|
|
targets: aarch64-apple-darwin,x86_64-apple-darwin
|
|
|
|
- name: Cache Rust build
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: src-tauri
|
|
|
|
- name: Fetch libmpv (KhooLy/mpv gpu-next fork)
|
|
run: ./src-tauri/fetch-libmpv.sh "$LIBMPV_TAG"
|
|
|
|
- name: Fetch libVLC runtime
|
|
run: |
|
|
VERSION="3.0.23"
|
|
DMG="$RUNNER_TEMP/vlc-universal.dmg"
|
|
curl -fL "https://download.videolan.org/pub/videolan/vlc/$VERSION/macosx/vlc-$VERSION-universal.dmg" -o "$DMG"
|
|
MOUNT="$RUNNER_TEMP/vlc-mount"
|
|
mkdir -p "$MOUNT"
|
|
hdiutil attach "$DMG" -nobrowse -mountpoint "$MOUNT"
|
|
mkdir -p src-tauri/lib/vlc
|
|
cp -R "$MOUNT/VLC.app/Contents/MacOS/lib/." src-tauri/lib/vlc/
|
|
cp -R "$MOUNT/VLC.app/Contents/MacOS/plugins" src-tauri/lib/vlc/plugins
|
|
hdiutil detach "$MOUNT"
|
|
test -f src-tauri/lib/vlc/libvlc.dylib
|
|
test -d src-tauri/lib/vlc/plugins
|
|
- name: Verify bundled macOS libraries
|
|
run: |
|
|
find src-tauri/lib -maxdepth 1 -type f -name '*.dylib' -print
|
|
test -f src-tauri/lib/libmpv.dylib
|
|
test -f src-tauri/lib/libMoltenVK.dylib
|
|
for dylib in src-tauri/lib/*.dylib; do
|
|
architectures="$(lipo -archs "$dylib")"
|
|
echo "$dylib: $architectures"
|
|
echo "$architectures" | grep -qw arm64
|
|
echo "$architectures" | grep -qw x86_64
|
|
for architecture in arm64 x86_64; do
|
|
otool -arch "$architecture" -L "$dylib"
|
|
if otool -arch "$architecture" -L "$dylib" | tail -n +3 | grep -Eq '^[[:space:]]+(@rpath/|/opt/homebrew/|/usr/local/)'; then
|
|
echo "non-portable dependency found in $dylib ($architecture)" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
done
|
|
|
|
- name: npm install
|
|
run: npm ci
|
|
|
|
- name: Build Tauri (macOS DMG — universal binary)
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
FLUXA_TRAKT_CLIENT_ID: ${{ secrets.FLUXA_TRAKT_CLIENT_ID }}
|
|
FLUXA_TRAKT_CLIENT_SECRET: ${{ secrets.FLUXA_TRAKT_CLIENT_SECRET }}
|
|
FLUXA_MAL_CLIENT_ID: ${{ secrets.FLUXA_MAL_CLIENT_ID }}
|
|
FLUXA_ANILIST_CLIENT_ID: ${{ secrets.FLUXA_ANILIST_CLIENT_ID }}
|
|
FLUXA_ANILIST_CLIENT_SECRET: ${{ secrets.FLUXA_ANILIST_CLIENT_SECRET }}
|
|
FLUXA_SIMKL_CLIENT_ID: ${{ secrets.FLUXA_SIMKL_CLIENT_ID }}
|
|
FLUXA_SIMKL_CLIENT_SECRET: ${{ secrets.FLUXA_SIMKL_CLIENT_SECRET }}
|
|
FLUXA_NUVIO_SUPABASE_URL: ${{ secrets.FLUXA_NUVIO_SUPABASE_URL }}
|
|
FLUXA_NUVIO_SUPABASE_KEY: ${{ secrets.FLUXA_NUVIO_SUPABASE_KEY }}
|
|
with:
|
|
tagName: ${{ github.event_name == 'push' && github.ref_name || '' }}
|
|
releaseName: ${{ github.event_name == 'push' && format('Fluxa Desktop {0}', github.ref_name) || '' }}
|
|
releaseDraft: true
|
|
args: --target universal-apple-darwin
|
|
|
|
- name: Verify bundled macOS application libraries
|
|
run: |
|
|
APP="src-tauri/target/universal-apple-darwin/release/bundle/macos/Fluxa Desktop.app"
|
|
LIB_DIR="$APP/Contents/Resources/lib"
|
|
test -d "$LIB_DIR"
|
|
test -f "$LIB_DIR/libmpv.dylib"
|
|
test -f "$LIB_DIR/libMoltenVK.dylib"
|
|
for dylib in "$LIB_DIR"/*.dylib; do
|
|
architectures="$(lipo -archs "$dylib")"
|
|
echo "$dylib: $architectures"
|
|
echo "$architectures" | grep -qw arm64
|
|
echo "$architectures" | grep -qw x86_64
|
|
for architecture in arm64 x86_64; do
|
|
if otool -arch "$architecture" -L "$dylib" | tail -n +3 | grep -Eq '^[[:space:]]+(@rpath/|/opt/homebrew/|/usr/local/)'; then
|
|
echo "non-portable dependency found in $dylib ($architecture)" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
done
|
|
codesign --force --deep --sign - "$APP"
|
|
codesign --verify --deep --strict "$APP"
|
|
|
|
- name: Upload build artifacts (manual run)
|
|
if: github.event_name != 'push'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: fluxa-macos-universal
|
|
path: |
|
|
src-tauri/target/universal-apple-darwin/release/bundle/dmg/*.dmg
|
|
src-tauri/target/universal-apple-darwin/release/bundle/macos/*.tar.gz
|
|
if-no-files-found: error
|
|
|
|
# libmpv comes prebuilt from KhooLy/mpv (built on ubuntu-24.04, must match).
|
|
build-linux:
|
|
needs: create-release
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 90
|
|
outputs:
|
|
appimage_signature: ${{ steps.strip-appimage.outputs.signature }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
repository: FluxaMedia/fluxa-core
|
|
path: fluxa-core
|
|
- name: Link sibling repos
|
|
run: ln -sfn "$GITHUB_WORKSPACE/fluxa-core" "$(dirname "$GITHUB_WORKSPACE")/fluxa-core"
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
cache: npm
|
|
|
|
- name: Set up Rust
|
|
uses: dtolnay/rust-toolchain@master
|
|
with:
|
|
toolchain: ${{ env.RUST_VERSION }}
|
|
|
|
- name: Cache Rust build
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: src-tauri
|
|
|
|
# cached under $HOME, not /var/cache/apt/archives, to avoid root-owned dir
|
|
- name: Cache apt packages
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.apt-cache
|
|
key: apt-noble-v2-${{ hashFiles('.github/workflows/build.yml') }}
|
|
restore-keys: apt-noble-v2-
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
sudo sed -i 's|mirror://mirrors.ubuntu.com/mirrors.txt|http://archive.ubuntu.com/ubuntu/|; s|mirror+file:/etc/apt/apt-mirrors.txt|http://archive.ubuntu.com/ubuntu/|' /etc/apt/sources.list.d/ubuntu.sources
|
|
mkdir -p ~/.apt-cache
|
|
sudo apt-get update
|
|
sudo apt-get -o Dir::Cache::Archives="$HOME/.apt-cache" install -y \
|
|
libavcodec-dev libavformat-dev libavutil-dev \
|
|
libswscale-dev libswresample-dev libavfilter-dev \
|
|
libass9 libplacebo-dev \
|
|
pkg-config \
|
|
libwebkit2gtk-4.1-dev libgtk-3-dev \
|
|
libayatana-appindicator3-dev librsvg2-dev \
|
|
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
|
|
patchelf
|
|
sudo chown -R "$(id -u):$(id -g)" ~/.apt-cache
|
|
|
|
- name: Fetch libmpv (KhooLy/mpv gpu-next fork)
|
|
run: ./src-tauri/fetch-libmpv.sh "$LIBMPV_TAG"
|
|
|
|
- name: Bundle libVLC runtime
|
|
run: |
|
|
sudo apt-get install -y libvlc5 vlc-plugin-base vlc-plugin-access-extra vlc-plugin-video-output
|
|
VLC_LIB="/usr/lib/x86_64-linux-gnu"
|
|
mkdir -p src-tauri/lib/vlc
|
|
cp -aL "$VLC_LIB/libvlc.so.5" "$VLC_LIB/libvlccore.so.9" src-tauri/lib/vlc/
|
|
cp -aL "$VLC_LIB/vlc/plugins" src-tauri/lib/vlc/plugins
|
|
test -f src-tauri/lib/vlc/libvlc.so.5
|
|
test -d src-tauri/lib/vlc/plugins
|
|
|
|
|
|
- name: Verify libmpv.so is intact
|
|
run: |
|
|
ldd src-tauri/lib/libmpv.so.2 | grep 'not found' && exit 1 || true
|
|
echo "OK: all libmpv deps resolvable on this runner"
|
|
|
|
- name: npm install
|
|
run: npm ci
|
|
|
|
- name: Build Tauri (AppImage + deb)
|
|
uses: tauri-apps/tauri-action@v0
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
FLUXA_TRAKT_CLIENT_ID: ${{ secrets.FLUXA_TRAKT_CLIENT_ID }}
|
|
FLUXA_TRAKT_CLIENT_SECRET: ${{ secrets.FLUXA_TRAKT_CLIENT_SECRET }}
|
|
FLUXA_MAL_CLIENT_ID: ${{ secrets.FLUXA_MAL_CLIENT_ID }}
|
|
FLUXA_ANILIST_CLIENT_ID: ${{ secrets.FLUXA_ANILIST_CLIENT_ID }}
|
|
FLUXA_ANILIST_CLIENT_SECRET: ${{ secrets.FLUXA_ANILIST_CLIENT_SECRET }}
|
|
FLUXA_SIMKL_CLIENT_ID: ${{ secrets.FLUXA_SIMKL_CLIENT_ID }}
|
|
FLUXA_SIMKL_CLIENT_SECRET: ${{ secrets.FLUXA_SIMKL_CLIENT_SECRET }}
|
|
FLUXA_NUVIO_SUPABASE_URL: ${{ secrets.FLUXA_NUVIO_SUPABASE_URL }}
|
|
FLUXA_NUVIO_SUPABASE_KEY: ${{ secrets.FLUXA_NUVIO_SUPABASE_KEY }}
|
|
with:
|
|
tagName: ${{ github.event_name == 'push' && github.ref_name || '' }}
|
|
releaseName: ${{ github.event_name == 'push' && format('Fluxa Desktop {0}', github.ref_name) || '' }}
|
|
releaseDraft: true
|
|
args: --target x86_64-unknown-linux-gnu
|
|
|
|
- name: Strip bundled GTK/WebKit2GTK from the AppImage
|
|
id: strip-appimage
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
run: |
|
|
set -euo pipefail
|
|
APPIMAGE="$(realpath "$(find src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/appimage -maxdepth 1 -iname '*.AppImage' | head -n1)")"
|
|
chmod +x "$APPIMAGE"
|
|
WORKDIR="$(mktemp -d)"
|
|
(cd "$WORKDIR" && "$APPIMAGE" --appimage-extract >/dev/null)
|
|
find "$WORKDIR/squashfs-root/usr/lib" -maxdepth 1 -iname '*.so*' -delete
|
|
rm -rf "$WORKDIR/squashfs-root/usr/lib/x86_64-linux-gnu" \
|
|
"$WORKDIR/squashfs-root/usr/lib/gstreamer-1.0" \
|
|
"$WORKDIR/squashfs-root/usr/lib/gstreamer1.0"
|
|
|
|
PLUGIN="$HOME/.cache/tauri/linuxdeploy-plugin-appimage.AppImage"
|
|
if [ ! -f "$PLUGIN" ]; then
|
|
curl -fL -o "$PLUGIN" "https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage"
|
|
chmod +x "$PLUGIN"
|
|
fi
|
|
|
|
STRIPPED="$WORKDIR/$(basename "$APPIMAGE")"
|
|
OUTPUT="$STRIPPED" "$PLUGIN" --appdir="$WORKDIR/squashfs-root"
|
|
mv "$STRIPPED" "$APPIMAGE"
|
|
rm -rf "$WORKDIR"
|
|
|
|
if [ "$GITHUB_EVENT_NAME" = "push" ]; then
|
|
npm run --silent tauri signer sign -- "$APPIMAGE"
|
|
echo "signature=$(cat "$APPIMAGE.sig")" >> "$GITHUB_OUTPUT"
|
|
gh release upload "${{ github.ref_name }}" "$APPIMAGE" --clobber
|
|
fi
|
|
|
|
- name: Upload build artifacts (manual run)
|
|
if: github.event_name != 'push'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: fluxa-linux-x64
|
|
path: |
|
|
src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/appimage/*.AppImage
|
|
src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb
|
|
if-no-files-found: error
|
|
|
|
publish-release:
|
|
if: github.event_name == 'push'
|
|
needs: [build-windows, build-macos, build-linux]
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
fetch-depth: 0
|
|
fetch-tags: true
|
|
- name: Build release notes from commits
|
|
run: |
|
|
PREV_TAG="$(git describe --tags --abbrev=0 "${{ github.ref_name }}^" 2>/dev/null || true)"
|
|
RANGE="${PREV_TAG:+$PREV_TAG..}${{ github.ref_name }}"
|
|
REPO_URL="https://github.com/${{ github.repository }}"
|
|
: > notes.md
|
|
git log "$RANGE" --pretty=format:"%h%x09%s" | while IFS=$'\t' read -r hash subject; do
|
|
clean="$(sed -E 's/^[a-zA-Z]+(\([^)]*\))?: //; s/^(.)/\U\1/' <<< "$subject")"
|
|
echo "- $clean ([$hash]($REPO_URL/commit/$hash))" >> notes.md
|
|
done
|
|
- name: Update AppImage signature and changelog in latest.json
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
SIGNATURE: ${{ needs.build-linux.outputs.appimage_signature }}
|
|
run: |
|
|
set -euo pipefail
|
|
[ -n "$SIGNATURE" ]
|
|
gh release download "${{ github.ref_name }}" --repo "${{ github.repository }}" --pattern latest.json
|
|
jq --arg sig "$SIGNATURE" --rawfile notes notes.md \
|
|
'(.platforms[] | select(.url | endswith(".AppImage")) | .signature) = $sig | .notes = $notes' \
|
|
latest.json > latest.json.patched
|
|
mv latest.json.patched latest.json
|
|
gh release upload "${{ github.ref_name }}" latest.json --clobber --repo "${{ github.repository }}"
|
|
- name: Hide updater signature assets from release downloads
|
|
run: |
|
|
gh release view "${{ github.ref_name }}" --repo "${{ github.repository }}" --json assets \
|
|
--jq '.assets[].name | select(endswith(".sig"))' |
|
|
while IFS= read -r asset; do
|
|
[ -n "$asset" ] || continue
|
|
gh release delete-asset "${{ github.ref_name }}" "$asset" --yes --repo "${{ github.repository }}"
|
|
done
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
- run: gh release edit "${{ github.ref_name }}" --draft=false --notes-file notes.md --repo "${{ github.repository }}"
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
publish-linux-repos:
|
|
if: github.event_name == 'push'
|
|
needs: [publish-release]
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- name: Install repo tooling
|
|
run: sudo apt-get update && sudo apt-get install -y dpkg-dev apt-utils gnupg rpm createrepo-c
|
|
|
|
- name: Import GPG signing key
|
|
env:
|
|
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
|
|
GPG_KEY_FINGERPRINT: ${{ secrets.GPG_KEY_FINGERPRINT }}
|
|
run: |
|
|
set -euo pipefail
|
|
echo "$GPG_SIGNING_KEY" | gpg --batch --import
|
|
gpg --batch --yes --export --armor "$GPG_KEY_FINGERPRINT" > /tmp/pubkey.asc
|
|
|
|
- name: Download release packages
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
set -euo pipefail
|
|
mkdir -p /tmp/pkgs
|
|
gh release download "${{ github.ref_name }}" --repo "${{ github.repository }}" \
|
|
--pattern '*.deb' --pattern '*.rpm' --dir /tmp/pkgs
|
|
|
|
- name: Checkout gh-pages
|
|
uses: actions/checkout@v7
|
|
with:
|
|
ref: gh-pages
|
|
path: gh-pages
|
|
|
|
- name: Build APT repo
|
|
run: |
|
|
set -euo pipefail
|
|
FPR="${{ secrets.GPG_KEY_FINGERPRINT }}"
|
|
REPO="gh-pages/apt"
|
|
mkdir -p "$REPO/pool/main" "$REPO/dists/stable/main/binary-amd64"
|
|
cp /tmp/pkgs/*.deb "$REPO/pool/main/"
|
|
cp /tmp/pubkey.asc "$REPO/fluxa-archive-keyring.asc"
|
|
gpg --dearmor < /tmp/pubkey.asc > "$REPO/fluxa-archive-keyring.gpg"
|
|
|
|
cd "$REPO"
|
|
dpkg-scanpackages --arch amd64 pool > dists/stable/main/binary-amd64/Packages
|
|
gzip -9 -c dists/stable/main/binary-amd64/Packages > dists/stable/main/binary-amd64/Packages.gz
|
|
|
|
apt-ftparchive \
|
|
-o APT::FTPArchive::Release::Origin="Fluxa Desktop" \
|
|
-o APT::FTPArchive::Release::Label="Fluxa Desktop" \
|
|
-o APT::FTPArchive::Release::Suite="stable" \
|
|
-o APT::FTPArchive::Release::Codename="stable" \
|
|
-o APT::FTPArchive::Release::Architectures="amd64" \
|
|
-o APT::FTPArchive::Release::Components="main" \
|
|
release dists/stable > dists/stable/Release
|
|
|
|
gpg --batch --yes --default-key "$FPR" -abs -o dists/stable/Release.gpg dists/stable/Release
|
|
gpg --batch --yes --default-key "$FPR" --clearsign -o dists/stable/InRelease dists/stable/Release
|
|
|
|
- name: Build DNF/YUM repo
|
|
run: |
|
|
set -euo pipefail
|
|
FPR="${{ secrets.GPG_KEY_FINGERPRINT }}"
|
|
REPO="gh-pages/rpm"
|
|
mkdir -p "$REPO/x86_64"
|
|
cp /tmp/pkgs/*.rpm "$REPO/x86_64/"
|
|
cp /tmp/pubkey.asc "$REPO/RPM-GPG-KEY-fluxa"
|
|
|
|
cat > ~/.rpmmacros <<EOF
|
|
%_gpg_name $FPR
|
|
%__gpg_sign_cmd %{__gpg} gpg --batch --yes --no-armor --pinentry-mode loopback --no-secmem-warning -u "%{_gpg_name}" --sign --detach-sign --output %{__signature_filename} %{__plaintext_filename}
|
|
EOF
|
|
rpmsign --addsign "$REPO"/x86_64/*.rpm
|
|
|
|
createrepo_c "$REPO/x86_64"
|
|
gpg --batch --yes --default-key "$FPR" --detach-sign --armor -o "$REPO/x86_64/repodata/repomd.xml.asc" "$REPO/x86_64/repodata/repomd.xml"
|
|
|
|
- name: Write repo landing page
|
|
run: |
|
|
cat > gh-pages/index.html <<'EOF'
|
|
<html><body>
|
|
<h1>Fluxa Desktop package repositories</h1>
|
|
|
|
<h2>Debian / Ubuntu (apt)</h2>
|
|
<pre>
|
|
curl -fsSL https://fluxamedia.github.io/fluxa-desktop/apt/fluxa-archive-keyring.gpg | sudo tee /usr/share/keyrings/fluxa-archive-keyring.gpg > /dev/null
|
|
echo "deb [signed-by=/usr/share/keyrings/fluxa-archive-keyring.gpg] https://fluxamedia.github.io/fluxa-desktop/apt stable main" | sudo tee /etc/apt/sources.list.d/fluxa-desktop.list
|
|
sudo apt update
|
|
sudo apt install fluxa-desktop
|
|
</pre>
|
|
|
|
<h2>Fedora (dnf)</h2>
|
|
<pre>
|
|
sudo rpm --import https://fluxamedia.github.io/fluxa-desktop/rpm/RPM-GPG-KEY-fluxa
|
|
sudo tee /etc/yum.repos.d/fluxa-desktop.repo <<REPOEOF
|
|
[fluxa-desktop]
|
|
name=Fluxa Desktop
|
|
baseurl=https://fluxamedia.github.io/fluxa-desktop/rpm/x86_64
|
|
enabled=1
|
|
gpgcheck=1
|
|
gpgkey=https://fluxamedia.github.io/fluxa-desktop/rpm/RPM-GPG-KEY-fluxa
|
|
REPOEOF
|
|
sudo dnf install fluxa-desktop
|
|
</pre>
|
|
</body></html>
|
|
EOF
|
|
|
|
- name: Publish gh-pages
|
|
run: |
|
|
cd gh-pages
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add apt rpm index.html
|
|
git diff --cached --quiet && exit 0
|
|
git commit -m "chore: publish ${{ github.ref_name }} to apt/dnf repos"
|
|
git push origin gh-pages
|
|
|
|
publish-aur:
|
|
if: github.event_name == 'push'
|
|
needs: [publish-release]
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Render PKGBUILD for this release
|
|
run: |
|
|
set -euo pipefail
|
|
PKGVER="${GITHUB_REF_NAME#v}"
|
|
DEB_URL="https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/Fluxa.Desktop_${PKGVER}_amd64.deb"
|
|
curl -fL -o /tmp/fluxa.deb "$DEB_URL"
|
|
SHA256="$(sha256sum /tmp/fluxa.deb | cut -d' ' -f1)"
|
|
sed -i \
|
|
-e "s/^pkgver=.*/pkgver=${PKGVER}/" \
|
|
-e "s/^pkgrel=.*/pkgrel=1/" \
|
|
-e "s/^sha256sums=.*/sha256sums=('${SHA256}')/" \
|
|
packaging/aur/PKGBUILD
|
|
|
|
- name: Publish to AUR
|
|
uses: KSXGitHub/github-actions-deploy-aur@v3
|
|
with:
|
|
pkgname: fluxa-desktop-bin
|
|
pkgbuild: ./packaging/aur/PKGBUILD
|
|
commit_username: KhooLy
|
|
commit_email: seslikitapicinkhooly@gmail.com
|
|
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
|
commit_message: "Update to ${{ github.ref_name }}"
|