Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 76 additions & 1 deletion .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,86 @@ jobs:
name: ${{ matrix.os }}-${{ matrix.rid }}-${{ matrix.configuration }}
path: ${{ github.workspace }}/artifacts/**/*

macos:
runs-on: ${{ matrix.os }}
name: Bootstrap ${{ matrix.rid }}-${{ matrix.configuration }}
needs: [setup]
strategy:
matrix:
configuration: [Debug, Release]
rid: [osx-x64, osx-arm64]
os: [macos-latest]
env:
SNAPX_VERSION: ${{ needs.setup.outputs.SNAPX_VERSION }}
SNAPX_DOTNET_FRAMEWORK_VERSION: ${{ needs.setup.outputs.SNAPX_DOTNET_FRAMEWORK_VERSION }}
DOTNET_NET100_VERSION: ${{ needs.setup.outputs.DOTNET_NET100_VERSION }}
DOTNET_NET90_VERSION: ${{ needs.setup.outputs.DOTNET_NET90_VERSION }}
DOTNET_NET80_VERSION: ${{ needs.setup.outputs.DOTNET_NET80_VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v5
with:
lfs: true
submodules: true

- name: Install .NET 8.0
uses: actions/setup-dotnet@v4.2.0
with:
dotnet-version: ${{ env.DOTNET_NET80_VERSION }}

- name: Install .NET 9.0
uses: actions/setup-dotnet@v4.2.0
with:
dotnet-version: ${{ env.DOTNET_NET90_VERSION }}

- name: Install .NET 10.0
uses: actions/setup-dotnet@v4.2.0
with:
dotnet-version: ${{ env.DOTNET_NET100_VERSION }}

- name: Bootstrap ${{ matrix.rid }}-${{ matrix.configuration }}
shell: pwsh
run: ./build.ps1 Bootstrap-Unix -Version ${{ env.SNAPX_VERSION }} -Configuration ${{ matrix.configuration }} -CIBuild -NetCoreAppVersion ${{ env.SNAPX_DOTNET_FRAMEWORK_VERSION }} -Rid ${{ matrix.rid }}

- name: Test native
shell: pwsh
run: ./build.ps1 Run-Native-UnitTests -Version ${{ env.SNAPX_VERSION }} -Configuration ${{ matrix.configuration }} -CIBuild -NetCoreAppVersion ${{ env.SNAPX_DOTNET_FRAMEWORK_VERSION }} -Rid ${{ matrix.rid }}

- name: Test .NET
shell: pwsh
run: ./build.ps1 Run-Dotnet-UnitTests -Version ${{ env.SNAPX_VERSION }} -Configuration ${{ matrix.configuration }} -CIBuild -NetCoreAppVersion ${{ env.SNAPX_DOTNET_FRAMEWORK_VERSION }} -Rid ${{ matrix.rid }}

- name: Collect artifacts
env:
SNAPX_MACOS_SETUP_ZIP_REL_DIR: build/dotnet/${{ matrix.rid }}/Snap.Installer/${{ env.SNAPX_DOTNET_FRAMEWORK_VERSION }}/${{ matrix.configuration }}/publish
SNAPX_MACOS_CORERUN_REL_DIR: build/native/Unix/${{ matrix.rid }}/${{ matrix.configuration }}/Snap.CoreRun
SNAPX_MACOS_PAL_REL_DIR: build/native/Unix/${{ matrix.rid }}/${{ matrix.configuration }}/Snap.CoreRun.Pal
SNAPX_MACOS_BSDIFF_REL_DIR: build/native/Unix/${{ matrix.rid }}/${{ matrix.configuration }}/Snap.Bsdiff
run: |
mkdir -p ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_SETUP_ZIP_REL_DIR }}
cp ${{ github.workspace }}/${{ env.SNAPX_MACOS_SETUP_ZIP_REL_DIR }}/Setup-${{ matrix.rid }}.zip ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_SETUP_ZIP_REL_DIR }}/Setup-${{ matrix.rid }}.zip

mkdir -p ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_CORERUN_REL_DIR }}
cp ${{ github.workspace }}/${{ env.SNAPX_MACOS_CORERUN_REL_DIR }}/corerun ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_CORERUN_REL_DIR }}/corerun.bin

