Skip to content

Commit dd66dfe

Browse files
committed
GitHub Actions: add image-building jobs
1 parent f7311aa commit dd66dfe

File tree

7 files changed

+314
-2
lines changed

7 files changed

+314
-2
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Generate Format
2+
description: Build a NixOS configuration using the specified nixos-generators format
3+
inputs:
4+
nix-exec-path:
5+
description: Path to the nix executable
6+
default: nix
7+
format:
8+
description: nixos-generate format name
9+
system:
10+
description: Target nixpkgs system (e.g. x86_64-linux)
11+
default: x86_64-linux
12+
nixpkgs-name:
13+
description: Flake input name for the target nixpkgs version
14+
default: nixpkgs
15+
nixpkgs:
16+
description: Search path/URL for the target nixpkgs
17+
default: 'https://github.com/nixos/nixpkgs/archive/nixpkgs-unstable.tar.gz'
18+
force-build:
19+
description: Build the target format even if no corresponding flake check exists
20+
flake:
21+
description: Nix flake URL
22+
default: ${{ github.workspace }}
23+
runs:
24+
using: composite
25+
steps:
26+
- name: Build the "${{ inputs.format }}" format
27+
id: generate
28+
shell: bash
29+
run: ${{ github.action_path }}/generate-format.sh
30+
env:
31+
NIX_EXEC_PATH: ${{ inputs.nix-exec-path }}
32+
FORMAT: ${{ inputs.format }}
33+
SYSTEM: ${{ inputs.system }}
34+
NIXPKGS_NAME: ${{ inputs.nixpkgs-name }}
35+
NIXPKGS: ${{ inputs.nixpkgs }}
36+
FORCE_BUILD: ${{ inputs.force-build }}
37+
FLAKE: ${{ inputs.flake }}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/bin/sh
2+
3+
set -x
4+
5+
printenv
6+
7+
die() {
8+
rc="$?"
9+
echo "::error file=nixos-generate::$*"
10+
exit "$rc"
11+
}
12+
13+
generate() {
14+
timeout 20m \
15+
"${NIX_EXEC_PATH:-nix}" run . \
16+
-- \
17+
-I "nixpkgs=${NIXPKGS?}" \
18+
"$@"
19+
}
20+
21+
getCheck() {
22+
"${NIX_EXEC_PATH:-nix}" eval --json "${FLAKE:-.}#checks.\"${1?}\"" --apply "(builtins.hasAttr \"${2?}\")"
23+
}
24+
25+
hasCheck() {
26+
has_check=$(getCheck "$@") || die "failed to confirm availablity of check output"
27+
[ "$has_check" = true ]
28+
}
29+
30+
buildCheck() {
31+
"${NIX_EXEC_PATH:-nix}" build "${FLAKE:-.}#checks.\"${1?}\".\"${2?}\""
32+
}
33+
34+
buildAnyway() {
35+
[ -n "${FORCE_BUILD:-}" ]
36+
}
37+
38+
checkOutputs() {
39+
path_var="$1"
40+
shift
41+
42+
path="$1"
43+
shift
44+
45+
test_type="$1"
46+
shift
47+
48+
test "$test_type" "$path" || die "path $path does not exist or is not the expected type"
49+
real=$(readlink -f "$path") || die "unable to resolve path to $path"
50+
store_paths=$(nix-store -q --outputs "$real") || die "unable to get store path of $real"
51+
echo "::set-output name=${path_var}::$(echo "$store_paths" | head -n 1)"
52+
}
53+
54+
format="${FORMAT?}"
55+
system="${SYSTEM:-x86_64-linux}"
56+
nixpkgs_name="${NIXPKGS_NAME:-nixpkgs}"
57+
check="${format}-${nixpkgs_name}"
58+
out_link="./result-${format}"
59+
60+
if hasCheck "$system" "$check"; then
61+
: # NOP
62+
elif buildAnyway; then
63+
buildCheck() { : ; }
64+
else
65+
printf 1>&2 -- "No flake check defined for format '%s' on system '%s' using nixpkgs '%s', and force-building is not enabled; exiting.\\n" \
66+
"$format" "$system" "$nixpkgs_name"
67+
68+
exit 0
69+
fi
70+
71+
out=$(generate -f "$format" --system "$system" -o "$out_link") || die "build exited with status $?"
72+
buildCheck "$system" "$check" || die "flake build exited with status $?"
73+
checkOutputs out "$out" -f
74+
checkOutputs out_link "$out_link" -e
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Get Rev
2+
description: Get a Nix flake input revision from the flake lock file
3+
inputs:
4+
nix-exec-path:
5+
description: Path to the nix executable
6+
default: nix
7+
flake-input-name:
8+
description: Name of the flake input whose revision should be retrieved
9+
default: nixpkgs
10+
flake:
11+
description: Nix flake URL
12+
default: ${{ github.workspace }}
13+
outputs:
14+
rev:
15+
description: Locked revision of the flake input
16+
value: ${{ steps.get-rev.outputs.rev }}
17+
runs:
18+
using: composite
19+
steps:
20+
- name: Get flake input revision for "${{ inputs.flake-input-name }}" from ${{ inputs.flake-lock-path }}
21+
id: get-rev
22+
shell: bash
23+
env:
24+
NIX_EXEC_PATH: ${{ inputs.nix-exec-path }}
25+
FLAKE_INPUT_NAME: ${{ inputs.flake-input-name }}
26+
FLAKE: ${{ inputs.flake }}
27+
run: ${{ github.action_path }}/get-flake-input-rev.sh
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/sh
2+
3+
getRev() {
4+
# Run in nix shell in order to use jq
5+
# shellcheck disable=SC2016
6+
"${NIX_EXEC_PATH:-nix}" develop "${FLAKE:-.}" --command \
7+
bash -c '"$1" flake metadata --json "$2" | jq -r --arg input "$3" ".locks.nodes[\$input].locked.rev"' \
8+
"$0" "${NIX_EXEC_PATH:-nix}" "${FLAKE:-.}" "${1?}"
9+
}
10+
11+
rev=$(getRev "${FLAKE_INPUT_NAME:-nixpkgs}") || exit
12+
13+
if [ "$rev" = null ]; then
14+
echo "::error file=${FLAKE:-.}::unable to retrieve revision for flake input ${FLAKE_INPUT_NAME:-nixpkgs}"
15+
exit 1
16+
fi
17+
18+
echo "::set-output name=rev::${rev}"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: List Formats
2+
description: List available nixos-generators formats
3+
inputs:
4+
nixos-generate-exec-path:
5+
description: Path to the nixos-generate executable
6+
default: ${{ github.workspace }}/nixos-generate
7+
nix-exec-path:
8+
description: Path to the nix executable
9+
default: nix
10+
flake:
11+
description: Nix flake URL
12+
default: ${{ github.workspace }}
13+
outputs:
14+
formats:
15+
description: Available nixos-generators formats
16+
value: ${{ steps.list-formats.outputs.formats }}
17+
runs:
18+
using: composite
19+
steps:
20+
- name: List available nixos-generators formats
21+
id: list-formats
22+
shell: bash
23+
env:
24+
NIXOS_GENERATE_EXEC_PATH: ${{ inputs.nixos-generate-exec-path }}
25+
NIX_EXEC_PATH: ${{ inputs.nix-exec-path }}
26+
FLAKE: ${{ inputs.flake }}
27+
run: ${{ github.action_path }}/list-formats.sh
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh
2+
3+
listFormats() {
4+
# Run in nix shell in order to use jq
5+
# shellcheck disable=SC2016
6+
"${NIX_EXEC_PATH:-nix}" develop "${FLAKE:-.}" --command \
7+
bash -c '"$1" --list | jq -cnMR "[inputs]"' \
8+
"$0" "${NIXOS_GENERATE_EXEC_PATH:-./nixos-generate}"
9+
}
10+
11+
formats=$(listFormats) || exit
12+
echo "::set-output name=formats::${formats}"

