ci: strengthen NixOS checks

This commit is contained in:
2026-07-14 19:49:56 +09:00
parent b5c49ffa79
commit 7f47448980
7 changed files with 169 additions and 146 deletions
-70
View File
@@ -1,70 +0,0 @@
name: NixOS build
on:
pull_request:
branches:
- main
paths:
- ".github/workflows/nixos-build.yml"
- "flake.lock"
- "flake.nix"
- "flake/**"
- "hosts/**"
- "modules/**"
- "overlays/**"
- "profiles/**"
- "shells/**"
- ".sops.yaml"
- "secrets/**"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
discover-hosts:
name: Discover NixOS hosts
runs-on: ubuntu-latest
outputs:
hosts: ${{ steps.hosts.outputs.hosts }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
access-tokens = github.com=${{ github.token }}
- name: Evaluate NixOS hosts
id: hosts
run: |
set -euo pipefail
hosts_json=$(nix eval --json '.#nixosConfigurations' --apply 'configs: builtins.attrNames configs')
echo "hosts=${hosts_json}" >> "$GITHUB_OUTPUT"
echo "Discovered hosts: ${hosts_json}"
build-host:
name: Build ${{ matrix.host }}
needs: discover-hosts
if: ${{ needs.discover-hosts.outputs.hosts != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
host: ${{ fromJSON(needs.discover-hosts.outputs.hosts) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
access-tokens = github.com=${{ github.token }}
- name: Build NixOS system
run: |
set -euo pipefail
nix build ".#nixosConfigurations.${{ matrix.host }}.config.system.build.toplevel" \
--print-build-logs
+150
View File
@@ -0,0 +1,150 @@
name: NixOS CI
on:
pull_request:
branches:
- main
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
concurrency:
group: nixos-ci-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
validate:
name: Validate flake
runs-on: ubuntu-latest
timeout-minutes: 30
outputs:
hosts: ${{ steps.hosts.outputs.hosts }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Install Nix
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
access-tokens = github.com=${{ github.token }}
- name: Check flake and evaluate all outputs
run: nix flake check --all-systems --no-build --show-trace
- name: Discover NixOS hosts
id: hosts
run: |
hosts=$(nix eval --json '.#nixosConfigurations' --apply 'configs: builtins.attrNames configs')
echo "hosts=$hosts" >> "$GITHUB_OUTPUT"
echo "Discovered hosts: $hosts"
build:
name: Build ${{ matrix.host }}
needs: validate
if: ${{ needs.validate.outputs.hosts != '[]' }}
runs-on: ubuntu-latest
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
host: ${{ fromJSON(needs.validate.outputs.hosts) }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Install Nix
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
access-tokens = github.com=${{ github.token }}
- name: Build NixOS system
run: |
nix build ".#nixosConfigurations.${{ matrix.host }}.config.system.build.toplevel" \
--no-link \
--print-build-logs \
--show-trace
report-main-status:
name: Report main status
needs:
- validate
- build
if: ${{ always() && !cancelled() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
issues: write
env:
CI_FAILED: ${{ needs.validate.result == 'failure' || needs.build.result == 'failure' }}
JOB_RESULTS: ${{ toJSON(needs) }}
steps:
- name: Create or resolve failure issue
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const title = "NixOS CI is failing on main";
const marker = "<!-- nixos-ci-main-failure -->";
const failed = process.env.CI_FAILED === "true";
const jobs = JSON.parse(process.env.JOB_RESULTS);
const failedJobs = Object.entries(jobs)
.filter(([, job]) => job.result === "failure")
.map(([name]) => `\`${name}\``)
.join(", ");
const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`;
const commitUrl = `${context.serverUrl}/${owner}/${repo}/commit/${context.sha}`;
const issues = await github.paginate(github.rest.issues.listForRepo, {
owner,
repo,
state: "open",
per_page: 100,
});
const existing = issues.find(
(issue) => !issue.pull_request && issue.title === title && issue.body?.includes(marker),
);
if (failed) {
const body = [
marker,
"The NixOS CI workflow failed after a push to `main`.",
"",
`- Failed jobs: ${failedJobs || "unknown"}`,
`- Commit: [\`${context.sha.slice(0, 7)}\`](${commitUrl})`,
`- Workflow run: [${context.runId}](${runUrl})`,
"",
"This issue is updated on subsequent failures and closed automatically after CI recovers.",
].join("\n");
if (existing) {
await github.rest.issues.update({
owner,
repo,
issue_number: existing.number,
body,
});
} else {
await github.rest.issues.create({ owner, repo, title, body });
}
return;
}
if (existing) {
await github.rest.issues.createComment({
owner,
repo,
issue_number: existing.number,
body: `CI recovered in [workflow run ${context.runId}](${runUrl}).`,
});
await github.rest.issues.update({
owner,
repo,
issue_number: existing.number,
state: "closed",
state_reason: "completed",
});
}
-69
View File
@@ -1,69 +0,0 @@
name: NixOS eval
on:
pull_request:
branches:
- main
paths:
- ".github/workflows/nixos-eval.yml"
- "flake.lock"
- "flake.nix"
- "flake/**"
- "hosts/**"
- "modules/**"
- "overlays/**"
- "profiles/**"
- "shells/**"
- ".sops.yaml"
- "secrets/**"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
discover-hosts:
name: Discover NixOS hosts
runs-on: ubuntu-latest
outputs:
hosts: ${{ steps.hosts.outputs.hosts }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
access-tokens = github.com=${{ github.token }}
- name: Evaluate NixOS hosts
id: hosts
run: |
set -euo pipefail
hosts_json=$(nix eval --json '.#nixosConfigurations' --apply 'configs: builtins.attrNames configs')
echo "hosts=${hosts_json}" >> "$GITHUB_OUTPUT"
echo "Discovered hosts: ${hosts_json}"
eval-host:
name: Eval ${{ matrix.host }}
needs: discover-hosts
if: ${{ needs.discover-hosts.outputs.hosts != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
host: ${{ fromJSON(needs.discover-hosts.outputs.hosts) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
experimental-features = nix-command flakes
accept-flake-config = true
access-tokens = github.com=${{ github.token }}
- name: Evaluate NixOS system derivation
run: |
set -euo pipefail
nix eval ".#nixosConfigurations.${{ matrix.host }}.config.system.build.toplevel.drvPath"
+4 -2
View File
@@ -16,10 +16,12 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/[email protected]
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
# Use a PAT or GitHub App token so Renovate PRs trigger the other workflows.
- name: Run Renovate
uses: renovatebot/[email protected]
uses: renovatebot/github-action@22e0a16091fc706b04affe6ae53d5e3358ac4023 # v46.1.19
with:
renovate-version: 43.262.1
token: ${{ secrets.RENOVATE_TOKEN }}
+11 -3
View File
@@ -47,9 +47,8 @@ let
;
};
};
in
{
flake.nixosConfigurations = {
nixosConfigurations = {
nix-example = mkSystem {
host = "nix-example";
system = "x86_64-linux";
@@ -102,4 +101,13 @@ in
};
};
};
in
{
flake = {
inherit nixosConfigurations;
checks.x86_64-linux = lib.mapAttrs' (
name: nixos: lib.nameValuePair "nixos-${name}" nixos.config.system.build.toplevel
) nixosConfigurations;
};
}
+2
View File
@@ -9,6 +9,8 @@
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
];
boot.zfs.forceImportRoot = false;
networking = {
hostName = "nixos-installer";
+2 -2
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"enabledManagers": ["nix"],
"extends": ["config:recommended", "helpers:pinGitHubActionDigests"],
"enabledManagers": ["github-actions", "nix"],
"nix": {
"enabled": true
},