Skip to content

Commit adb1f8a

Browse files
authoredMar 21, 2024··
Merge pull request #16 from NixOS/automated-releases
This sets up automated releases, mainly so that we can distribute a pre-built version of the tool, allowing Nixpkgs' CI to fetch it without building.
2 parents 0f556f9 + ce41249 commit adb1f8a

File tree

4 files changed

+122
-4
lines changed

4 files changed

+122
-4
lines changed
 

‎.github/workflows/main.yml

-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ on:
33
pull_request:
44
branches:
55
- main
6-
push:
7-
branches:
8-
- main
96

107
jobs:
118
check:

‎.github/workflows/release.yml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: CD
2+
on:
3+
push:
4+
branches:
5+
- main
6+
7+
jobs:
8+
release:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
13+
- uses: cachix/install-nix-action@v26
14+
15+
- name: release
16+
run: scripts/release.sh

‎package.nix

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
}:
1414
let
1515
fs = lib.fileset;
16+
version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).package.version;
1617
in
1718
rustPlatform.buildRustPackage {
18-
name = "nixpkgs-check-by-name";
19+
pname = "nixpkgs-check-by-name";
20+
inherit version;
1921
src = fs.toSource {
2022
root = ./.;
2123
fileset = fs.unions [

‎scripts/release.sh

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
tmp=$(mktemp -d)
6+
trap 'rm -rf "$tmp"' exit
7+
8+
nixeval() {
9+
# Since there's no stable `nix eval --raw`, also see https://github.com/NixOS/nix/pull/9361
10+
nix-instantiate --eval --json "$@" | jq -r .
11+
}
12+
13+
# The system to pre-build the release for and distribute artifacts for
14+
system=x86_64-linux
15+
root=$(git rev-parse --show-toplevel)
16+
repository=${GITHUB_REPOSITORY:-NixOS/nixpkgs-check-by-name}
17+
18+
# Get the version from the Cargo.toml file
19+
version=$(nixeval "$root" -A build.version)
20+
echo "Current version is $version"
21+
22+
if existingRelease=$(gh api \
23+
-H "Accept: application/vnd.github+json" \
24+
-H "X-GitHub-Api-Version: 2022-11-28" \
25+
/repos/"$repository"/releases/tags/"$version"); then
26+
echo "Release $version already exists, no new release necessary"
27+
exit 0
28+
else
29+
echo "$existingRelease"
30+
echo "Release $version doesn't exist yet, creating it"
31+
fi
32+
33+
echo "Building release artifact for system $system"
34+
35+
nix-build "$root" -A build -o "$tmp/build" >/dev/null
36+
readarray -t closure < <(nix-store -qR "$tmp/build")
37+
nix-store --export "${closure[@]}" > "$tmp/$system.nar"
38+
gzip "$tmp/$system.nar"
39+
artifactName=$system.nar.gz
40+
41+
body='Automated release.
42+
43+
The artifact is a gzip-compressed [Nix Archive](https://nixos.org/manual/nix/stable/command-ref/nix-store/export.html) of the [build closure](https://nixos.org/manual/nix/stable/glossary#gloss-closure).
44+
45+
To import it:
46+
```bash
47+
gzip -cd '"$artifactName"' | nix-store --import | tail -1
48+
```
49+
'
50+
51+
echo "Creating draft release"
52+
if ! release=$(gh api \
53+
--method POST \
54+
-H "Accept: application/vnd.github+json" \
55+
-H "X-GitHub-Api-Version: 2022-11-28" \
56+
/repos/"$repository"/releases \
57+
-f tag_name="$version" \
58+
-f name="Version $version" \
59+
-f body="$body" \
60+
-F draft=true); then
61+
echo "Failed to create release: $release"
62+
fi
63+
64+
releaseId=$(jq .id <<< "$release")
65+
66+
abortRelease() {
67+
echo "Aborting, deleting the draft release"
68+
gh api \
69+
--method DELETE \
70+
-H "Accept: application/vnd.github+json" \
71+
-H "X-GitHub-Api-Version: 2022-11-28" \
72+
/repos/"$repository"/releases/"$releaseId"
73+
exit 1
74+
}
75+
76+
echo "Uploading release artifact"
77+
# GitHub docs say to use the releases' upload_url, but that's of the RFC 6570 form, see
78+
# https://docs.github.com/en/rest/using-the-rest-api/getting-started-with-the-rest-api?apiVersion=2022-11-28#hypermedia
79+
# And neither the GitHub CLI nor curl seem to have support for that right now, so let's do it
80+
# manually instead
81+
if ! uploadResult=$(curl -sSfL \
82+
-X POST \
83+
-H "Accept: application/vnd.github+json" \
84+
-H "Authorization: Bearer $(gh auth token)" \
85+
-H "X-GitHub-Api-Version: 2022-11-28" \
86+
-H "Content-Type: application/octet-stream" \
87+
"https://uploads.github.com/repos/$repository/releases/$releaseId/assets?name=$artifactName" \
88+
--data-binary "@$tmp/$artifactName"); then
89+
echo "Failed to upload artifact: $uploadResult"
90+
abortRelease
91+
fi
92+
93+
if ! publishResult=$(gh api \
94+
--method PATCH \
95+
-H "Accept: application/vnd.github+json" \
96+
-H "X-GitHub-Api-Version: 2022-11-28" \
97+
/repos/"$repository"/releases/"$releaseId" \
98+
-F draft=false); then
99+
echo "Failed to publish release: $publishResult"
100+
abortRelease
101+
fi
102+
103+
echo "Published release: $(jq .html_url -r <<< "$publishResult")"

0 commit comments

Comments
 (0)
Please sign in to comment.