diff --git a/.github/workflows/build-osx-arm64.yml b/.github/workflows/build-osx-arm64.yml new file mode 100644 index 00000000000..223a1a959ab --- /dev/null +++ b/.github/workflows/build-osx-arm64.yml @@ -0,0 +1,40 @@ +name: osx-arm64 Release Build + +on: + workflow_dispatch: + push: + branches: + - macos-arm64 + - macos-arm64-test + +jobs: + build: + runs-on: [self-hosted, macOS, ARM64] + steps: + - uses: actions/checkout@v1 + + # Build runner layout + - name: Build & Layout Release + run: | + ./dev.sh layout Release osx-arm64 + working-directory: src + + # Run tests + - name: L0 + run: | + ./dev.sh test + working-directory: src + + # Create runner package tar.gz/zip + - name: Package Release + run: | + ./dev.sh package Release osx-arm64 + working-directory: src + + # Upload runner package tar.gz/zip as artifact. + # Since each package name is unique, so we don't need to put ${{matrix}} info into artifact name + - name: Publish Artifact + uses: actions/upload-artifact@v1 + with: + name: runner-packages + path: _package diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 71e570e08d7..1931b7f8f08 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -25,9 +25,12 @@ $(DefineConstants);X86 - + $(DefineConstants);X64 + + $(DefineConstants);ARM64 + $(DefineConstants);X64 diff --git a/src/Misc/contentHash/dotnetRuntime/osx-arm64 b/src/Misc/contentHash/dotnetRuntime/osx-arm64 new file mode 100644 index 00000000000..e9b076a19af --- /dev/null +++ b/src/Misc/contentHash/dotnetRuntime/osx-arm64 @@ -0,0 +1 @@ +a1860fe3695b8aa71ad9ff748cfb011c51edb42f15b490aa8a617112b25a7ae8 diff --git a/src/Misc/contentHash/externals/osx-arm64 b/src/Misc/contentHash/externals/osx-arm64 new file mode 100644 index 00000000000..b2601211c30 --- /dev/null +++ b/src/Misc/contentHash/externals/osx-arm64 @@ -0,0 +1 @@ +3e7f1001760d4c84e7d77aaba3f2d2427920194b03099cc12e55c337a8b003f2 diff --git a/src/Misc/externals.sh b/src/Misc/externals.sh index fe7a74b9a0d..0a93e169711 100755 --- a/src/Misc/externals.sh +++ b/src/Misc/externals.sh @@ -134,12 +134,20 @@ if [[ "$PACKAGERUNTIME" == "win-x64" || "$PACKAGERUNTIME" == "win-x86" ]]; then fi fi -# Download the external tools only for OSX. +# Download the external tools only for OSX X64. if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-x64.tar.gz" node12 fix_nested_dir acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-darwin-x64.tar.gz" node16 fix_nested_dir fi +# Download the external tools only for OSX ARM64. +if [[ "$PACKAGERUNTIME" == "osx-arm64" ]]; then + # Node 12 is not available, fallback to Node 16 instead + NODE12_VERSION="${NODE16_VERSION}" + acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-arm64.tar.gz" node12 fix_nested_dir + acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-darwin-arm64.tar.gz" node16 fix_nested_dir +fi + # Download the external tools for Linux PACKAGERUNTIMEs. if [[ "$PACKAGERUNTIME" == "linux-x64" ]]; then acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-x64.tar.gz" node12 fix_nested_dir diff --git a/src/Runner.Common/Runner.Common.csproj b/src/Runner.Common/Runner.Common.csproj index bf55ea845da..84bb6e4c0ce 100644 --- a/src/Runner.Common/Runner.Common.csproj +++ b/src/Runner.Common/Runner.Common.csproj @@ -3,7 +3,7 @@ net6.0 Library - win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64 + win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64 true NU1701;NU1603 $(Version) diff --git a/src/Runner.Listener/Runner.Listener.csproj b/src/Runner.Listener/Runner.Listener.csproj index a327bd298d7..1aa14e38601 100644 --- a/src/Runner.Listener/Runner.Listener.csproj +++ b/src/Runner.Listener/Runner.Listener.csproj @@ -3,7 +3,7 @@ net6.0 Exe - win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64 + win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64 true NU1701;NU1603 $(Version) diff --git a/src/Runner.Listener/Runner.cs b/src/Runner.Listener/Runner.cs index 5ef0a3d6431..0a1d2193c31 100644 --- a/src/Runner.Listener/Runner.cs +++ b/src/Runner.Listener/Runner.cs @@ -404,6 +404,7 @@ private async Task RunAsync(RunnerSettings settings, bool runOnce = false) HostContext.WritePerfCounter($"MessageReceived_{message.MessageType}"); if (string.Equals(message.MessageType, AgentRefreshMessage.MessageType, StringComparison.OrdinalIgnoreCase)) { +#if !(OS_OSX && ARM64) if (autoUpdateInProgress == false) { autoUpdateInProgress = true; @@ -437,6 +438,7 @@ private async Task RunAsync(RunnerSettings settings, bool runOnce = false) { Trace.Info("Refresh message received, skip autoupdate since a previous autoupdate is already running."); } +#endif } else if (string.Equals(message.MessageType, JobRequestMessageTypes.PipelineAgentJobRequest, StringComparison.OrdinalIgnoreCase)) { diff --git a/src/Runner.PluginHost/Runner.PluginHost.csproj b/src/Runner.PluginHost/Runner.PluginHost.csproj index a7418bb8d9c..7937a25164d 100644 --- a/src/Runner.PluginHost/Runner.PluginHost.csproj +++ b/src/Runner.PluginHost/Runner.PluginHost.csproj @@ -3,7 +3,7 @@ net6.0 Exe - win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64 + win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64 true NU1701;NU1603 $(Version) diff --git a/src/Runner.Plugins/Runner.Plugins.csproj b/src/Runner.Plugins/Runner.Plugins.csproj index daa86f02687..8314aea5187 100644 --- a/src/Runner.Plugins/Runner.Plugins.csproj +++ b/src/Runner.Plugins/Runner.Plugins.csproj @@ -3,7 +3,7 @@ net6.0 Library - win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64 + win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64 true NU1701;NU1603 $(Version) diff --git a/src/Runner.Sdk/Runner.Sdk.csproj b/src/Runner.Sdk/Runner.Sdk.csproj index e0294afc6a3..63d6c0e186d 100644 --- a/src/Runner.Sdk/Runner.Sdk.csproj +++ b/src/Runner.Sdk/Runner.Sdk.csproj @@ -3,7 +3,7 @@ net6.0 Library - win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64 + win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64 true NU1701;NU1603 $(Version) diff --git a/src/Runner.Worker/Runner.Worker.csproj b/src/Runner.Worker/Runner.Worker.csproj index 40779c33bf3..f949b60375d 100644 --- a/src/Runner.Worker/Runner.Worker.csproj +++ b/src/Runner.Worker/Runner.Worker.csproj @@ -3,7 +3,7 @@ net6.0 Exe - win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64 + win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64 true NU1701;NU1603 $(Version) diff --git a/src/Sdk/Sdk.csproj b/src/Sdk/Sdk.csproj index 133f99a419e..44f6c794165 100644 --- a/src/Sdk/Sdk.csproj +++ b/src/Sdk/Sdk.csproj @@ -3,7 +3,7 @@ net6.0 Library - win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64 + win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64 true NU1701;NU1603 $(Version) diff --git a/src/Test/L0/ConstantGenerationL0.cs b/src/Test/L0/ConstantGenerationL0.cs index d964ba4743f..69c3a0bd469 100644 --- a/src/Test/L0/ConstantGenerationL0.cs +++ b/src/Test/L0/ConstantGenerationL0.cs @@ -19,7 +19,8 @@ public void BuildConstantGenerateSucceed() "linux-x64", "linux-arm", "linux-arm64", - "osx-x64" + "osx-x64", + "osx-arm64" }; Assert.True(BuildConstants.Source.CommitHash.Length == 40, $"CommitHash should be SHA-1 hash {BuildConstants.Source.CommitHash}"); diff --git a/src/Test/L0/Listener/RunnerL0.cs b/src/Test/L0/Listener/RunnerL0.cs index acaff40eb5f..ef4acf93ea5 100644 --- a/src/Test/L0/Listener/RunnerL0.cs +++ b/src/Test/L0/Listener/RunnerL0.cs @@ -418,6 +418,7 @@ public async void TestRunOnceOnlyTakeOneJobMessage() } } +#if !(OS_OSX && ARM64) [Fact] [Trait("Level", "L0")] [Trait("Category", "Runner")] @@ -503,5 +504,6 @@ public async void TestRunOnceHandleUpdateMessage() _messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny()), Times.Once()); } } +#endif } } diff --git a/src/Test/L0/Listener/SelfUpdaterL0.cs b/src/Test/L0/Listener/SelfUpdaterL0.cs index dbf8d220cd3..0f748e3eba7 100644 --- a/src/Test/L0/Listener/SelfUpdaterL0.cs +++ b/src/Test/L0/Listener/SelfUpdaterL0.cs @@ -13,6 +13,8 @@ using Moq; using Xunit; +#if !(OS_OSX && ARM64) + namespace GitHub.Runner.Common.Tests.Listener { public sealed class SelfUpdaterL0 @@ -791,3 +793,5 @@ public async void TestSelfUpdateAsync_FallbackToFullPackage() } } } + +#endif diff --git a/src/Test/L0/PackagesTrimL0.cs b/src/Test/L0/PackagesTrimL0.cs index 51a91b0ff00..e15b8592e71 100644 --- a/src/Test/L0/PackagesTrimL0.cs +++ b/src/Test/L0/PackagesTrimL0.cs @@ -208,7 +208,7 @@ public async Task RunnerLayoutParts_CheckDotnetRuntimeHash() killProcessOnCancel: true, cancellationToken: CancellationToken.None); - Assert.True(string.Equals(hashResult, File.ReadAllText(dotnetRuntimeHashFile).Trim()), $"Hash mismatch for dotnet runtime. You might need to update `Misc/contentHash/dotnetRuntime/{BuildConstants.RunnerPackage.PackageName}` or check if `hashFiles.ts` ever changed recently."); + Assert.True(string.Equals(hashResult, File.ReadAllText(dotnetRuntimeHashFile).Trim()), $"Hash mismatch for dotnet runtime. You might need to update `Misc/contentHash/dotnetRuntime/{BuildConstants.RunnerPackage.PackageName}` to '{hashResult}' or check if `hashFiles.ts` ever changed recently."); } } @@ -270,7 +270,7 @@ public async Task RunnerLayoutParts_CheckExternalsHash() killProcessOnCancel: true, cancellationToken: CancellationToken.None); - Assert.True(string.Equals(hashResult, File.ReadAllText(externalsHashFile).Trim()), $"Hash mismatch for externals. You might need to update `Misc/contentHash/externals/{BuildConstants.RunnerPackage.PackageName}` or check if `hashFiles.ts` ever changed recently."); + Assert.True(string.Equals(hashResult, File.ReadAllText(externalsHashFile).Trim()), $"Hash mismatch for externals. You might need to update `Misc/contentHash/externals/{BuildConstants.RunnerPackage.PackageName}` to '{hashResult}' or check if `hashFiles.ts` ever changed recently."); } } } diff --git a/src/Test/L0/Worker/StepHostL0.cs b/src/Test/L0/Worker/StepHostL0.cs index 8666e2e0af5..08686a185ff 100644 --- a/src/Test/L0/Worker/StepHostL0.cs +++ b/src/Test/L0/Worker/StepHostL0.cs @@ -60,6 +60,11 @@ public async Task DetermineNodeRuntimeVersionInContainerAsync() [Trait("Category", "Worker")] public async Task DetermineNodeRuntimeVersionInAlpineContainerAsync() { + if (!Constants.Runner.PlatformArchitecture.Equals(Constants.Architecture.X64)) { + // Test only works on X64. + return; + } + using (TestHostContext hc = CreateTestContext()) { // Arrange. diff --git a/src/Test/Test.csproj b/src/Test/Test.csproj index 432d482237f..1e48b2baf41 100644 --- a/src/Test/Test.csproj +++ b/src/Test/Test.csproj @@ -1,7 +1,7 @@  net6.0 - win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64 + win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64 true NU1701;NU1603;NU1603;xUnit2013; diff --git a/src/dev.sh b/src/dev.sh index e7b075ca550..fc2929a65e1 100755 --- a/src/dev.sh +++ b/src/dev.sh @@ -54,6 +54,12 @@ elif [[ "$CURRENT_PLATFORM" == 'linux' ]]; then fi elif [[ "$CURRENT_PLATFORM" == 'darwin' ]]; then RUNTIME_ID='osx-x64' + if command -v uname > /dev/null; then + CPU_NAME=$(uname -m) + if [[ "$CPU_NAME" == "arm64" ]]; then + RUNTIME_ID="osx-arm64" + fi + fi fi if [[ -n "$DEV_TARGET_RUNTIME" ]]; then @@ -63,7 +69,7 @@ fi # Make sure current platform support publish the dotnet runtime # Windows can publish win-x86/x64 # Linux can publish linux-x64/arm/arm64 -# OSX can publish osx-x64 +# OSX can publish osx-x64/arm64 if [[ "$CURRENT_PLATFORM" == 'windows' ]]; then if [[ ("$RUNTIME_ID" != 'win-x86') && ("$RUNTIME_ID" != 'win-x64') ]]; then echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2 @@ -75,7 +81,7 @@ elif [[ "$CURRENT_PLATFORM" == 'linux' ]]; then exit 1 fi elif [[ "$CURRENT_PLATFORM" == 'darwin' ]]; then - if [[ ("$RUNTIME_ID" != 'osx-x64') ]]; then + if [[ ("$RUNTIME_ID" != 'osx-x64') && ("$RUNTIME_ID" != 'osx-arm64') ]]; then echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2 exit 1 fi