mirror of
https://github.com/Felitendo/spotifast.git
synced 2026-11-01 17:33:26 +01:00
The build itself takes 28 to 30 minutes, so saving the Nix cache afterwards ran past the 30-minute limit and marked successful builds as cancelled.
202 lines
8.0 KiB
YAML
202 lines
8.0 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
merge_group:
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
|
|
jobs:
|
|
quality:
|
|
name: quality
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: rustfmt, clippy
|
|
- name: GUI build dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y libasound2-dev libpulse-dev libxkbcommon-dev \
|
|
libwayland-dev libgl1-mesa-dev cmake libclang-dev ruby
|
|
# After the toolchain, so the cache key follows the pinned rustc. The
|
|
# key carries no job name, so each job sets its own generation. Only
|
|
# pushes to main save; a pull request restores and builds on top.
|
|
# Letting every branch save its own copy filled the repository's
|
|
# ten-gigabyte cache in a few days, and a full cache evicts the entry
|
|
# the next build wanted.
|
|
- uses: jdx/mr-boxington-action@v1
|
|
with:
|
|
cache-generation: quality-v1
|
|
- name: Formatting
|
|
run: cargo fmt --all --check
|
|
- name: Flatpak release metadata regression tests
|
|
run: python3 packaging/flatpak/test-metainfo.py
|
|
- name: Linux launcher packaging regressions
|
|
run: python3 packaging/test-launchers.py
|
|
- name: Release name migration regressions
|
|
run: python3 packaging/test-release-names.py
|
|
- name: Clippy (default features)
|
|
run: mbx clippy --locked --all-targets -- -D warnings
|
|
- name: Clippy (all features)
|
|
run: mbx clippy --locked --all-targets --all-features -- -D warnings
|
|
- name: Rustdoc
|
|
env:
|
|
RUSTDOCFLAGS: -D warnings
|
|
run: mbx doc --locked --all-features --no-deps
|
|
|
|
test:
|
|
name: test (${{ matrix.os }})
|
|
runs-on: ${{ matrix.os }}
|
|
env:
|
|
CMAKE_GENERATOR: Ninja
|
|
# A cold mbx cache on Windows (projectM through cmake) needs about 30
|
|
# minutes before the action saves the cache; warm runs take far less.
|
|
timeout-minutes: 60
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
- name: GUI build dependencies
|
|
if: runner.os == 'Linux'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y libasound2-dev libpulse-dev libxkbcommon-dev \
|
|
libwayland-dev libgl1-mesa-dev cmake libclang-dev
|
|
# libprojectM reads OpenGL through GLEW on Windows; projectm-sys builds
|
|
# against vcpkg's static-CRT triplet, matching .cargo/config.toml.
|
|
- name: GLEW for libprojectM
|
|
if: runner.os == 'Windows'
|
|
run: vcpkg install glew:x64-windows-static
|
|
# projectm-sys asks CMake for the Visual Studio generator, which the
|
|
# runner image no longer satisfies; Ninja inside the MSVC environment
|
|
# builds the same thing without caring which Visual Studio is on. The
|
|
# generator is job-level env, since a GITHUB_ENV write never reached
|
|
# the build script.
|
|
- name: MSVC environment for libprojectM
|
|
if: runner.os == 'Windows'
|
|
uses: ilammy/msvc-dev-cmd@v1
|
|
- uses: jdx/mr-boxington-action@v1
|
|
with:
|
|
cache-generation: test-v1
|
|
# The demo feature carries the headless render test that lays out every
|
|
# page, panel, and dialog without a display.
|
|
- name: Tests (default features)
|
|
run: mbx test --locked --all-targets
|
|
- name: Tests (all features)
|
|
run: mbx test --locked --all-targets --all-features
|
|
- name: Native credential store (dummy grants)
|
|
if: runner.os == 'Windows' || runner.os == 'macOS'
|
|
timeout-minutes: 2
|
|
run: mbx test --locked --lib credentials::tests::native_store_round_trip -- --ignored --exact
|
|
- name: Documentation tests
|
|
run: mbx test --locked --all-features --doc
|
|
# A build can pass while importing Microsoft's C++ runtime, then fail on
|
|
# a clean user's machine. Inspect the executable CI actually produced.
|
|
- name: Standalone Windows runtime
|
|
if: runner.os == 'Windows'
|
|
shell: pwsh
|
|
run: |
|
|
mbx build --locked
|
|
$imports = & dumpbin /dependents target\debug\spotifast.exe | Out-String
|
|
$runtime = $imports | Select-String -Pattern 'MSVCP[0-9_]*\.dll|VCRUNTIME[0-9_]*\.dll'
|
|
if ($runtime) { throw "Spotifast imports an MSVC runtime:`n$runtime" }
|
|
|
|
- name: Windows installer syntax and renamed inputs
|
|
if: runner.os == 'Windows'
|
|
shell: pwsh
|
|
run: |
|
|
$version = (cargo metadata --no-deps --format-version 1 | ConvertFrom-Json).packages[0].version
|
|
$iscc = (Get-Command iscc -ErrorAction SilentlyContinue).Source
|
|
if (-not $iscc) { $iscc = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" }
|
|
& $iscc "/DVersion=$version" /DArch=x86_64 "/DBinary=$PWD\target\debug\spotifast.exe" "/DOutputDir=$env:RUNNER_TEMP\spotifast-installer-check" packaging\windows\spotifast.iss
|
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
|
|
- name: macOS bundle identity and helper startup
|
|
if: runner.os == 'macOS'
|
|
shell: bash
|
|
run: |
|
|
mbx build --locked
|
|
version=$(cargo metadata --no-deps --format-version 1 | python3 -c 'import json,sys; print(json.load(sys.stdin)["packages"][0]["version"])')
|
|
app="$RUNNER_TEMP/spotifast-bundle-check/Spotifast.app"
|
|
bash packaging/macos/bundle.sh target/debug/spotifast "$app" "$version"
|
|
executable=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "$app/Contents/Info.plist")
|
|
"$app/Contents/MacOS/$executable" --version
|
|
# A missing job must reach our error handler, not die during launch.
|
|
set +e
|
|
"$app/Contents/MacOS/$executable" --apply-update "$RUNNER_TEMP/spotifast-missing-job.json" 2> "$RUNNER_TEMP/spotifast-helper-check.log"
|
|
status=$?
|
|
set -e
|
|
test "$status" -eq 1
|
|
test -s "$RUNNER_TEMP/spotifast-helper-check.log"
|
|
|
|
nix:
|
|
name: Nix package
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: wimpysworld/nothing-but-nix@v9
|
|
- uses: cachix/install-nix-action@v31
|
|
- uses: nix-community/cache-nix-action@v7
|
|
with:
|
|
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/flake.lock') }}
|
|
restore-prefixes-first-match: nix-${{ runner.os }}-
|
|
- name: Read the public Nix cache
|
|
if: vars.CACHIX_CACHE != ''
|
|
uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17
|
|
with:
|
|
name: ${{ vars.CACHIX_CACHE }}
|
|
skipPush: true
|
|
- run: nix build .#default
|
|
# Only a successful main push publishes. PRs and manual branch builds
|
|
# can read the public cache, but never receive its upload credential.
|
|
- name: Publish the Nix package closure
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && vars.CACHIX_CACHE != ''
|
|
shell: bash
|
|
env:
|
|
CACHIX_CACHE: ${{ vars.CACHIX_CACHE }}
|
|
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
|
|
run: |
|
|
if [ -z "$CACHIX_AUTH_TOKEN" ]; then
|
|
echo '::error::CACHIX_CACHE is configured but CACHIX_AUTH_TOKEN is missing.'
|
|
exit 1
|
|
fi
|
|
nix path-info --recursive ./result | cachix push "$CACHIX_CACHE"
|
|
|
|
docs:
|
|
name: docs
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- uses: ruby/setup-ruby@v1
|
|
with:
|
|
ruby-version: '4.0'
|
|
bundler-cache: true
|
|
working-directory: docs
|
|
|
|
- name: Build documentation site
|
|
working-directory: docs
|
|
env:
|
|
JEKYLL_ENV: production
|
|
run: |
|
|
bundle exec jekyll build --destination "$RUNNER_TEMP/spotifast-site"
|