Skip to content

Commit 9aba4cd

Browse files
committed
Provide MUSL-based build
Fixes #408
1 parent bac42d3 commit 9aba4cd

File tree

5 files changed

+70
-12
lines changed

5 files changed

+70
-12
lines changed

.github/workflows/package.yml

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
fail-fast: false
1212
matrix:
13-
os: [ubuntu-latest, ubuntu-arm, macos-intel, macos-arm, windows-latest]
13+
os: [ubuntu-latest, ubuntu-arm, alpine-latest, macos-intel, macos-arm, windows-latest]
1414
include:
1515
- os: ubuntu-latest
1616
out-file: libtemporal_sdk_bridge.so
@@ -25,6 +25,13 @@ jobs:
2525
# We use the Python manylinux image for glibc compatibility
2626
container: quay.io/pypa/manylinux2014_aarch64
2727
protobuf-url: https://github.com/protocolbuffers/protobuf/releases/download/v22.3/protoc-22.3-linux-aarch_64.zip
28+
- os: alpine-latest
29+
out-file: libtemporal_sdk_bridge.so
30+
out-prefix: linux-musl-x64
31+
# Need Alpine container since GH runner doesn't have one
32+
container: mcr.microsoft.com/dotnet/sdk:8.0-alpine
33+
protobuf-url: https://github.com/protocolbuffers/protobuf/releases/download/v22.3/protoc-22.3-linux-x86_64.zip
34+
runsOn: ubuntu-latest
2835
- os: macos-intel
2936
out-file: libtemporal_sdk_bridge.dylib
3037
out-prefix: osx-x64
@@ -68,8 +75,8 @@ jobs:
6875
if: ${{ !matrix.container }}
6976
run: cargo build --manifest-path src/Temporalio/Bridge/Cargo.toml --release
7077

71-
- name: Build (Docker)
72-
if: ${{ matrix.container }}
78+
- name: Build (Docker non-Alpine)
79+
if: ${{ matrix.container && matrix.os != 'alpine-latest' }}
7380
run: |
7481
docker run --rm -v "$(pwd):/workspace" -w /workspace \
7582
${{ matrix.container }} \
@@ -82,11 +89,27 @@ jobs:
8289
&& cargo build --manifest-path src/Temporalio/Bridge/Cargo.toml --release \
8390
'
8491
92+
- name: Build (Docker Alpine)
93+
if: ${{ matrix.container && matrix.os == 'alpine-latest' }}
94+
run: |
95+
docker run --rm -v "$(pwd):/workspace" -w /workspace \
96+
${{ matrix.container }} \
97+
sh -c ' \
98+
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y \
99+
&& . $HOME/.cargo/env \
100+
&& apk add --no-cache build-base \
101+
&& curl -LO ${{ matrix.protobuf-url }} \
102+
&& unzip protoc-*.zip -d /usr/local/protobuf \
103+
&& export PATH="$PATH:/usr/local/protobuf/bin" \
104+
&& RUSTFLAGS="-C target-feature=-crt-static" cargo build --manifest-path src/Temporalio/Bridge/Cargo.toml --release \
105+
'
106+
85107
- name: Upload bridge library
86108
uses: actions/upload-artifact@v4
87109
with:
88110
name: ${{ matrix.out-prefix }}-bridge
89111
path: src/Temporalio/Bridge/target/release/${{ matrix.out-file }}
112+
if-no-files-found: error
90113

91114
build-nuget-package:
92115
needs:
@@ -129,15 +152,19 @@ jobs:
129152
strategy:
130153
fail-fast: false
131154
matrix:
132-
os: [ubuntu-latest, ubuntu-arm, macos-intel, macos-arm, windows-latest]
155+
os: [ubuntu-latest, ubuntu-arm, alpine-latest, macos-intel, macos-arm, windows-latest]
133156
include:
134157
- os: ubuntu-arm
135158
runsOn: buildjet-4vcpu-ubuntu-2204-arm
159+
- os: alpine-latest
160+
container: mcr.microsoft.com/dotnet/sdk:6.0-alpine
161+
runsOn: ubuntu-latest
136162
- os: macos-intel
137163
runsOn: macos-13
138164
- os: macos-arm
139165
runsOn: macos-14
140166
runs-on: ${{ matrix.runsOn || matrix.os }}
167+
container: ${{ matrix.container }}
141168
steps:
142169
- name: Checkout repository
143170
uses: actions/checkout@v4
@@ -148,18 +175,30 @@ jobs:
148175
uses: actions/download-artifact@v4
149176
with:
150177
name: nuget-package
151-
path: nuget-package
178+
path: ${{ github.workspace }}/nuget-package
152179

153-
- name: Setup .NET
180+
- name: Setup .NET (non-Alpine)
154181
uses: actions/setup-dotnet@v4
182+
if: ${{ matrix.os != 'alpine-latest' }}
155183
with:
156184
# Specific .NET version required because GitHub macos ARM image has
157185
# bad pre-installed .NET version
158186
dotnet-version: 6.x
159187

