nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 stdenvNoCC,
3 lib,
4 fetchurl,
5 writeScript,
6 nix,
7 runtimeShell,
8 curl,
9 cacert,
10 jq,
11 yq,
12 gnupg,
13
14 releaseManifestFile,
15 releaseInfoFile,
16 bootstrapSdkFile,
17 allowPrerelease,
18}:
19
20let
21 inherit (lib.importJSON releaseManifestFile) channel tag;
22
23 pkg = stdenvNoCC.mkDerivation {
24 name = "update-dotnet-vmr-env";
25
26 nativeBuildInputs = [
27 nix
28 curl
29 cacert
30 jq
31 yq
32 gnupg
33 ];
34 };
35
36 releaseKey = fetchurl {
37 url = "https://dotnet.microsoft.com/download/dotnet/release-key-2023.asc";
38 hash = "sha256-F668QB55md0GQvoG0jeA66Fb2RbrsRhFTzTbXIX3GUo=";
39 };
40
41 drv = builtins.unsafeDiscardOutputDependency pkg.drvPath;
42
43 toOutputPath =
44 path:
45 let
46 root = ../../../..;
47 in
48 lib.path.removePrefix root path;
49
50in
51writeScript "update-dotnet-vmr.sh" ''
52 #! ${nix}/bin/nix-shell
53 #! nix-shell -i ${runtimeShell} --pure ${drv} --keep UPDATE_NIX_ATTR_PATH
54 set -euo pipefail
55
56 tag=''${1-}
57
58 if [[ -n $tag ]]; then
59 query=$(cat <<EOF
60 map(
61 select(
62 (.tag_name == "$tag"))) |
63 first
64 EOF
65 )
66 else
67 query=$(cat <<EOF
68 map(
69 select(
70 ${lib.optionalString (!allowPrerelease) ".prerelease == false and"}
71 .draft == false and
72 (.tag_name | startswith("v${channel}")))) |
73 first
74 EOF
75 )
76 fi
77
78 query="$query "$(cat <<EOF
79 | (
80 .tag_name,
81 (.assets |
82 .[] |
83 select(.name == "release.json") |
84 .browser_download_url),
85 (.assets |
86 .[] |
87 select(.name | endswith(".tar.gz.sig")) |
88 .browser_download_url))
89 EOF
90 )
91
92 (
93 curl -fsSL https://api.github.com/repos/dotnet/dotnet/releases | \
94 jq -er "$query" \
95 ) | (
96 read tagName
97 read releaseUrl
98 read sigUrl
99
100 # TMPDIR might be really long, which breaks gpg
101 tmp="$(TMPDIR=/tmp mktemp -d)"
102 trap 'rm -rf "$tmp"' EXIT
103
104 cd "$tmp"
105
106 curl -fsSL "$releaseUrl" -o release.json
107
108 if [[ -z $tag && "$tagName" == "${tag}" ]]; then
109 >&2 echo "release is already $tagName"
110 exit
111 fi
112
113 tarballUrl=https://github.com/dotnet/dotnet/archive/refs/tags/$tagName.tar.gz
114
115 mapfile -t prefetch < <(nix-prefetch-url --print-path "$tarballUrl")
116 tarballHash=$(nix-hash --to-sri --type sha256 "''${prefetch[0]}")
117 tarball=''${prefetch[1]}
118
119 # recent dotnet 10 releases don't have a signature for the github tarball
120 if [[ ! $sigUrl = */dotnet-source-* ]]; then
121 curl -fssL "$sigUrl" -o release.sig
122
123 (
124 export GNUPGHOME=$PWD/.gnupg
125 mkdir -m 700 -p $GNUPGHOME
126 trap 'gpgconf --kill all' EXIT
127 gpg --no-autostart --batch --import ${releaseKey}
128 gpg --no-autostart --batch --verify release.sig "$tarball"
129 )
130 fi
131
132 tar --strip-components=1 --no-wildcards-match-slash --wildcards -xzf "$tarball" \*/eng/Versions.props \*/global.json \*/prep\*.sh
133 artifactsVersion=$(xq -r '.Project.PropertyGroup |
134 map(select(.PrivateSourceBuiltArtifactsVersion))
135 | .[] | .PrivateSourceBuiltArtifactsVersion' eng/Versions.props)
136
137 if [[ "$artifactsVersion" != "" ]]; then
138 artifactVar=$(grep ^defaultArtifactsRid= prep-source-build.sh)
139 eval "$artifactVar"
140
141 artifactsUrl=https://builds.dotnet.microsoft.com/${
142 if lib.versionAtLeast channel "10" then "dotnet/source-build" else "source-built-artifacts/assets"
143 }/Private.SourceBuilt.Artifacts.$artifactsVersion.$defaultArtifactsRid.tar.gz
144 else
145 artifactsUrl=$(xq -r '.Project.PropertyGroup |
146 map(select(.PrivateSourceBuiltArtifactsUrl))
147 | .[] | .PrivateSourceBuiltArtifactsUrl' eng/Versions.props)
148 fi
149 artifactsUrl="''${artifactsUrl/dotnetcli.azureedge.net/builds.dotnet.microsoft.com}"
150
151 artifactsHash=$(nix-hash --to-sri --type sha256 "$(nix-prefetch-url "$artifactsUrl")")
152
153 sdkVersion=$(jq -er .tools.dotnet global.json)
154
155 # below needs to be run in nixpkgs because toOutputPath uses relative paths
156 cd -
157
158 cp "$tmp"/release.json "${toOutputPath releaseManifestFile}"
159
160 jq --null-input \
161 --arg _0 "$tarballHash" \
162 --arg _1 "$artifactsUrl" \
163 --arg _2 "$artifactsHash" \
164 '{
165 "tarballHash": $_0,
166 "artifactsUrl": $_1,
167 "artifactsHash": $_2,
168 }' > "${toOutputPath releaseInfoFile}"
169
170 updateSDK() {
171 ${lib.escapeShellArg (toOutputPath ./update.sh)} \
172 -o ${lib.escapeShellArg (toOutputPath bootstrapSdkFile)} --sdk "$1" >&2
173 }
174
175 updateSDK "$sdkVersion" || if [[ $? == 2 ]]; then
176 >&2 echo "WARNING: bootstrap sdk missing, attempting to bootstrap with self"
177 updateSDK "$(jq -er .sdkVersion "$tmp"/release.json)"
178 else
179 exit 1
180 fi
181
182 $(nix-build -A $UPDATE_NIX_ATTR_PATH.fetch-deps --no-out-link) >&2
183 )
184''