diff --git a/.github/workflows/flatpak-pages.yml b/.github/workflows/flatpak-pages.yml
deleted file mode 100644
index d08ac430a..000000000
--- a/.github/workflows/flatpak-pages.yml
+++ /dev/null
@@ -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" <"$site/flatpak/index.html" <
GridCraft Flatpak repositoryGridCraft Flatpak repository
Latest published release: $RELEASE_TAG
Add the GridCraft repository
flatpak remote-add --if-not-exists gridcraft $base_url/flatpak/gridcraft.flatpakrepo
- flatpak install gridcraft $APP_ID
- HTML
- cat >"$site/index.html" <GridCraft downloadsGridCraft downloads
Flatpak repository
Release assets
- 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
diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml
index 0a82a910f..6cdde6e47 100644
--- a/.github/workflows/freebsd.yml
+++ b/.github/workflows/freebsd.yml
@@ -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--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
diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml
new file mode 100644
index 000000000..18392587a
--- /dev/null
+++ b/.github/workflows/nix.yml
@@ -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