.github/workflows/build.yml

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,127 @@ jobs:
1111
steps:
1212
- uses: actions/checkout@v3
1313
with:
14-
# Nix Flakes doesn't work on shallow clones
15-
fetch-depth: 0
14+
# Nix Flakes doesn't work on shallow clones
15+
fetch-depth: 0
1616
- uses: cachix/install-nix-action@v17
1717
- name: List flake structure
1818
run: nix flake show
1919
- name: Run unit tests (flake)
2020
run: nix build -L
21+
check:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v3
25+
with:
26+
fetch-depth: 0
27+
- uses: cachix/install-nix-action@v17
28+
- name: Run flake checks
29+
run: nix flake check --no-build --keep-going
30+
introspect:
31+
runs-on: ubuntu-latest
32+
outputs:
33+
nixpkgs-rev: ${{ steps.nixpkgs-rev.outputs.rev }}
34+
nixos-rev: ${{ steps.nixos-rev.outputs.rev }}
35+
formats: ${{ steps.list-formats.outputs.formats }}
36+
steps:
37+
- uses: actions/checkout@v3
38+
with:
39+
fetch-depth: 0
40+
- uses: cachix/install-nix-action@v17
41+
- name: Get nixpkgs flake input rev
42+
id: nixpkgs-rev
43+
uses: ./.github/actions/get-flake-input-rev
44+
with:
45+
flake-input-name: nixpkgs
46+
- name: Get nixos flake input rev
47+
id: nixos-rev
48+
uses: ./.github/actions/get-flake-input-rev
49+
with:
50+
flake-input-name: nixos
51+
- name: List available formats
52+
id: list-formats
53+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
54+
uses: ./.github/actions/list-formats
55+
default-formats:
56+
strategy:
57+
matrix:
58+
format:
59+
- amazon
60+
- docker
61+
- iso
62+
- kexec-bundle
63+
nixpkgs-name:
64+
- nixpkgs
65+
- nixos
66+
include:
67+
- nixpkgs-name: nixpkgs
68+
nixpkgs: 'https://github.com/nixos/nixpkgs/archive/${{ needs.introspect.outputs.nixpkgs-rev }}.tar.gz'
69+
- nixpkgs-name: nixos
70+
nixpkgs: 'https://github.com/nixos/nixpkgs/archive/${{ needs.introspect.outputs.nixos-rev }}.tar.gz'
71+
- format: kexec-bundle
72+
force-build: yes
73+
runs-on: ubuntu-latest
74+
needs: [ 'check', 'introspect' ]
75+
steps:
76+
- uses: actions/checkout@v3
77+
with:
78+
fetch-depth: 0
79+
- uses: cachix/install-nix-action@v17
80+
with:
81+
# kvm required for a number of formats; big-parallel required for
82+
# proxmox and possibly others.
83+
extra_nix_config: |
84+
system-features = big-parallel kvm
85+
- name: Build the "${{ matrix.format }}" format
86+
id: generate
87+
uses: ./.github/actions/generate-format
88+
with:
89+
format: ${{ matrix.format }}
90+
system: ${{ matrix.system }}
91+
nixpkgs-name: ${{ matrix.nixpkgs-name }}
92+
nixpkgs: ${{ matrix.nixpkgs }}
93+
force-build: ${{ matrix.force-build }}
94+
all-formats:
95+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
96+
strategy:
97+
matrix:
98+
format: ${{ needs.introspect.outputs.formats && fromJSON(needs.introspect.outputs.formats) }}
99+
nixpkgs-name:
100+
- nixpkgs
101+
- nixos
102+
include:
103+
- nixpkgs-name: nixpkgs
104+
nixpkgs: 'https://github.com/nixos/nixpkgs/archive/${{ needs.introspect.outputs.nixpkgs-rev }}.tar.gz'
105+
- nixpkgs-name: nixos
106+
nixpkgs: 'https://github.com/nixos/nixpkgs/archive/${{ needs.introspect.outputs.nixos-rev }}.tar.gz'
107+
- format: kexec-bundle
108+
force-build: yes
109+
- format: sd-aarch64-installer
110+
system: aarch64-linux
111+
- format: sd-aarch64
112+
system: aarch64-linux
113+
runs-on: ubuntu-latest
114+
needs: [ 'check', 'introspect' ]
115+
steps:
116+
- uses: actions/checkout@v3
117+
with:
118+
fetch-depth: 0
119+
# set up qemu if we are targeting a non-native system
120+
- uses: docker/setup-qemu-action@v2
121+
if: ${{ matrix.system }}
122+
- uses: cachix/install-nix-action@v17
123+
with:
124+
# kvm required for a number of formats; big-parallel required for
125+
# proxmox and possibly others.
126+
extra_nix_config: |
127+
system-features = big-parallel kvm
128+
extra-platforms = ${{ matrix.system }}
129+
- name: Build the "${{ matrix.format }}" format
130+
id: generate
131+
uses: ./.github/actions/generate-format
132+
with:
133+
format: ${{ matrix.format }}
134+
system: ${{ matrix.system }}
135+
nixpkgs-name: ${{ matrix.nixpkgs-name }}
136+
nixpkgs: ${{ matrix.nixpkgs }}
137+
force-build: ${{ matrix.force-build }}

0 commit comments

Comments
 (0)