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 tmp="$(mktemp -d)"
101 trap 'rm -rf "$tmp"' EXIT
102
103 cd "$tmp"
104
105 curl -fsSL "$releaseUrl" -o release.json
106
107 if [[ -z $tag && "$tagName" == "${tag}" ]]; then
108 >&2 echo "release is already $tagName"
109 exit
110 fi
111
112 tarballUrl=https://github.com/dotnet/dotnet/archive/refs/tags/$tagName.tar.gz
113
114 mapfile -t prefetch < <(nix-prefetch-url --print-path "$tarballUrl")
115 tarballHash=$(nix-hash --to-sri --type sha256 "''${prefetch[0]}")
116 tarball=''${prefetch[1]}
117
118 curl -fssL "$sigUrl" -o release.sig
119
120 (
121 export GNUPGHOME=$PWD/.gnupg
122 trap 'gpgconf --kill all' EXIT
123 gpg --batch --import ${releaseKey}
124 gpg --batch --verify release.sig "$tarball"
125 )
126
127 tar --strip-components=1 --no-wildcards-match-slash --wildcards -xzf "$tarball" \*/eng/Versions.props \*/global.json \*/prep\*.sh
128 artifactsVersion=$(xq -r '.Project.PropertyGroup |
129 map(select(.PrivateSourceBuiltArtifactsVersion))
130 | .[] | .PrivateSourceBuiltArtifactsVersion' eng/Versions.props)
131
132 if [[ "$artifactsVersion" != "" ]]; then
133 artifactVar=$(grep ^defaultArtifactsRid= prep-source-build.sh)
134 eval "$artifactVar"
135
136 artifactsUrl=https://builds.dotnet.microsoft.com/source-built-artifacts/assets/Private.SourceBuilt.Artifacts.$artifactsVersion.$defaultArtifactsRid.tar.gz
137 else
138 artifactsUrl=$(xq -r '.Project.PropertyGroup |
139 map(select(.PrivateSourceBuiltArtifactsUrl))
140 | .[] | .PrivateSourceBuiltArtifactsUrl' eng/Versions.props)
141 fi
142 artifactsUrl="''${artifactsUrl/dotnetcli.azureedge.net/builds.dotnet.microsoft.com}"
143
144 artifactsHash=$(nix-hash --to-sri --type sha256 "$(nix-prefetch-url "$artifactsUrl")")
145
146 sdkVersion=$(jq -er .tools.dotnet global.json)
147
148 # below needs to be run in nixpkgs because toOutputPath uses relative paths
149 cd -
150
151 cp "$tmp"/release.json "${toOutputPath releaseManifestFile}"
152
153 jq --null-input \
154 --arg _0 "$tarballHash" \
155 --arg _1 "$artifactsUrl" \
156 --arg _2 "$artifactsHash" \
157 '{
158 "tarballHash": $_0,
159 "artifactsUrl": $_1,
160 "artifactsHash": $_2,
161 }' > "${toOutputPath releaseInfoFile}"
162
163 updateSDK() {
164 ${lib.escapeShellArg (toOutputPath ./update.sh)} \
165 -o ${lib.escapeShellArg (toOutputPath bootstrapSdkFile)} --sdk "$1" >&2
166 }
167
168 updateSDK "$sdkVersion" || if [[ $? == 2 ]]; then
169 >&2 echo "WARNING: bootstrap sdk missing, attempting to bootstrap with self"
170 updateSDK "$(jq -er .sdkVersion "$tmp"/release.json)"
171 else
172 exit 1
173 fi
174
175 $(nix-build -A $UPDATE_NIX_ATTR_PATH.fetch-deps --no-out-link) >&2
176 )
177''