160-
- name: Run smoke test
188+
- name: Setup .NET (Alpine)
189+
if: ${{ matrix.os == 'alpine-latest' }}
190+
run: apk add dotnet6-sdk
191+
192+
- name: Run smoke test (non-Windows)
193+
if: ${{ matrix.os != 'windows-latest' }}
194+
run: |
195+
dotnet add tests/Temporalio.SmokeTest package Temporalio -s "$GITHUB_WORKSPACE/nuget-package/Temporalio/bin/Release;https://api.nuget.org/v3/index.json" --prerelease
196+
dotnet run --project tests/Temporalio.SmokeTest
197+
198+
- name: Run smoke test (Windows)
199+
if: ${{ matrix.os == 'windows-latest' }}
161200
run: |
162-
dotnet add tests/Temporalio.SmokeTest package Temporalio -s "${{ github.workspace }}/nuget-package/Temporalio/bin/Release;https://api.nuget.org/v3/index.json" --prerelease
201+
dotnet add tests/Temporalio.SmokeTest package Temporalio -s "$env:GITHUB_WORKSPACE/nuget-package/Temporalio/bin/Release;https://api.nuget.org/v3/index.json" --prerelease
163202
dotnet run --project tests/Temporalio.SmokeTest
164203
165204
- name: Setup msbuild (Windows only)
@@ -169,6 +208,6 @@ jobs:
169208
- name: Run .NET framework smoke test (Windows only)
170209
if: ${{ matrix.os == 'windows-latest' }}
171210
run: |
172-
dotnet add tests/Temporalio.SmokeTestDotNetFramework package Temporalio -s "${{ github.workspace }}/nuget-package/Temporalio/bin/Release;https://api.nuget.org/v3/index.json" --prerelease
211+
dotnet add tests/Temporalio.SmokeTestDotNetFramework package Temporalio -s "$env:GITHUB_WORKSPACE/nuget-package/Temporalio/bin/Release;https://api.nuget.org/v3/index.json" --prerelease
173212
msbuild tests/Temporalio.SmokeTestDotNetFramework -t:restore,build -p:Platform=x64
174213
tests/Temporalio.SmokeTestDotNetFramework/bin/x64/Debug/Temporalio.SmokeTestDotNetFramework.exe

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,8 @@ reimplementation of the Temporal server with special time skipping capabilities.
815815
to run when first called. Note, this class is not thread safe nor safe for use with independent tests. It can be reused,
816816
but only for one test at a time because time skipping is locked/unlocked at the environment level.
817817

818+
⚠️ WARNING - at this time, the time-skipping test server does not work on musl-based environments like Alpine.
819+
818820
##### Automatic Time Skipping
819821

820822
Anytime a workflow result is waiting on, the time-skipping server automatically advances to the next event it can. To
@@ -1130,8 +1132,8 @@ included when using modern versions of .NET on a common platform. If you are usi
11301132
explicitly set the platform to `x64` or `arm64` because `AnyCPU` will not choose the proper library.
11311133

11321134
Currently we only support [RIDs](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog) `linux-arm64`,
1133-
`linux-x64`, `osx-arm64`, `osx-x64`, and `win-x64`. Any other platforms needed (e.g. `linux-musl-x64` on Alpine) will
1134-
require a custom build.
1135+
`linux-x64`, `linux-musl-x64`, `osx-arm64`, `osx-x64`, and `win-x64`. Any other platforms needed (e.g. `linux-musl-x64`
1136+
on Alpine) will require a custom build.
11351137

11361138
The native shared library on Windows does require a Visual C++ runtime. Some containers, such as Windows Nano Server, do
11371139
not include this runtime. If not available, users may have to manually copy this runtime (usually just

src/Temporalio/Bridge/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2021"
55

66
[lib]
77
name = "temporal_sdk_bridge"
8-
crate-type = ["cdylib", "rlib"]
8+
crate-type = ["cdylib"]
99

1010
[dependencies]
1111
anyhow = "1.0"

src/Temporalio/Temporalio.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@
9090
<Content Include="$(BridgeLibraryRoot)/linux-arm64-bridge/libtemporal_sdk_bridge.so">
9191
<PackagePath>runtimes/linux-arm64/native/libtemporal_sdk_bridge.so</PackagePath>
9292
</Content>
93+
<Content Include="$(BridgeLibraryRoot)/linux-musl-x64-bridge/libtemporal_sdk_bridge.so">
94+
<PackagePath>runtimes/linux-musl-x64/native/libtemporal_sdk_bridge.so</PackagePath>
95+
</Content>
9396
<Content Include="$(BridgeLibraryRoot)/osx-x64-bridge/libtemporal_sdk_bridge.dylib">
9497
<PackagePath>runtimes/osx-x64/native/libtemporal_sdk_bridge.dylib</PackagePath>
9598
</Content>

src/Temporalio/Testing/WorkflowEnvironment.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ public static async Task<WorkflowEnvironment> StartTimeSkippingAsync(
8585
WorkflowEnvironmentStartTimeSkippingOptions? options = null)
8686
{
8787
options ??= new();
88+
89+
// If they did not provide a binary to use, eagerly fail on musl since musl
90+
// time-skipping is not supported at this time. We can only do this check in .NET 5+,
91+
// otherwise we assume it is not musl for now since this is just a temporary situation.
92+
// TODO(cretz): Remove when musl-support for time-skipping test server is present.
93+
#if NET5_0_OR_GREATER
94+
if (options.TestServer.ExistingPath == null &&
95+
System.Runtime.InteropServices.RuntimeInformation.Contains("-musl", StringComparison.OrdinalIgnoreCase))
96+
{
97+
throw new InvalidOperationException(
98+
"Time-skipping test server not currently supported in musl-based environments");
99+
}
100+
#endif
101+
88102
var runtime = options.Runtime ?? TemporalRuntime.Default;
89103
var server = await Bridge.EphemeralServer.StartTestServerAsync(
90104
runtime.Runtime,

0 commit comments

Comments
 (0)