at master 370 lines 13 kB view raw
1{ 2 bash, 3 buildDotnetModule, 4 coreutils, 5 darwin, 6 dotnetCorePackages, 7 fetchFromGitHub, 8 fetchpatch, 9 gitMinimal, 10 glibc, 11 glibcLocales, 12 lib, 13 nixosTests, 14 stdenv, 15 which, 16 buildPackages, 17 runtimeShell, 18 # List of Node.js runtimes the package should support 19 nodeRuntimes ? [ 20 "node20" 21 "node24" 22 ], 23 nodejs_20, 24 nodejs_24, 25}: 26 27# Node.js runtimes supported by upstream 28assert builtins.all ( 29 x: 30 builtins.elem x [ 31 "node20" 32 "node24" 33 ] 34) nodeRuntimes; 35 36buildDotnetModule (finalAttrs: { 37 pname = "github-runner"; 38 version = "2.328.0"; 39 40 src = fetchFromGitHub { 41 owner = "actions"; 42 repo = "runner"; 43 tag = "v${finalAttrs.version}"; 44 hash = "sha256-3Q2bscLKdUBPx+5X0qxwtcy3CU6N/wE8yO1CcATSyBQ="; 45 leaveDotGit = true; 46 postFetch = '' 47 git -C $out rev-parse --short HEAD > $out/.git-revision 48 rm -rf $out/.git 49 ''; 50 }; 51 52 # The git commit is read during the build and some tests depend on a git repo to be present 53 # https://github.com/actions/runner/blob/22d1938ac420a4cb9e3255e47a91c2e43c38db29/src/dir.proj#L5 54 unpackPhase = '' 55 cp -r $src $TMPDIR/src 56 chmod -R +w $TMPDIR/src 57 cd $TMPDIR/src 58 ( 59 export PATH=${buildPackages.git}/bin:$PATH 60 git init 61 git config user.email "root@localhost" 62 git config user.name "root" 63 git add . 64 git commit -m "Initial commit" 65 git checkout -b v${finalAttrs.version} 66 ) 67 mkdir -p $TMPDIR/bin 68 cat > $TMPDIR/bin/git <<EOF 69 #!${runtimeShell} 70 if [ \$# -eq 1 ] && [ "\$1" = "rev-parse" ]; then 71 echo $(cat $TMPDIR/src/.git-revision) 72 exit 0 73 fi 74 exec ${buildPackages.git}/bin/git "\$@" 75 EOF 76 chmod +x $TMPDIR/bin/git 77 export PATH=$TMPDIR/bin:$PATH 78 ''; 79 80 patches = [ 81 # Replace some paths that originally point to Nix's read-only store 82 ./patches/host-context-dirs.patch 83 # Use GetDirectory() to obtain "diag" dir 84 ./patches/use-get-directory-for-diag.patch 85 # Don't try to install service 86 ./patches/dont-install-service.patch 87 # Access `.env` and `.path` relative to `$RUNNER_ROOT`, if set 88 ./patches/env-sh-use-runner-root.patch 89 # Fix FHS path: https://github.com/actions/runner/pull/2464 90 (fetchpatch { 91 name = "ln-fhs.patch"; 92 url = "https://github.com/actions/runner/commit/5ff0ce1.patch"; 93 hash = "sha256-2Vg3cKZK3cE/OcPDZkdN2Ro2WgvduYTTwvNGxwCfXas="; 94 }) 95 # Fix source path discovery in tests 96 ./patches/test-getsrcpath.patch 97 ]; 98 99 postPatch = '' 100 # Ignore changes to src/Runner.Sdk/BuildConstants.cs 101 substituteInPlace src/dir.proj \ 102 --replace-fail 'git update-index --assume-unchanged ./Runner.Sdk/BuildConstants.cs' \ 103 'true' 104 ''; 105 106 DOTNET_SYSTEM_GLOBALIZATION_INVARIANT = isNull glibcLocales; 107 LOCALE_ARCHIVE = lib.optionalString ( 108 !finalAttrs.DOTNET_SYSTEM_GLOBALIZATION_INVARIANT 109 ) "${glibcLocales}/lib/locale/locale-archive"; 110 111 postConfigure = '' 112 # Generate src/Runner.Sdk/BuildConstants.cs 113 dotnet msbuild \ 114 -t:GenerateConstant \ 115 -p:ContinuousIntegrationBuild=true \ 116 -p:Deterministic=true \ 117 -p:PackageRuntime="${dotnetCorePackages.systemToDotnetRid stdenv.hostPlatform.system}" \ 118 -p:RunnerVersion="${finalAttrs.version}" \ 119 src/dir.proj 120 ''; 121 122 nativeBuildInputs = [ 123 which 124 gitMinimal 125 # needed for `uname` 126 coreutils 127 ] 128 ++ lib.optionals (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64) [ 129 darwin.autoSignDarwinBinariesHook 130 ]; 131 132 buildInputs = [ 133 (lib.getLib stdenv.cc.cc) 134 bash 135 ]; 136 137 dotnet-sdk = dotnetCorePackages.sdk_8_0; 138 dotnet-runtime = dotnetCorePackages.runtime_8_0; 139 140 dotnetFlags = [ 141 "-p:PackageRuntime=${dotnetCorePackages.systemToDotnetRid stdenv.hostPlatform.system}" 142 ]; 143 144 # As given here: https://github.com/actions/runner/blob/0befa62/src/dir.proj#L33-L41 145 projectFile = [ 146 "src/Sdk/Sdk.csproj" 147 "src/Runner.Common/Runner.Common.csproj" 148 "src/Runner.Listener/Runner.Listener.csproj" 149 "src/Runner.Worker/Runner.Worker.csproj" 150 "src/Runner.PluginHost/Runner.PluginHost.csproj" 151 "src/Runner.Sdk/Runner.Sdk.csproj" 152 "src/Runner.Plugins/Runner.Plugins.csproj" 153 ]; 154 nugetDeps = ./deps.json; 155 156 doCheck = true; 157 158 __darwinAllowLocalNetworking = true; 159 160 # Fully qualified name of disabled tests 161 disabledTests = [ 162 "GitHub.Runner.Common.Tests.Listener.SelfUpdaterL0.TestSelfUpdateAsync" 163 "GitHub.Runner.Common.Tests.ProcessInvokerL0.OomScoreAdjIsInherited" 164 # intermittently failing 165 "GitHub.Runner.Common.Tests.ProcessExtensionL0.SuccessReadProcessEnv" 166 ] 167 ++ map (x: "GitHub.Runner.Common.Tests.Listener.SelfUpdaterL0.TestSelfUpdateAsync_${x}") [ 168 "Cancel_CloneHashTask_WhenNotNeeded" 169 "CloneHash_RuntimeAndExternals" 170 "DownloadRetry" 171 "FallbackToFullPackage" 172 "NoUpdateOnOldVersion" 173 "NotUseExternalsRuntimeTrimmedPackageOnHashMismatch" 174 "UseExternalsRuntimeTrimmedPackage" 175 "UseExternalsTrimmedPackage" 176 "ValidateHash" 177 ] 178 ++ map (x: "GitHub.Runner.Common.Tests.Listener.SelfUpdaterV2L0.${x}") [ 179 "TestSelfUpdateAsync_DownloadRetry" 180 "TestSelfUpdateAsync_ValidateHash" 181 "TestSelfUpdateAsync" 182 ] 183 ++ map (x: "GitHub.Runner.Common.Tests.Worker.ActionManagerL0.PrepareActions_${x}") [ 184 "CompositeActionWithActionfile_CompositeContainerNested" 185 "CompositeActionWithActionfile_CompositePrestepNested" 186 "CompositeActionWithActionfile_MaxLimit" 187 "CompositeActionWithActionfile_Node" 188 "DownloadActionFromGraph" 189 "NotPullOrBuildImagesMultipleTimes" 190 "RepositoryActionWithActionYamlFile_DockerHubImage" 191 "RepositoryActionWithActionfileAndDockerfile" 192 "RepositoryActionWithActionfile_DockerHubImage" 193 "RepositoryActionWithActionfile_Dockerfile" 194 "RepositoryActionWithActionfile_DockerfileRelativePath" 195 "RepositoryActionWithActionfile_Node" 196 "RepositoryActionWithDockerfile" 197 "RepositoryActionWithDockerfileInRelativePath" 198 "RepositoryActionWithDockerfilePrepareActions_Repository" 199 "RepositoryActionWithInvalidWrapperActionfile_Node" 200 "RepositoryActionWithWrapperActionfile_PreSteps" 201 ] 202 ++ map (x: "GitHub.Runner.Common.Tests.DotnetsdkDownloadScriptL0.${x}") [ 203 "EnsureDotnetsdkBashDownloadScriptUpToDate" 204 "EnsureDotnetsdkPowershellDownloadScriptUpToDate" 205 ] 206 ++ [ "GitHub.Runner.Common.Tests.Listener.RunnerL0.TestRunOnceHandleUpdateMessage" ] 207 # Tests for trimmed runner packages which aim at reducing the update size. Not relevant for Nix. 208 ++ map (x: "GitHub.Runner.Common.Tests.PackagesTrimL0.${x}") [ 209 "RunnerLayoutParts_CheckExternalsHash" 210 "RunnerLayoutParts_CheckDotnetRuntimeHash" 211 ] 212 # Strictly require a Debug configuration to work 213 ++ [ 214 # https://github.com/actions/runner/blob/da3412e/src/Runner.Common/HostContext.cs#L260-L266 215 "GitHub.Runner.Common.Tests.HostContextL0.AuthMigrationAutoReset" 216 ] 217 ++ lib.optionals (stdenv.hostPlatform.system == "aarch64-linux") [ 218 # "JavaScript Actions in Alpine containers are only supported on x64 Linux runners. Detected Linux Arm64" 219 "GitHub.Runner.Common.Tests.Worker.StepHostL0.DetermineNodeRuntimeVersionInAlpineContainerAsync" 220 "GitHub.Runner.Common.Tests.Worker.StepHostL0.DetermineNode20RuntimeVersionInAlpineContainerAsync" 221 "GitHub.Runner.Common.Tests.Worker.StepHostL0.DetermineNode24RuntimeVersionInAlpineContainerAsync" 222 ] 223 ++ lib.optionals finalAttrs.DOTNET_SYSTEM_GLOBALIZATION_INVARIANT [ 224 "GitHub.Runner.Common.Tests.Util.StringUtilL0.FormatUsesInvariantCulture" 225 "GitHub.Runner.Common.Tests.Worker.VariablesL0.Constructor_SetsOrdinalIgnoreCaseComparer" 226 "GitHub.Runner.Common.Tests.Worker.WorkerL0.DispatchCancellation" 227 "GitHub.Runner.Common.Tests.Worker.WorkerL0.DispatchRunNewJob" 228 ]; 229 230 testProjectFile = [ "src/Test/Test.csproj" ]; 231 232 preCheck = '' 233 # Required by some tests 234 export GITHUB_ACTIONS_RUNNER_TRACE=1 235 mkdir -p _layout/externals 236 '' 237 + lib.optionalString (lib.elem "node20" nodeRuntimes) '' 238 ln -s ${nodejs_20} _layout/externals/node20 239 '' 240 + lib.optionalString (lib.elem "node24" nodeRuntimes) '' 241 ln -s ${nodejs_24} _layout/externals/node24 242 ''; 243 244 postInstall = '' 245 mkdir -p $out/bin 246 247 install -m755 src/Misc/layoutbin/runsvc.sh $out/lib/github-runner 248 install -m755 src/Misc/layoutbin/RunnerService.js $out/lib/github-runner 249 install -m755 src/Misc/layoutroot/run.sh $out/lib/github-runner 250 install -m755 src/Misc/layoutroot/run-helper.sh.template $out/lib/github-runner/run-helper.sh 251 install -m755 src/Misc/layoutroot/config.sh $out/lib/github-runner 252 install -m755 src/Misc/layoutroot/env.sh $out/lib/github-runner 253 254 # env.sh is patched to not require any wrapping 255 ln -sr "$out/lib/github-runner/env.sh" "$out/bin/" 256 257 substituteInPlace $out/lib/github-runner/config.sh \ 258 --replace './bin/Runner.Listener' "$out/bin/Runner.Listener" 259 '' 260 + lib.optionalString stdenv.hostPlatform.isLinux '' 261 substituteInPlace $out/lib/github-runner/config.sh \ 262 --replace 'command -v ldd' 'command -v ${glibc.bin}/bin/ldd' \ 263 --replace 'ldd ./bin' '${glibc.bin}/bin/ldd ${finalAttrs.dotnet-runtime}/share/dotnet/shared/Microsoft.NETCore.App/${finalAttrs.dotnet-runtime.version}/' \ 264 --replace '/sbin/ldconfig' '${glibc.bin}/bin/ldconfig' 265 '' 266 + '' 267 # Remove uneeded copy for run-helper template 268 substituteInPlace $out/lib/github-runner/run.sh --replace 'cp -f "$DIR"/run-helper.sh.template "$DIR"/run-helper.sh' ' ' 269 substituteInPlace $out/lib/github-runner/run-helper.sh --replace '"$DIR"/bin/' '"$DIR"/' 270 271 # Make paths absolute 272 substituteInPlace $out/lib/github-runner/runsvc.sh \ 273 --replace './externals' "$out/lib/externals" \ 274 --replace './bin/RunnerService.js' "$out/lib/github-runner/RunnerService.js" 275 276 # The upstream package includes Node and expects it at the path 277 # externals/node$version. As opposed to the official releases, we don't 278 # link the Alpine Node flavors. 279 mkdir -p $out/lib/externals 280 '' 281 + lib.optionalString (lib.elem "node20" nodeRuntimes) '' 282 ln -s ${nodejs_20} $out/lib/externals/node20 283 '' 284 + lib.optionalString (lib.elem "node24" nodeRuntimes) '' 285 ln -s ${nodejs_24} $out/lib/externals/node24 286 '' 287 + '' 288 # Install Nodejs scripts called from workflows 289 install -D src/Misc/layoutbin/hashFiles/index.js $out/lib/github-runner/hashFiles/index.js 290 mkdir -p $out/lib/github-runner/checkScripts 291 install src/Misc/layoutbin/checkScripts/* $out/lib/github-runner/checkScripts/ 292 '' 293 + lib.optionalString stdenv.hostPlatform.isLinux '' 294 # Wrap explicitly to, e.g., prevent extra entries for LD_LIBRARY_PATH 295 makeWrapperArgs=() 296 297 # We don't wrap with libicu 298 substituteInPlace $out/lib/github-runner/config.sh \ 299 --replace '$LDCONFIG_COMMAND -NXv ''${libpath//:/ }' 'echo libicu' 300 '' 301 + '' 302 # XXX: Using the corresponding Nix argument does not work as expected: 303 # https://github.com/NixOS/nixpkgs/issues/218449 304 # Common wrapper args for `executables` 305 makeWrapperArgs+=( 306 --run 'export RUNNER_ROOT="''${RUNNER_ROOT:-"$HOME/.github-runner"}"' 307 --run 'mkdir -p "$RUNNER_ROOT"' 308 --chdir "$out" 309 ) 310 ''; 311 312 # List of files to wrap 313 executables = [ 314 "config.sh" 315 "Runner.Listener" 316 "Runner.PluginHost" 317 "Runner.Worker" 318 "run.sh" 319 "runsvc.sh" 320 ]; 321 322 doInstallCheck = true; 323 installCheckPhase = '' 324 runHook preInstallCheck 325 326 export RUNNER_ROOT="$TMPDIR" 327 328 $out/bin/config.sh --help >/dev/null 329 $out/bin/Runner.Listener --help >/dev/null 330 331 version=$($out/bin/Runner.Listener --version) 332 if [[ "$version" != "${finalAttrs.version}" ]]; then 333 printf 'Unexpected version %s' "$version" 334 exit 1 335 fi 336 337 commit=$($out/bin/Runner.Listener --commit) 338 if [[ "$commit" != "$(git rev-parse HEAD)" ]]; then 339 printf 'Unexpected commit %s' "$commit" 340 exit 1 341 fi 342 343 runHook postInstallCheck 344 ''; 345 346 passthru = { 347 tests.smoke-test = nixosTests.github-runner; 348 updateScript = ./update.sh; 349 }; 350 351 meta = { 352 changelog = "https://github.com/actions/runner/releases/tag/v${finalAttrs.version}"; 353 description = "Self-hosted runner for GitHub Actions"; 354 homepage = "https://github.com/actions/runner"; 355 license = lib.licenses.mit; 356 maintainers = with lib.maintainers; [ 357 veehaitch 358 kfollesdal 359 aanderse 360 zimbatm 361 ]; 362 platforms = [ 363 "x86_64-linux" 364 "aarch64-linux" 365 "x86_64-darwin" 366 "aarch64-darwin" 367 ]; 368 sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; 369 }; 370})