Skip to content

refactor: make volume controls consistent #338

refactor: make volume controls consistent

refactor: make volume controls consistent #338

Workflow file for this run

name: Flake Builder 🏗️
on:
pull_request:
push:
branches:
- main
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# ──────────────────────────────────────────────
# Inventory: discover all flake outputs
# ──────────────────────────────────────────────
inventory:
name: Inventory 📋
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
outputs:
devshells: ${{ steps.inventory.outputs.devshells }}
packages: ${{ steps.inventory.outputs.packages }}
nixos: ${{ steps.inventory.outputs.nixos }}
darwin: ${{ steps.inventory.outputs.darwin }}
orphan_homes: ${{ steps.inventory.outputs.orphan_homes }}
has_devshells: ${{ steps.inventory.outputs.has_devshells }}
has_packages: ${{ steps.inventory.outputs.has_packages }}
has_nixos: ${{ steps.inventory.outputs.has_nixos }}
has_darwin: ${{ steps.inventory.outputs.has_darwin }}
has_orphan_homes: ${{ steps.inventory.outputs.has_orphan_homes }}
steps:
- uses: actions/checkout@v6
- uses: wimpysworld/nothing-but-nix@main
with:
hatchet-protocol: "holster"
- uses: DeterminateSystems/determinate-nix-action@v3
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
- name: Inventory
id: inventory
run: bash home-manager/_mixins/scripts/flake-inventory/flake-inventory.sh
# ──────────────────────────────────────────────
# DevShells & Formatter (per-platform)
# ──────────────────────────────────────────────
devshells:
name: DevShells 🐚 (${{ matrix.target.system }})
needs: inventory
if: needs.inventory.outputs.has_devshells == 'true'
runs-on: ${{ matrix.target.runner }}
permissions:
id-token: write
contents: read
strategy:
fail-fast: false
matrix:
target: ${{ fromJSON(needs.inventory.outputs.devshells) }}
steps:
- uses: actions/checkout@v6
- uses: wimpysworld/nothing-but-nix@main
if: contains(matrix.target.system, 'linux')
with:
hatchet-protocol: "holster"
- uses: DeterminateSystems/determinate-nix-action@v3
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
- name: Build devShells & formatter
env:
SYSTEM: ${{ matrix.target.system }}
SHELLS_JSON: ${{ toJSON(matrix.target.shells) }}
HAS_FORMATTER: ${{ matrix.target.formatter }}
run: |
FAILED=()
BUILT=0
SKIPPED=0
# Build each devShell, checking evaluability first.
while IFS= read -r shell; do
[ -z "${shell}" ] && continue
ATTR="devShells.${SYSTEM}.${shell}"
if nix eval ".#${ATTR}.drvPath" --raw --no-write-lock-file >/dev/null 2>&1; then
echo "🔨 Building ${ATTR}"
if nix build ".#${ATTR}" --no-link -L; then
echo "✅ Built ${ATTR}"
BUILT=$((BUILT + 1))
else
echo "❌ Failed to build ${ATTR}" >&2
FAILED+=("${ATTR}")
fi
else
echo "⏭️ Skipping ${ATTR} (not evaluable for ${SYSTEM})"
SKIPPED=$((SKIPPED + 1))
fi
done < <(echo "${SHELLS_JSON}" | jq -r '.[]')
# Build formatter if present.
if [ "${HAS_FORMATTER}" = "true" ]; then
ATTR="formatter.${SYSTEM}"
echo "🔨 Building ${ATTR}"
if nix build ".#${ATTR}" --no-link -L; then
echo "✅ Built ${ATTR}"
BUILT=$((BUILT + 1))
else
echo "❌ Failed to build ${ATTR}" >&2
FAILED+=("${ATTR}")
fi
fi
echo ""
echo "Built: ${BUILT}, Skipped: ${SKIPPED}, Failed: ${#FAILED[@]}"
if [ "${#FAILED[@]}" -gt 0 ]; then
echo "Failed outputs:"
for f in "${FAILED[@]}"; do
echo " ✗ ${f}"
done
exit 1
fi
# ──────────────────────────────────────────────
# Packages (per-platform)
# ──────────────────────────────────────────────
packages:
name: Packages 📦 (${{ matrix.target.system }})
needs: inventory
if: needs.inventory.outputs.has_packages == 'true'
runs-on: ${{ matrix.target.runner }}
permissions:
id-token: write
contents: read
strategy:
fail-fast: false
matrix:
target: ${{ fromJSON(needs.inventory.outputs.packages) }}
steps:
- uses: actions/checkout@v6
- uses: wimpysworld/nothing-but-nix@main
if: contains(matrix.target.system, 'linux')
with:
hatchet-protocol: "holster"
- uses: DeterminateSystems/determinate-nix-action@v3
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
- name: Prefetch proprietary packages 📦
if: contains(matrix.target.system, 'linux')
env:
PICO8_DOWNLOAD_URL: ${{ secrets.PICO8_DOWNLOAD_URL }}
run: |
if [ -n "${PICO8_DOWNLOAD_URL}" ]; then
nix-prefetch-url --name "pico-8_0.2.7_amd64.zip" "${PICO8_DOWNLOAD_URL}" || echo "⚠️ PICO-8 prefetch failed"
fi
- name: Build packages
env:
SYSTEM: ${{ matrix.target.system }}
PACKAGES_JSON: ${{ toJSON(matrix.target.packages) }}
run: |
FAILED=()
BUILT=0
SKIPPED=0
SUMMARY_ROWS=()
while IFS= read -r name; do
[ -z "${name}" ] && continue
ATTR="packages.${SYSTEM}.${name}"
# Check whether the package evaluates for this platform.
if ! nix eval ".#${ATTR}.drvPath" --raw --no-write-lock-file >/dev/null 2>&1; then
echo "⏭️ Skipping ${ATTR} (not evaluable for ${SYSTEM})"
SKIPPED=$((SKIPPED + 1))
SUMMARY_ROWS+=("| ${name} | ⏭️ Skipped |")
continue
fi
# Check hydraPlatforms; skip if explicitly set to empty.
hydra_platforms=$(nix eval ".#${ATTR}.meta.hydraPlatforms" --json --no-write-lock-file 2>/dev/null || echo "null")
if [ "${hydra_platforms}" = "[]" ]; then
echo "⏭️ Skipping ${ATTR} (excluded from CI via hydraPlatforms)"
SKIPPED=$((SKIPPED + 1))
SUMMARY_ROWS+=("| ${name} | ⏭️ Skipped |")
continue
fi
echo "🔨 Building ${ATTR}"
if nix build ".#${ATTR}" --no-link -L; then
echo "✅ Built ${ATTR}"
BUILT=$((BUILT + 1))
SUMMARY_ROWS+=("| ${name} | ✅ Built |")
else
echo "❌ Failed to build ${ATTR}" >&2
FAILED+=("${ATTR}")
SUMMARY_ROWS+=("| ${name} | ❌ Failed |")
fi
done < <(echo "${PACKAGES_JSON}" | jq -r '.[]')
# Write Job Summary
{
printf "## Packages 📦 (%s)\n\n" "${SYSTEM}"
printf "| Package | Status |\n"
printf "|---------|--------|\n"
for row in "${SUMMARY_ROWS[@]}"; do
printf "%s\n" "${row}"
done
printf "\n**Built: %d, Skipped: %d, Failed: %d**\n" "${BUILT}" "${SKIPPED}" "${#FAILED[@]}"
} >> "$GITHUB_STEP_SUMMARY"
echo ""
echo "Built: ${BUILT}, Skipped: ${SKIPPED}, Failed: ${#FAILED[@]}"
if [ "${#FAILED[@]}" -gt 0 ]; then
echo "Failed outputs:"
for f in "${FAILED[@]}"; do
echo " ✗ ${f}"
done
exit 1
fi
# ──────────────────────────────────────────────
# NixOS Configurations (per-host)
# ──────────────────────────────────────────────
nixos:
name: NixOS 🐧 ${{ matrix.target.name }}
needs: inventory
if: needs.inventory.outputs.has_nixos == 'true'
runs-on: ${{ matrix.target.runner }}
permissions:
id-token: write
contents: read
strategy:
fail-fast: false
matrix:
target: ${{ fromJSON(needs.inventory.outputs.nixos) }}
steps:
- uses: actions/checkout@v6
- uses: wimpysworld/nothing-but-nix@main
with:
hatchet-protocol: "holster"
- uses: DeterminateSystems/determinate-nix-action@v3
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
- name: Prefetch proprietary packages 📦
env:
PICO8_DOWNLOAD_URL: ${{ secrets.PICO8_DOWNLOAD_URL }}
run: |
if [ -n "${PICO8_DOWNLOAD_URL}" ]; then
nix-prefetch-url --name "pico-8_0.2.7_amd64.zip" "${PICO8_DOWNLOAD_URL}" || echo "⚠️ PICO-8 prefetch failed"
fi
- name: Build NixOS ${{ matrix.target.name }}
run: |
nix build ".#nixosConfigurations.${{ matrix.target.name }}.config.system.build.toplevel" --no-link -L
- name: Build Home ${{ matrix.target.home }}
if: matrix.target.home != ''
run: |
nix build ".#homeConfigurations.\"${{ matrix.target.home }}\".activationPackage" --no-link -L
# ──────────────────────────────────────────────
# Darwin Configurations (per-host)
# ──────────────────────────────────────────────
darwin:
name: Darwin 🍏 ${{ matrix.target.name }}
needs: inventory
if: needs.inventory.outputs.has_darwin == 'true'
runs-on: ${{ matrix.target.runner }}
permissions:
id-token: write
contents: read
strategy:
fail-fast: false
matrix:
target: ${{ fromJSON(needs.inventory.outputs.darwin) }}
steps:
- uses: actions/checkout@v6
- uses: DeterminateSystems/determinate-nix-action@v3
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
- name: Build Darwin ${{ matrix.target.name }}
run: |
nix build ".#darwinConfigurations.${{ matrix.target.name }}.config.system.build.toplevel" --no-link -L
- name: Build Home ${{ matrix.target.home }}
if: matrix.target.home != ''
run: |
nix build ".#homeConfigurations.\"${{ matrix.target.home }}\".activationPackage" --no-link -L
# ──────────────────────────────────────────────
# Orphan Home Configurations (lima, wsl, gaming)
# ──────────────────────────────────────────────
orphan-homes:
name: Home 🏠 ${{ matrix.target.name }}
needs: inventory
if: needs.inventory.outputs.has_orphan_homes == 'true'
runs-on: ${{ matrix.target.runner }}
permissions:
id-token: write
contents: read
strategy:
fail-fast: false
matrix:
target: ${{ fromJSON(needs.inventory.outputs.orphan_homes) }}
steps:
- uses: actions/checkout@v6
- uses: wimpysworld/nothing-but-nix@main
with:
hatchet-protocol: "holster"
- uses: DeterminateSystems/determinate-nix-action@v3
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
- name: Prefetch proprietary packages 📦
if: contains(matrix.target.runner, 'ubuntu')
env:
PICO8_DOWNLOAD_URL: ${{ secrets.PICO8_DOWNLOAD_URL }}
run: |
if [ -n "${PICO8_DOWNLOAD_URL}" ]; then
nix-prefetch-url --name "pico-8_0.2.7_amd64.zip" "${PICO8_DOWNLOAD_URL}" || echo "⚠️ PICO-8 prefetch failed"
fi
- name: Build Home ${{ matrix.target.name }}
run: |
nix build ".#homeConfigurations.\"${{ matrix.target.name }}\".activationPackage" --no-link -L
# ──────────────────────────────────────────────
# Sentinel: gate builds and derive release version
# ──────────────────────────────────────────────
sentinel:
name: Sentinel 👁️
needs: [devshells, packages, nixos, darwin, orphan-homes]
if: always()
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
outputs:
ver: ${{ steps.version.outputs.ver }}
publish_ver: ${{ steps.version.outputs.publish_ver }}
steps:
- name: Check build results
run: |
results='${{ toJSON(needs.*.result) }}'
echo "Job results: ${results}"
if echo "${results}" | jq -e 'any(. == "failure" or . == "cancelled")' > /dev/null 2>&1; then
echo "❌ One or more build jobs failed or were cancelled"
exit 1
fi
echo "✅ All build jobs passed (or were skipped)"
- uses: actions/checkout@v6
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
- uses: DeterminateSystems/determinate-nix-action@v3
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
- name: Derive version
id: version
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
# Extract NixOS version (e.g. 25.11.20260211.6c5e707) and take first 3
# dot-separated components, then strip leading zeros for semver compliance
NIXOS_VER=$(nix eval .#nixosConfigurations.nihilus.config.system.nixos.version --raw)
VER=$(echo "${NIXOS_VER}" | cut -d'.' -f1-3 | sed -E 's/\b0+([1-9])/\1/g')
PUBLISH_VER="${VER}$(date -u +%H)"
echo "ver=${VER}" >> "$GITHUB_OUTPUT"
echo "publish_ver=${PUBLISH_VER}" >> "$GITHUB_OUTPUT"
echo "📌 Version: ${VER}"
echo "📌 Publish version: ${PUBLISH_VER}"
# ──────────────────────────────────────────────
# Publish to FlakeHub (after all builds pass)
# ──────────────────────────────────────────────
publish:
name: Publish FlakeHub ❄️
needs: [sentinel]
if: github.repository_owner == 'wimpysworld' && needs.sentinel.outputs.publish_ver != ''
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
id-token: write
contents: read
steps:
- uses: actionhippie/swap-space@v1
with:
size: 16G
- uses: actions/checkout@v6
- uses: DeterminateSystems/determinate-nix-action@v3
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
# Use fork with OIDC fix until upstream merges:
# https://github.com/DeterminateSystems/flakehub-push/pull/275
- name: Build flakehub-push 🔨
run: |
nix build github:flexiondotorg/flakehub-push/oidc-order#packages.x86_64-linux.default -L
- uses: DeterminateSystems/flakehub-push@v6
with:
tag: v${{ needs.sentinel.outputs.publish_ver }}
visibility: public
include-output-paths: true
log-directives: flakehub_push=debug
source-binary: result/bin/flakehub-push
# ──────────────────────────────────────────────
# Release ISO (after NixOS builds pass)
# ──────────────────────────────────────────────
release:
name: Release ISO 📀
needs: [sentinel]
if: github.repository_owner == 'wimpysworld' && needs.sentinel.outputs.ver != ''
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
steps:
- uses: actions/checkout@v6
- name: Check existing release 🔍
id: check-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if gh release view "v${{ needs.sentinel.outputs.ver }}" --repo "${{ github.repository }}" >/dev/null 2>&1; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Release v${{ needs.sentinel.outputs.ver }} already exists; skipping ISO build"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "Release v${{ needs.sentinel.outputs.ver }} not found; proceeding with ISO build"
fi
- uses: wimpysworld/nothing-but-nix@main
if: steps.check-release.outputs.exists == 'false'
with:
hatchet-protocol: "holster"
root-safe-haven: "10240"
mnt-safe-haven: "10240"
- uses: DeterminateSystems/determinate-nix-action@v3
if: steps.check-release.outputs.exists == 'false'
with:
extra-conf: |
eval-cores = 0
- uses: DeterminateSystems/flakehub-cache-action@v3
if: steps.check-release.outputs.exists == 'false'
- name: Build ISO 💿️
if: steps.check-release.outputs.exists == 'false'
id: build-iso
run: |
nix build .#nixosConfigurations.nihilus.config.system.build.isoImage -L
ISO=$(head -n1 result/nix-support/hydra-build-products | cut -d'/' -f6)
# Stage ISO for release upload; GitHub auto-generates sha256 digests
mkdir -p iso
sudo mv "result/iso/${ISO}" "iso/${ISO}"
- name: Release ISO 🎁
if: steps.check-release.outputs.exists == 'false'
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.sentinel.outputs.ver }}
files: iso/*
generate_release_notes: true
make_latest: true