nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ autoPatchelfHook
2, coreutils
3, curl
4, dotnetCorePackages
5, dotnetPackages
6, fetchFromGitHub
7, fetchurl
8, git
9, glibc
10, icu
11, libkrb5
12, lib
13, linkFarmFromDrvs
14, lttng-ust
15, makeWrapper
16, nodejs-16_x
17, openssl
18, stdenv
19, zlib
20, writeShellApplication
21, nuget-to-nix
22# Keeping this option until upstream removes support for EoL Node.js 12 entirely
23# Also refer to: https://github.com/actions/runner/pull/1716
24, withNode12 ? false
25, nodejs-12_x
26}:
27let
28 nugetSource = linkFarmFromDrvs "nuget-packages" (
29 import ./deps.nix {
30 fetchNuGet = { pname, version, sha256 }: fetchurl {
31 name = "${pname}.${version}.nupkg";
32 url = "https://www.nuget.org/api/v2/package/${pname}/${version}";
33 inherit sha256;
34 };
35 }
36 );
37
38 dotnetSdk = dotnetCorePackages.sdk_6_0;
39 # Map Nix systems to .NET runtime ids
40 runtimeIds = {
41 "x86_64-linux" = "linux-x64";
42 "aarch64-linux" = "linux-arm64";
43 };
44 runtimeId = runtimeIds.${stdenv.system};
45 fakeSha1 = "0000000000000000000000000000000000000000";
46in
47stdenv.mkDerivation rec {
48 pname = "github-runner";
49 version = "2.291.1";
50
51 src = fetchFromGitHub {
52 owner = "actions";
53 repo = "runner";
54 rev = "v${version}";
55 hash = "sha256-0Eijq2vXY+Y2g3bhEhIGnFxTCLXpw7k3iXpgj3x8nL4=";
56 };
57
58 nativeBuildInputs = [
59 dotnetSdk
60 dotnetPackages.Nuget
61 makeWrapper
62 autoPatchelfHook
63 ];
64
65 buildInputs = [
66 curl # libcurl.so.4
67 libkrb5 # libgssapi_krb5.so.2
68 lttng-ust # liblttng-ust.so.0
69 stdenv.cc.cc.lib # libstdc++.so.6
70 zlib # libz.so.1
71 icu
72 ];
73
74 patches = [
75 # Don't run Git, no restore on build/test
76 ./patches/dir-proj.patch
77 # Replace some paths that originally point to Nix's read-only store
78 ./patches/host-context-dirs.patch
79 # Use GetDirectory() to obtain "diag" dir
80 ./patches/use-get-directory-for-diag.patch
81 # Don't try to install systemd service
82 ./patches/dont-install-systemd-service.patch
83 ];
84
85 postPatch = ''
86 # Relax the version requirement
87 substituteInPlace src/global.json \
88 --replace '6.0.100' '${dotnetSdk.version}'
89
90 # Disable specific tests
91 substituteInPlace src/dir.proj \
92 --replace 'dotnet test Test/Test.csproj' \
93 "dotnet test Test/Test.csproj --filter '${lib.concatStringsSep "&" (map (x: "FullyQualifiedName!=${x}") disabledTests)}'"
94
95 # We don't use a Git checkout
96 substituteInPlace src/dir.proj \
97 --replace 'git update-index --assume-unchanged ./Runner.Sdk/BuildConstants.cs' \
98 'echo Patched out.'
99
100 # Fix FHS path
101 substituteInPlace src/Test/L0/Util/IOUtilL0.cs \
102 --replace '/bin/ln' '${coreutils}/bin/ln'
103 '';
104
105 configurePhase = ''
106 runHook preConfigure
107
108 export HOME=$(mktemp -d)
109
110 # Never use nuget.org
111 nuget sources Disable -Name "nuget.org"
112
113 # Restore the dependencies
114 dotnet restore src/ActionsRunner.sln \
115 --runtime "${runtimeId}" \
116 --source "${nugetSource}"
117
118 runHook postConfigure
119 '';
120
121 buildPhase = ''
122 runHook preBuild
123
124 dotnet msbuild \
125 -t:Build \
126 -p:PackageRuntime="${runtimeId}" \
127 -p:BUILDCONFIG="Release" \
128 -p:RunnerVersion="${version}" \
129 -p:GitInfoCommitHash="${fakeSha1}" \
130 src/dir.proj
131
132 runHook postBuild
133 '';
134
135 doCheck = true;
136
137 # Fully qualified name of disabled tests
138 disabledTests =
139 [ "GitHub.Runner.Common.Tests.Listener.SelfUpdaterL0.TestSelfUpdateAsync" ]
140 ++ map (x: "GitHub.Runner.Common.Tests.Listener.SelfUpdaterL0.TestSelfUpdateAsync_${x}") [
141 "Cancel_CloneHashTask_WhenNotNeeded"
142 "CloneHash_RuntimeAndExternals"
143 "DownloadRetry"
144 "FallbackToFullPackage"
145 "NoUpdateOnOldVersion"
146 "NotUseExternalsRuntimeTrimmedPackageOnHashMismatch"
147 "UseExternalsRuntimeTrimmedPackage"
148 "UseExternalsTrimmedPackage"
149 "ValidateHash"
150 ]
151 ++ map (x: "GitHub.Runner.Common.Tests.Worker.ActionManagerL0.PrepareActions_${x}") [
152 "CompositeActionWithActionfile_CompositeContainerNested"
153 "CompositeActionWithActionfile_CompositePrestepNested"
154 "CompositeActionWithActionfile_MaxLimit"
155 "CompositeActionWithActionfile_Node"
156 "DownloadActionFromGraph"
157 "DownloadActionFromGraph_Legacy"
158 "NotPullOrBuildImagesMultipleTimes"
159 "NotPullOrBuildImagesMultipleTimes_Legacy"
160 "RepositoryActionWithActionYamlFile_DockerHubImage"
161 "RepositoryActionWithActionYamlFile_DockerHubImage_Legacy"
162 "RepositoryActionWithActionfileAndDockerfile"
163 "RepositoryActionWithActionfileAndDockerfile_Legacy"
164 "RepositoryActionWithActionfile_DockerHubImage"
165 "RepositoryActionWithActionfile_DockerHubImage_Legacy"
166 "RepositoryActionWithActionfile_Dockerfile"
167 "RepositoryActionWithActionfile_Dockerfile_Legacy"
168 "RepositoryActionWithActionfile_DockerfileRelativePath"
169 "RepositoryActionWithActionfile_DockerfileRelativePath_Legacy"
170 "RepositoryActionWithActionfile_Node"
171 "RepositoryActionWithActionfile_Node_Legacy"
172 "RepositoryActionWithDockerfile"
173 "RepositoryActionWithDockerfile_Legacy"
174 "RepositoryActionWithDockerfileInRelativePath"
175 "RepositoryActionWithDockerfileInRelativePath_Legacy"
176 "RepositoryActionWithDockerfilePrepareActions_Repository"
177 "RepositoryActionWithInvalidWrapperActionfile_Node"
178 "RepositoryActionWithInvalidWrapperActionfile_Node_Legacy"
179 "RepositoryActionWithWrapperActionfile_PreSteps"
180 "RepositoryActionWithWrapperActionfile_PreSteps_Legacy"
181 ]
182 ++ map (x: "GitHub.Runner.Common.Tests.DotnetsdkDownloadScriptL0.${x}") [
183 "EnsureDotnetsdkBashDownloadScriptUpToDate"
184 "EnsureDotnetsdkPowershellDownloadScriptUpToDate"
185 ]
186 ++ [ "GitHub.Runner.Common.Tests.Listener.RunnerL0.TestRunOnceHandleUpdateMessage" ]
187 # Tests for trimmed runner packages which aim at reducing the update size. Not relevant for Nix.
188 ++ map (x: "GitHub.Runner.Common.Tests.PackagesTrimL0.${x}") [
189 "RunnerLayoutParts_CheckExternalsHash"
190 "RunnerLayoutParts_CheckDotnetRuntimeHash"
191 ]
192 ++ lib.optionals (stdenv.hostPlatform.system == "aarch64-linux") [
193 # "JavaScript Actions in Alpine containers are only supported on x64 Linux runners. Detected Linux Arm64"
194 "GitHub.Runner.Common.Tests.Worker.StepHostL0.DetermineNodeRuntimeVersionInAlpineContainerAsync"
195 ]
196 ++ lib.optionals (!withNode12) [
197 "GitHub.Runner.Common.Tests.ProcessExtensionL0.SuccessReadProcessEnv"
198 ];
199 checkInputs = [ git ];
200
201 checkPhase = ''
202 runHook preCheck
203
204 mkdir -p _layout/externals
205 ${lib.optionalString withNode12 "ln -s ${nodejs-12_x} _layout/externals/node12"}
206 ln -s ${nodejs-16_x} _layout/externals/node16
207
208 printf 'Disabled tests:\n%s\n' '${lib.concatMapStringsSep "\n" (x: " - ${x}") disabledTests}'
209
210 # BUILDCONFIG needs to be "Debug"
211 dotnet msbuild \
212 -t:test \
213 -p:PackageRuntime="${runtimeId}" \
214 -p:BUILDCONFIG="Debug" \
215 -p:RunnerVersion="${version}" \
216 -p:GitInfoCommitHash="${fakeSha1}" \
217 src/dir.proj
218
219 runHook postCheck
220 '';
221
222 installPhase = ''
223 runHook preInstall
224
225 # Copy the built binaries to lib/ instead of bin/ as they
226 # have to be wrapped in the fixup phase to work
227 mkdir -p $out/lib
228 cp -r _layout/bin/. $out/lib/
229
230 # Delete debugging files
231 find "$out/lib" -type f -name '*.pdb' -delete
232
233 # Install the helper scripts to bin/ to resemble the upstream package
234 mkdir -p $out/bin
235 install -m755 src/Misc/layoutbin/runsvc.sh $out/bin/
236 install -m755 src/Misc/layoutbin/RunnerService.js $out/lib/
237 install -m755 src/Misc/layoutroot/run.sh $out/lib/
238 install -m755 src/Misc/layoutroot/config.sh $out/lib/
239 install -m755 src/Misc/layoutroot/env.sh $out/lib/
240
241 # Rewrite reference in helper scripts from bin/ to lib/
242 substituteInPlace $out/lib/run.sh --replace '"$DIR"/bin' "$out/lib"
243 substituteInPlace $out/lib/config.sh --replace './bin' "$out/lib"
244
245 # Make paths absolute
246 substituteInPlace $out/bin/runsvc.sh \
247 --replace './externals' "$out/externals" \
248 --replace './bin' "$out/lib"
249
250 # The upstream package includes Node {12,16} and expects it at the path
251 # externals/node{12,16}. As opposed to the official releases, we don't
252 # link the Alpine Node flavors.
253 mkdir -p $out/externals
254 ${lib.optionalString withNode12 "ln -s ${nodejs-12_x} $out/externals/node12"}
255 ln -s ${nodejs-16_x} $out/externals/node16
256
257 # Install Nodejs scripts called from workflows
258 install -D src/Misc/layoutbin/hashFiles/index.js $out/lib/hashFiles/index.js
259 mkdir -p $out/lib/checkScripts
260 install src/Misc/layoutbin/checkScripts/* $out/lib/checkScripts/
261
262 runHook postInstall
263 '';
264
265 # Stripping breaks the binaries
266 dontStrip = true;
267
268 preFixup = ''
269 patchelf --replace-needed liblttng-ust.so.0 liblttng-ust.so $out/lib/libcoreclrtraceptprovider.so
270 '';
271
272 postFixup = ''
273 fix_rpath() {
274 patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/lib/$1
275 }
276
277 wrap() {
278 makeWrapper $out/lib/$1 $out/bin/$1 \
279 --prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath (buildInputs ++ [ openssl ])} \
280 ''${@:2}
281 }
282
283 fix_rpath Runner.Listener
284 fix_rpath Runner.PluginHost
285 fix_rpath Runner.Worker
286
287 wrap Runner.Listener
288 wrap Runner.PluginHost
289 wrap Runner.Worker
290 wrap run.sh
291 wrap env.sh
292
293 wrap config.sh --prefix PATH : ${lib.makeBinPath [ glibc.bin ]}
294 '';
295
296 # Script to create deps.nix file for dotnet dependencies. Run it with
297 # $(nix-build -A github-runner.passthru.createDepsFile)/bin/create-deps-file
298 #
299 # Default output path is /tmp/${pname}-deps.nix, but can be overriden with cli argument.
300 #
301 # Inspired by passthru.fetch-deps in pkgs/build-support/build-dotnet-module/default.nix
302 passthru.createDepsFile = writeShellApplication {
303 name = "create-deps-file";
304 runtimeInputs = [ dotnetSdk nuget-to-nix ];
305 text = ''
306 # Disable telemetry data
307 export DOTNET_CLI_TELEMETRY_OPTOUT=1
308
309 rundir=$(pwd)
310
311 printf "\n* Setup workdir\n"
312 workdir="$(mktemp -d /tmp/${pname}.XXX)"
313 cp -rT "${src}" "$workdir"
314 chmod -R +w "$workdir"
315 trap 'rm -rf "$workdir"' EXIT
316
317 pushd "$workdir"
318
319 mkdir nuget_pkgs
320
321 ${lib.concatMapStrings (rid: ''
322 printf "\n* Restore ${pname} (${rid}) dotnet project\n"
323 dotnet restore src/ActionsRunner.sln --packages nuget_pkgs --no-cache --force --runtime "${rid}"
324 '') (lib.attrValues runtimeIds)}
325
326 cd "$rundir"
327 deps_file=''${1-"/tmp/${pname}-deps.nix"}
328 printf "\n* Make %s file\n" "$(basename "$deps_file")"
329 nuget-to-nix "$workdir/nuget_pkgs" > "$deps_file"
330 printf "\n* Dependency file writen to %s" "$deps_file"
331 '';
332 };
333
334 meta = with lib; {
335 description = "Self-hosted runner for GitHub Actions";
336 homepage = "https://github.com/actions/runner";
337 license = licenses.mit;
338 maintainers = with maintainers; [ veehaitch newam kfollesdal ];
339 platforms = attrNames runtimeIds;
340 };
341}