ci: delegate FreeBSD workflow, add nix check, and remove flatpak-pages

This commit is contained in:
Dylan M. Taylor
2026-10-15 20:47:20 -04:00
parent 82ee02aac4
commit e91e7f7a68
3 changed files with 46 additions and 259 deletions
-178
View File
@@ -1,178 +0,0 @@
name: Publish Flatpak repository to Pages
on:
release:
types: [published]
workflow_dispatch:
inputs:
release_tag:
description: "Published GitHub release tag to publish (for example, v1.2.3)"
required: true
type: string
permissions:
contents: read
concurrency:
group: flatpak-pages-${{ github.repository }}
cancel-in-progress: false
jobs:
build:
timeout-minutes: 60
name: Build Flatpak repository
# Pre-releases (rc builds) never reach the stable branch: a published pre-release is skipped
# here, and the validation step below refuses a manual tag with a pre-release suffix.
if: github.event_name != 'release' || !github.event.release.prerelease
runs-on: ubuntu-24.04
permissions:
contents: read
# configure-pages only reads the Pages configuration (base_url); deploy needs write.
pages: read
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.release_tag }}
APP_ID: ai.storyteller.gridcraft
steps:
- name: Configure Pages
id: pages
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
- name: Install Flatpak repository tools
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends flatpak ostree
- name: Download and validate release bundles
shell: bash
run: |
set -euo pipefail
tag="$RELEASE_TAG"
if ! printf '%s' "$tag" | grep -Eq '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*))?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$'; then
echo "::error::Release tag '$tag' is not strict SemVer prefixed with v"
exit 1
fi
# A pre-release has a "-" before any "+build" metadata (v1.2.3-rc.1).
case "${tag%%+*}" in
*-*)
echo "::error::$tag is a pre-release; only stable releases are published to the Flatpak repository"
exit 1
;;
esac
published_tag="$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/$tag" --jq \
'select(.draft == false and .prerelease == false and .published_at != null) | .tag_name')"
if [[ "$published_tag" != "$tag" ]]; then
echo "::error::$tag is not a published stable (non-pre-release) release in $GITHUB_REPOSITORY"
exit 1
fi
version="${tag#v}"
mkdir -p bundles
gh release download "$tag" --repo "$GITHUB_REPOSITORY" \
--pattern SHA256SUMS.txt --dir bundles
for arch in x86_64 aarch64; do
asset="gridcraft-$version-linux-$arch.flatpak"
gh release download "$tag" --repo "$GITHUB_REPOSITORY" \
--pattern "$asset" --dir bundles
test -s "bundles/$asset"
(
cd bundles
awk -v file="$asset" '$2 == file || $2 == "*" file { print; found=1 } END { exit !found }' \
SHA256SUMS.txt | sha256sum --check -
)
done
test "$(find bundles -maxdepth 1 -type f -name '*.flatpak' | wc -l)" -eq 2
for arch in x86_64 aarch64; do
asset="bundles/gridcraft-$version-linux-$arch.flatpak"
validation_repo="$(mktemp -d)"
ostree --repo="$validation_repo" init --mode=archive-z2
flatpak build-import-bundle "$validation_repo" "$asset"
expected_ref="app/$APP_ID/$arch/stable"
ostree --repo="$validation_repo" refs | grep -Fxq "$expected_ref" || {
echo "::error::$(basename "$asset") does not contain $expected_ref"
exit 1
}
rm -rf "$validation_repo"
done
- name: Build repository and site
shell: bash
env:
PAGES_BASE_URL: ${{ steps.pages.outputs.base_url }}
run: |
set -euo pipefail
site="$RUNNER_TEMP/site"
repo_dir="$site/flatpak/repo"
mkdir -p "$repo_dir"
ostree --repo="$repo_dir" init --mode=archive-z2
previous_url="${PAGES_BASE_URL%/}/flatpak/repo"
if curl --fail --silent --show-error --location \
--output /dev/null "$previous_url/summary"; then
ostree --repo="$repo_dir" remote add --no-gpg-verify previous "$previous_url"
ostree --repo="$repo_dir" pull --mirror previous
ostree --repo="$repo_dir" remote delete previous
fi
version="${RELEASE_TAG#v}"
for arch in x86_64 aarch64; do
flatpak build-import-bundle "$repo_dir" \
"bundles/gridcraft-$version-linux-$arch.flatpak"
done
# Prune unreachable objects and keep at most 3 commits per ref, so the Pages repository
# (re-mirrored and re-deployed on every release) does not grow without bound.
flatpak build-update-repo \
--prune --prune-depth=3 \
--title="GridCraft" \
--comment='Official GridCraft releases' \
--description='Official Flatpak repository for GridCraft' \
--homepage="https://github.com/$GITHUB_REPOSITORY" \
--default-branch=stable \
"$repo_dir"
for arch in x86_64 aarch64; do
ostree --repo="$repo_dir" rev-parse "app/$APP_ID/$arch/stable" >/dev/null
done
test -s "$repo_dir/summary"
base_url="${PAGES_BASE_URL%/}"
repo_url="$base_url/flatpak/repo/"
cat >"$site/flatpak/gridcraft.flatpakrepo" <<META
[Flatpak Repo]
Title=GridCraft
Comment=Official GridCraft releases
Description=Official Flatpak repository for GridCraft
Url=$repo_url
Homepage=https://github.com/$GITHUB_REPOSITORY
META
cat >"$site/flatpak/index.html" <<HTML
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>GridCraft Flatpak repository</title></head><body><main><h1>GridCraft Flatpak repository</h1><p>Latest published release: <strong>$RELEASE_TAG</strong></p><p><a href="gridcraft.flatpakrepo">Add the GridCraft repository</a></p><pre>flatpak remote-add --if-not-exists gridcraft $base_url/flatpak/gridcraft.flatpakrepo
flatpak install gridcraft $APP_ID</pre></main></body></html>
HTML
cat >"$site/index.html" <<HTML
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>GridCraft downloads</title></head><body><main><h1>GridCraft downloads</h1><p><a href="flatpak/">Flatpak repository</a></p><p><a href="https://github.com/$GITHUB_REPOSITORY/releases/tag/$RELEASE_TAG">Release assets</a></p></main></body></html>
HTML
touch "$site/.nojekyll"
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: ${{ runner.temp }}/site
include-hidden-files: true
deploy:
timeout-minutes: 60
name: Deploy Pages
needs: build
runs-on: ubuntu-24.04
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
+13 -81
View File
@@ -1,95 +1,27 @@
# Builds and tests the workspace on FreeBSD, inside a FreeBSD VM on a Linux runner
# (GitHub has no FreeBSD runners). GPU tests skip themselves when the VM has no adapter.
# Test builds run only from the `release` branch (a manual run from any other branch is skipped).
# Packaging runs (release.yml calls it that way) run from any branch, so a release.yml dry run
# from a branch builds the tarball too; they need no secrets.
#
# With `package: true` (release.yml calls it that way, or a manual run) it instead builds the
# release binaries and uploads `gridcraft-<version>-freebsd-x86_64.tar.gz` as the
# `release-freebsd` artifact (packaging/freebsd/package.sh), which release.yml attaches to the
# draft GitHub Release.
name: FreeBSD
on:
push:
branches: [release]
pull_request:
paths:
- .github/workflows/freebsd.yml
- packaging/freebsd/**
- packaging/env.sh
workflow_dispatch:
inputs:
package:
description: "Build the release tarball instead of running the tests"
type: boolean
default: false
workflow_call:
inputs:
version:
description: "Version for the artifact name (empty: Cargo.toml)"
type: string
default: ""
version_override:
description: "Also write the version into Cargo.toml before building (test runs)"
type: boolean
default: false
package:
type: boolean
default: false
concurrency:
# Called from release.yml, github.workflow is the caller's name; keep the groups apart.
group: freebsd-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.workflow == 'FreeBSD' }}
group: freebsd-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
freebsd:
name: FreeBSD 14 (${{ inputs.package && 'package' || 'build + test' }})
if: github.ref == 'refs/heads/release' || inputs.package
runs-on: ubuntu-latest
timeout-minutes: 300
env:
GRIDCRAFT_VERSION: ${{ inputs.version }}
GRIDCRAFT_VERSION_OVERRIDE: ${{ inputs.version_override && '1' || '' }}
GRIDCRAFT_PACKAGE: ${{ inputs.package && '1' || '' }}
GRIDCRAFT_BUILD_SHA: ${{ github.sha }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check out craft-fonts
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: storytold/craft-fonts
ref: abb83316d96aa59c1cf64784289e378fe9fa5695
path: craft-fonts
- name: Build in a FreeBSD VM
uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc # v1.5.9
with:
release: "14.3"
usesh: true
cpu: 4
mem: 12288
envs: "GRIDCRAFT_VERSION GRIDCRAFT_VERSION_OVERRIDE GRIDCRAFT_PACKAGE GRIDCRAFT_BUILD_SHA"
# Only the packaging run brings files back (dist/release). The target dir lives outside
# the synced checkout, because copying it out of the VM fails on large builds.
copyback: ${{ inputs.package }}
prepare: |
pkg install -y bash git curl pkgconf cmake python3 libxkbcommon wayland libX11 libXcursor libXrandr libXi libxcb mesa-libs vulkan-loader gtk3 fontconfig freetype2
curl -fsSL https://sh.rustup.rs | sh -s -- -y --profile minimal
run: |
. "$HOME/.cargo/env"
# The checkout is synced in under another owner; let tests that call git read it.
git config --global --add safe.directory "*"
export CARGO_TARGET_DIR=/var/tmp/gridcraft-target CARGO_PROFILE_DEV_DEBUG=0
rustc --version
if [ -n "$GRIDCRAFT_PACKAGE" ]; then
if [ -n "$GRIDCRAFT_VERSION_OVERRIDE" ]; then
cargo run -q -p xtask --no-default-features -- version set "$GRIDCRAFT_VERSION"
fi
CRAFT_FONTS_DIR="$PWD/craft-fonts" CRAFT_FONTS_REQUIRED=1 bash packaging/freebsd/package.sh
else
cargo build --workspace --all-targets --locked
CRAFT_FONTS_DIR="$PWD/craft-fonts" cargo test --workspace --locked
fi
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: inputs.package
with:
name: release-freebsd
path: dist/release/*
if-no-files-found: error
# Intentionally tracked at @main (not SHA-pinned) so org-wide CI improvements, security fixes, and build optimizations propagate without PR churn across all craftapp repos.
uses: storytold/craft-common-actions/.github/workflows/freebsd.yml@main
with:
craft-fonts-ref: abb83316d96aa59c1cf64784289e378fe9fa5695
+33
View File
@@ -0,0 +1,33 @@
# Evaluates the Nix flake (no build, about a minute): `nix build` / `nix develop` stop at evaluation
# when Cargo.lock gains something nix/package.nix can't vendor, and nothing else would notice.
name: Nix
on:
push:
branches: [main]
paths: ["flake.nix", "flake.lock", "nix/**", "Cargo.lock", ".github/workflows/nix.yml"]
pull_request:
paths: ["flake.nix", "flake.lock", "nix/**", "Cargo.lock", ".github/workflows/nix.yml"]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: nix-${{ github.ref }}
cancel-in-progress: true
jobs:
eval:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1
- name: nix flake check --no-build
run: |
if [ -f flake.nix ]; then
nix flake check --no-build --all-systems
else
echo "No flake.nix present in this repository; skipping check."
fi