Repository navigation
118 lines (110 loc) · 4.92 KB
/
Copy pathflake-closure-diff.yml
File metadata and controls
118 lines (110 loc) · 4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
name: flake-closure-diff
# Reusable only. Reports what a flake.lock change actually does.
#
# A lock bump is unreviewable as a diff: one opaque `rev`/`narHash` line for
# nixpkgs silently moves every package in the dev shell — the Go toolchain,
# golangci-lint, treefmt, kubectl, helm. Renovate's weekly lockFileMaintenance
# refreshes every input at once and is merged by a human, who has nothing to
# look at. This builds the shell both sides of the change and posts the
# package-level difference to the job summary.
#
# Advisory: it reports, it never fails on a difference. A lock bump being large
# is not an error, it is a thing somebody should see.
on:
workflow_call:
inputs:
attribute:
description: >-
Flake output attribute whose closure to compare, with no `.#` prefix:
both sides are addressed as <path>#<attribute>.
type: string
default: devShells.x86_64-linux.default
secrets:
cachix-auth-token:
required: false
cachix-signing-key:
required: false
permissions:
contents: read
jobs:
closure-diff:
name: Diff flake closures
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
# The installer and cache are inlined rather than taken from setup-nix,
# as in renovate-dev-kit-lock: a reusable workflow cannot use the `./`
# path, which resolves against the caller, and a full self-reference
# would need the release's own SHA before that commit exists. Keep these
# two pins in step with .github/actions/setup-nix.
- name: Install nix
uses: cachix/install-nix-action@75c75c31ebece974e48ebc36b4ad125bd97bd97b # 31.11.3
- name: Use the shared Cachix cache
uses: cachix/cachix-action@38b082610b782e7e93e209c35fd730d399dee866 # v17
with:
name: opendefensecloud
authToken: ${{ secrets.cachix-auth-token }}
signingKey: ${{ secrets.cachix-signing-key }}
# Both sides are realised as profiles, which is the supported way to get a
# dev shell's closure as a store path. The base side usually comes
# straight from the cache, since it is what the last run built.
- name: Realise the closure before the change
id: before
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
ATTR: ${{ inputs.attribute }}
run: |
work="$(mktemp -d)"
git worktree add --detach "$work" "$BASE_SHA"
# Evaluation and build are separated deliberately. A base that does not
# evaluate is expected — it may predate the flake or the attribute —
# and is a notice. A base that evaluates but will not build is not
# expected, and silence would hide it, so it is a warning rather than a
# failure: this job is advisory, and the PR did not break the base.
if ! nix eval --raw "$work#$ATTR.drvPath" > /dev/null 2>"$work/eval-err"; then
echo "::notice::base revision does not evaluate $ATTR, skipping the closure diff"
sed 's/^/ /' "$work/eval-err" | tail -5
echo "path=" >> "$GITHUB_OUTPUT"
elif ! nix develop --profile "$work/.profile" "$work#$ATTR" --command true 2>"$work/build-err"; then
echo "::warning::base revision evaluates but its shell does not build, skipping the closure diff"
sed 's/^/ /' "$work/build-err" | tail -5
echo "path=" >> "$GITHUB_OUTPUT"
else
echo "path=$work/.profile" >> "$GITHUB_OUTPUT"
fi
- name: Realise the closure after the change
id: after
if: steps.before.outputs.path != ''
env:
ATTR: ${{ inputs.attribute }}
run: |
nix develop --profile .profile ".#$ATTR" --command true
# Absolute, because nix reads a relative path as a flake reference:
# it resolves the profile symlink and then rejects the store path with
# "is not a flake (because it's not a directory)". An absolute path
# under the store is recognised as a store path, which is what
# diff-closures wants.
echo "path=$PWD/.profile" >> "$GITHUB_OUTPUT"
- name: Report the difference
if: steps.before.outputs.path != ''
env:
BEFORE: ${{ steps.before.outputs.path }}
AFTER: ${{ steps.after.outputs.path }}
run: |
diff="$(nix store diff-closures "$BEFORE" "$AFTER")"
{
echo "## Dev shell closure diff"
echo
if [ -z "$diff" ]; then
echo "No package-level change in the dev shell."
else
echo '```'
echo "$diff"
echo '```'
fi
} >> "$GITHUB_STEP_SUMMARY"
# Also in the log, so it is greppable from a failed neighbouring job.
echo "$diff"