mkdir -p ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_PAL_REL_DIR }}
cp ${{ github.workspace }}/${{ env.SNAPX_MACOS_PAL_REL_DIR }}/libpal.dylib ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_PAL_REL_DIR }}/libpal.dylib

mkdir -p ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_BSDIFF_REL_DIR }}
cp ${{ github.workspace }}/${{ env.SNAPX_MACOS_BSDIFF_REL_DIR }}/libsnap_bsdiff.dylib ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_BSDIFF_REL_DIR }}/libsnap_bsdiff.dylib

- name: Upload artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.os }}-${{ matrix.rid }}-${{ matrix.configuration }}
path: ${{ github.workspace }}/artifacts/**/*

publish:
if: success()
runs-on: ubuntu-latest
name: Nupkg
needs: [setup, windows, linux] # todo: enable me when github actions supports arm64: test-linux-arm64
needs: [setup, windows, linux, macos] # todo: enable me when github actions supports arm64: test-linux-arm64
env:
SNAPX_VERSION: ${{ needs.setup.outputs.SNAPX_VERSION }}
DOTNET_NET100_VERSION: ${{ needs.setup.outputs.DOTNET_NET100_VERSION }}
Expand Down
8 changes: 7 additions & 1 deletion bootstrap.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ param(
[Parameter(Position = 2, ValueFromPipelineByPropertyName = $true)]
[switch] $Lto,
[Parameter(Position = 3, ValueFromPipelineByPropertyName = $true)]
[ValidateSet("win-x86", "win-x64", "linux-x64", "linux-arm64")]
[ValidateSet("win-x86", "win-x64", "linux-x64", "linux-arm64", "osx-x64", "osx-arm64")]
[string] $Rid = $null,
[Parameter(Position = 4, ValueFromPipelineByPropertyName = $true, Mandatory = $true)]
[string] $NetCoreAppVersion,
Expand Down Expand Up @@ -211,6 +211,12 @@ function Invoke-Build-Snap-Installer {
"linux-arm64" {
$SnapInstallerExeName = "Snap.Installer"
}
"osx-x64" {
$SnapInstallerExeName = "Snap.Installer"
}
"osx-arm64" {
$SnapInstallerExeName = "Snap.Installer"
}
default {
Write-Error "Rid not supported: $Rid"
}
Expand Down
2 changes: 2 additions & 0 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ function Invoke-Build-Rids-Array {
if($Rid -eq "any") {
$Rids += "linux-x64"
$Rids += "linux-arm64"
$Rids += "osx-x64"
$Rids += "osx-arm64"
} else {
$Rids += $Rid
}
Expand Down
18 changes: 17 additions & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,23 @@
</PropertyGroup>

<PropertyGroup Condition="$(OsPlatform) == 'MACOSX'">
<DefineConstants>$(DefineConstants);PLATFORM_MAXOSX;</DefineConstants>
<DefineConstants>$(DefineConstants);PLATFORM_MACOSX;</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="$(OsPlatform) == 'MACOSX' AND $(SnapRid) == 'osx-x64'">
<DefineConstants>$(DefineConstants);PLATFORM_MACOSX_X64;</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="$(OsPlatform) == 'MACOSX' AND $(SnapRid) == 'osx-arm64'">
<DefineConstants>$(DefineConstants);PLATFORM_MACOSX_ARM64;</DefineConstants>
</PropertyGroup>

<PropertyGroup>
<GitVersionToolVersion>6.4.0</GitVersionToolVersion>
<SnapxDotNetFrameworkVersion>net10.0</SnapxDotNetFrameworkVersion>
<DotNetNet80Version>8.0.414</DotNetNet80Version>
<DotNetNet90Version>9.0.305</DotNetNet90Version>
<DotNetNet100Version>10.0.100-rc.1.25451.107</DotNetNet100Version>
</PropertyGroup>

<PropertyGroup>
Expand Down
12 changes: 9 additions & 3 deletions src/Snap.CoreRun.Pal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,15 @@ elseif (UNIX)
libstdc++.a
)

list(APPEND pal_DEFINES
PAL_PLATFORM_LINUX
)
if(APPLE)
list(APPEND pal_DEFINES
PAL_PLATFORM_MACOS
)
else()
list(APPEND pal_DEFINES
PAL_PLATFORM_LINUX
)
endif()

endif ()

Expand Down
24 changes: 23 additions & 1 deletion src/Snap.CoreRun.Pal/src/include/pal/pal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@
#define PAL_API
#define PAL_CALLING_CONVENTION
#endif
#elif PAL_PLATFORM_MACOS
#include <climits>
#include <cstdio>
#include <cstdint>
#include <sys/wait.h>
#include <sys/stat.h> // mode_t
#define PAL_MAX_PATH PATH_MAX
#define PAL_DIRECTORY_SEPARATOR_STR "/"
#define PAL_DIRECTORY_SEPARATOR_C '/'
#define PAL_CORECLR_TPA_SEPARATOR_STR ":"
#define PAL_CORECLR_TPA_SEPARATOR_C ':'
#if defined(__GNUC__)
#define PAL_API __attribute__((visibility("default")))
#define PAL_CALLING_CONVENTION
#else
#define PAL_API
#define PAL_CALLING_CONVENTION
#endif
#else
#error Unsupported platform
#endif
Expand All @@ -79,6 +97,10 @@ typedef DWORD pal_exit_code_t;
typedef pid_t pal_pid_t;
typedef mode_t pal_mode_t;
typedef int pal_exit_code_t;
#elif defined(PAL_PLATFORM_MACOS)
typedef pid_t pal_pid_t;
typedef mode_t pal_mode_t;
typedef int pal_exit_code_t;
#endif

// - Callbacks
Expand Down Expand Up @@ -135,7 +157,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_8_or_greater();
PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_7_or_greater();

PAL_API BOOL PAL_CALLING_CONVENTION pal_is_linux();

PAL_API BOOL PAL_CALLING_CONVENTION pal_is_macos();
PAL_API BOOL PAL_CALLING_CONVENTION pal_is_unknown_os();

// - Environment
Expand Down
22 changes: 21 additions & 1 deletion src/Snap.CoreRun.Pal/src/pal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@
#include <csignal> // kill
#include <ctime> // nanosleep
static const char *symlink_entrypoint_executable = "/proc/self/exe";
#elif defined(PAL_PLATFORM_MACOS)
#include <sys/wait.h> // wait
#include <unistd.h> // getcwd
#include <fcntl.h> // open
#include <dirent.h> // opendir
#include <libgen.h> // dirname
#include <dlfcn.h> // dlopen
#include <csignal> // kill
#include <ctime> // nanosleep
#include <mach-o/dyld.h> // _NSGetExecutablePath
static const char* symlink_entrypoint_executable = nullptr; // macOS uses different approach
#endif

#include <regex>
Expand Down Expand Up @@ -607,7 +618,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_sleep_ms(const uint32_t milliseconds) {
#if defined(PAL_PLATFORM_WINDOWS)
Sleep(milliseconds);
return TRUE;
#elif defined(PAL_PLATFORM_LINUX)
#elif defined(PAL_PLATFORM_LINUX) || defined(PAL_PLATFORM_MACOS)
struct timespec ts = {0};
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
Expand Down Expand Up @@ -650,9 +661,18 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_linux() {
#endif
}

PAL_API BOOL PAL_CALLING_CONVENTION pal_is_macos() {
#if defined(PAL_PLATFORM_MACOS)
return TRUE;
#else
return FALSE;
#endif
}

PAL_API BOOL PAL_CALLING_CONVENTION pal_is_unknown_os() {
return pal_is_linux()
|| pal_is_windows()
|| pal_is_macos()
? FALSE
: TRUE;
}
Expand Down
77 changes: 77 additions & 0 deletions src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#if PLATFORM_MACOSX
using Snap.AnyOS;
using Snap.AnyOS.MacOS;
using Snap.Core;
using Snap.Shared.Tests;
using Xunit;

namespace Snap.Tests.AnyOS.MacOS;

public class SnapOsMacOSTests : IClassFixture<BaseFixture>
{
readonly BaseFixture _baseFixture;
readonly ISnapFilesystem _snapFilesystem;
readonly ISnapOs _snapOs;
readonly SnapOsMacOS _snapOsMacOS;

public SnapOsMacOSTests(BaseFixture baseFixture)
{
_baseFixture = baseFixture;
_snapFilesystem = new SnapFilesystem();
_snapOsMacOS = new SnapOsMacOS(_snapFilesystem, new SnapOsProcessManager(), new SnapOsSpecialFoldersMacOS());
_snapOs = new SnapOs(_snapOsMacOS);
}

[Fact]
public void TestOsPlatform()
{
Assert.Equal(System.Runtime.InteropServices.OSPlatform.OSX, _snapOs.OsPlatform);
}

[Fact]
public void TestDistroType()
{
Assert.Equal(SnapOsDistroType.MacOS, _snapOs.DistroType);
}

[Fact]
public void TestSpecialFolders()
{
var specialFolders = _snapOs.SpecialFolders;

Assert.NotNull(specialFolders.ApplicationData);
Assert.NotNull(specialFolders.LocalApplicationData);
Assert.NotNull(specialFolders.DesktopDirectory);
Assert.NotNull(specialFolders.StartupDirectory);
Assert.NotNull(specialFolders.StartMenu);
Assert.NotNull(specialFolders.InstallerCacheDirectory);
Assert.NotNull(specialFolders.NugetCacheDirectory);

// macOS-specific path checks
Assert.Contains("Library/LaunchAgents", specialFolders.StartupDirectory);
Assert.Equal("/Applications", specialFolders.StartMenu);
Assert.Contains("snapx", specialFolders.InstallerCacheDirectory);
}

[Fact]
public void TestGetProcesses()
{
var processes = _snapOs.GetProcesses();
Assert.NotEmpty(processes);
}

[Fact]
public void TestUsername()
{
Assert.NotNull(_snapOsMacOS.Username);
Assert.NotEmpty(_snapOsMacOS.Username);
}

[Fact]
public void TestExitSignalHandler()
{
var exitSignalHandler = _snapOsMacOS.InstallExitSignalHandler();
Assert.NotNull(exitSignalHandler);
}
}
#endif
47 changes: 47 additions & 0 deletions src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#if PLATFORM_MACOSX
using Snap.AnyOS;
using Snap.Shared.Tests;
using Xunit;

namespace Snap.Tests.AnyOS.MacOS;

public class SnapOsSpecialFoldersMacOSTests : IClassFixture<BaseFixture>
{
readonly BaseFixture _baseFixture;

public SnapOsSpecialFoldersMacOSTests(BaseFixture baseFixture)
{
_baseFixture = baseFixture;
}

[Fact]
public void TestMacOSSpecialFolders()
{
var specialFolders = new SnapOsSpecialFoldersMacOS();

Assert.NotNull(specialFolders.ApplicationData);
Assert.NotNull(specialFolders.LocalApplicationData);
Assert.NotNull(specialFolders.DesktopDirectory);
Assert.NotNull(specialFolders.StartupDirectory);
Assert.NotNull(specialFolders.StartMenu);
Assert.NotNull(specialFolders.InstallerCacheDirectory);
Assert.NotNull(specialFolders.NugetCacheDirectory);

// Test macOS-specific paths
Assert.Contains("Library/LaunchAgents", specialFolders.StartupDirectory);
Assert.Equal("/Applications", specialFolders.StartMenu);
Assert.Contains("/snapx", specialFolders.InstallerCacheDirectory);
Assert.Contains("/temp/nuget", specialFolders.NugetCacheDirectory);
}

[Fact]
public void TestAnyOsReturnsMacOSOnMacOS()
{
if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX))
{
var anyOs = SnapOsSpecialFolders.AnyOs;
Assert.IsType<SnapOsSpecialFoldersMacOS>(anyOs);
}
}
}
#endif
2 changes: 1 addition & 1 deletion src/Snap.Tests/Snap.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<PropertyGroup>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading
Loading