Skip to content

Build Temporal Core SDK artifacts #21

Build Temporal Core SDK artifacts

Build Temporal Core SDK artifacts #21

name: Build Temporal Core SDK artifacts
on:
workflow_dispatch:
env:
RUST_VERSION: "1.88"
ARTIFACT_BUNDLE_NAME: "temporal.artifactbundle"
XCFRAMEWORK_NAME: "temporal.xcframework"
HEADER_SOURCE: "dependencies/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h"
TEMPORAL_BUILT_LIB_NAME: "libtemporal_sdk_core_c_bridge.a"
RUST_PROJECT_DIR: "dependencies/sdk-core/core-c-bridge"
jobs:
setup:
name: Setup release
runs-on: ubuntu-latest
outputs:
release_id: ${{ steps.create_release.outputs.id }}
upload_url: ${{ steps.create_release.outputs.upload_url }}
core_sha: ${{ steps.get_sha.outputs.sha }}
core_sha_short: ${{ steps.get_sha.outputs.sha_short }}
release_tag: ${{ steps.get_sha.outputs.tag }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Get Core SDK commit SHA
id: get_sha
run: |
cd dependencies/sdk-core
CORE_SHA=$(git rev-parse HEAD)
CORE_SHA_SHORT=$(git rev-parse --short HEAD)
RELEASE_TAG="temporal-sdk-core-${CORE_SHA_SHORT}"
echo "sha=${CORE_SHA}" >> $GITHUB_OUTPUT
echo "sha_short=${CORE_SHA_SHORT}" >> $GITHUB_OUTPUT
echo "tag=${RELEASE_TAG}" >> $GITHUB_OUTPUT
echo "Core SDK SHA: ${CORE_SHA}"
echo "Release tag: ${RELEASE_TAG}"
# Validate submodule is clean
if [[ -n $(git status --porcelain) ]]; then
echo "Error: Core SDK submodule has uncommitted changes"
exit 1
fi
- name: Check for existing release
run: |
if gh release view "${{ steps.get_sha.outputs.tag }}" >/dev/null 2>&1; then
echo "Release ${{ steps.get_sha.outputs.tag }} already exists"
echo "Use force_rebuild=true to rebuild anyway"
exit 1
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release notes
run: |
cat > release_notes.md << 'EOF'
Pre-built binaries for Temporal Core SDK at commit https://github.com/temporalio/sdk-core/tree/${{ steps.get_sha.outputs.sha }}.
## Assets
- **temporal.artifactbundle.zip** - Artifact bundle
- **temporal.xcframework.zip** - XCFramework
EOF
- name: Create draft release
id: create_release
run: |
gh release create "${{ steps.get_sha.outputs.tag }}" \
--title "Temporal Core SDK v${{ steps.get_sha.outputs.sha_short }}" \
--notes-file release_notes.md \
--draft \
--latest=false
# Get release details
RELEASE_DATA=$(gh release view "${{ steps.get_sha.outputs.tag }}" --json id,uploadUrl)
RELEASE_ID=$(echo "$RELEASE_DATA" | jq -r '.id')
UPLOAD_URL=$(echo "$RELEASE_DATA" | jq -r '.uploadUrl')
echo "id=${RELEASE_ID}" >> $GITHUB_OUTPUT
echo "upload_url=${UPLOAD_URL}" >> $GITHUB_OUTPUT
echo "Created draft release: ${{ steps.get_sha.outputs.tag }}"
echo "Release ID: ${RELEASE_ID}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-macos:
name: Build macOS static libraries
runs-on: [self-hosted, macos]
needs: setup
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install protoc
run: |
PB_REL="https://github.com/protocolbuffers/protobuf/releases"
curl -LO $PB_REL/download/v32.1/protoc-32.1-osx-universal_binary.zip
unzip protoc-32.1-osx-universal_binary.zip -d $HOME/.local
export PATH="$PATH:$HOME/.local/bin"
- name: Install rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
. "$HOME/.cargo/env"
rustup install ${{ env.RUST_VERSION }}
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
- name: Build macOS x86_64
run: |
export PATH="$PATH:$HOME/.local/bin"
. "$HOME/.cargo/env"
cd ${{ env.RUST_PROJECT_DIR }}
MACOSX_DEPLOYMENT_TARGET="15" \
IPHONEOS_DEPLOYMENT_TARGET="18" \
TVOS_DEPLOYMENT_TARGET="18" \
WATCHOS_DEPLOYMENT_TARGET="11" \
cargo rustc \
--release \
--target x86_64-apple-darwin \
--features xz2-static \
--crate-type=staticlib
- name: Build macOS arm64
run: |
export PATH="$PATH:$HOME/.local/bin"
. "$HOME/.cargo/env"
cd ${{ env.RUST_PROJECT_DIR }}
MACOSX_DEPLOYMENT_TARGET="15" \
IPHONEOS_DEPLOYMENT_TARGET="18" \
TVOS_DEPLOYMENT_TARGET="18" \
WATCHOS_DEPLOYMENT_TARGET="11" \
cargo rustc \
--release \
--target aarch64-apple-darwin \
--features xz2-static \
--crate-type=staticlib
- name: Create fat library
run: |
X86_64_LIB="dependencies/sdk-core/target/x86_64-apple-darwin/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}"
ARM64_LIB="dependencies/sdk-core/target/aarch64-apple-darwin/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}"
if [[ ! -f "${X86_64_LIB}" ]]; then
echo "Error: x86_64 library not found: ${X86_64_LIB}"
exit 1
fi
if [[ ! -f "${ARM64_LIB}" ]]; then
echo "Error: arm64 library not found: ${ARM64_LIB}"
exit 1
fi
lipo -create "${X86_64_LIB}" "${ARM64_LIB}" -output "libtemporal_fat.a"
echo "βœ… Fat library created: libtemporal_fat.a"
- name: Create XCFramework
run: |
# Create temporary directory for framework structure
TEMP_DIR="temp_framework"
rm -rf "${TEMP_DIR}"
mkdir -p "${TEMP_DIR}/Headers"
# Copy fat library and headers
cp "libtemporal_fat.a" "${TEMP_DIR}/libTemporal-macos.a"
cp "${{ env.HEADER_SOURCE }}" "${TEMP_DIR}/Headers/temporal.h"
cp "dependencies/sdk-core/LICENSE.txt" "${TEMP_DIR}/Headers/LICENSE.txt"
# Create module map
cat > "${TEMP_DIR}/Headers/module.modulemap" << 'EOF'
module Bridge {
header "temporal.h"
export *
}
EOF
# Create XCFramework using xcodebuild
xcodebuild -create-xcframework \
-library "${TEMP_DIR}/libTemporal-macos.a" \
-headers "${TEMP_DIR}/Headers" \
-output "${{ env.XCFRAMEWORK_NAME }}"
# Clean up temporary files
rm -rf "${TEMP_DIR}"
rm -f "libtemporal_fat.a"
echo "βœ… XCFramework created: ${{ env.XCFRAMEWORK_NAME }}"
- name: Upload macOS artifacts for bundle assembly
uses: actions/upload-artifact@v4
with:
name: macos-libraries
path: |
dependencies/sdk-core/target/x86_64-apple-darwin/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}
dependencies/sdk-core/target/aarch64-apple-darwin/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}
${{ env.XCFRAMEWORK_NAME }}
retention-days: 1
build-linux-x86:
name: Build Linux x86_64
runs-on: ubuntu-24.04
needs: setup
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install protoc
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq protobuf-compiler
- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
target: x86_64-unknown-linux-gnu
rustflags: ""
- name: Build Linux x86_64
run: |
cd ${{ env.RUST_PROJECT_DIR }}
cargo rustc \
--release \
--target x86_64-unknown-linux-gnu \
--features xz2-static \
--crate-type=staticlib
- name: Upload Linux x86_64 artifacts
uses: actions/upload-artifact@v4
with:
name: linux-x86-libraries
path: dependencies/sdk-core/target/x86_64-unknown-linux-gnu/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}
retention-days: 1
# build-linux-arm:
# name: Build Linux ARM64
# runs-on: ubuntu-24.04-arm
# needs: setup
# steps:
# - name: Checkout repository
# uses: actions/checkout@v4
# with:
# submodules: recursive
# - name: Install protoc
# run: |
# sudo apt-get update -qq
# sudo apt-get install -y -qq protobuf-compiler
# - name: Install Rust
# uses: actions-rust-lang/setup-rust-toolchain@v1
# with:
# toolchain: ${{ env.RUST_VERSION }}
# target: aarch64-unknown-linux-gnu
# rustflags: ""
# - name: Build Linux ARM64
# run: |
# cd ${{ env.RUST_PROJECT_DIR }}
# cargo rustc \
# --release \
# --target aarch64-unknown-linux-gnu \
# --features xz2-static \
# --crate-type=staticlib
# - name: Upload Linux ARM64 artifacts
# uses: actions/upload-artifact@v4
# with:
# name: linux-arm-libraries
# path: dependencies/sdk-core/target/aarch64-unknown-linux-gnu/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}
# retention-days: 1
assemble-bundle:
name: Assemble artifact bundle
runs-on: ubuntu-latest
needs: [setup, build-macos, build-linux-x86]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Download all platform artifacts
uses: actions/download-artifact@v4
- name: Reconstruct build structure
run: |
# List downloaded artifacts to debug
echo "πŸ“ Downloaded artifacts:"
find macos-libraries/ -type f -name "*" || echo "macos-libraries not found"
find linux-x86-libraries/ -type f -name "*" || echo "linux-x86-libraries not found"
# The artifacts already contain the full directory structure
# Just copy them to the current directory
if [ -d "macos-libraries/dependencies" ]; then
cp -r macos-libraries/dependencies .
echo "βœ… Copied macOS libraries with directory structure"
else
echo "Error: macOS libraries not found in expected structure"
exit 1
fi
if [ -d "linux-x86-libraries" ]; then
cp linux-x86-libraries/${{ env.TEMPORAL_BUILT_LIB_NAME }} \
dependencies/sdk-core/target/x86_64-unknown-linux-gnu/release/
echo "βœ… Copied Linux x86_64 library"
else
echo "Error: Linux x86_64 library not found"
exit 1
fi
echo "βœ… Build structure reconstructed"
- name: Create artifact bundle structure
run: |
rm -rf "${{ env.ARTIFACT_BUNDLE_NAME }}"
mkdir -p "${{ env.ARTIFACT_BUNDLE_NAME }}/temporal"
mkdir -p "${{ env.ARTIFACT_BUNDLE_NAME }}/include"
- name: Setup headers and module map
run: |
# Copy and rename header file
cp "${{ env.HEADER_SOURCE }}" "${{ env.ARTIFACT_BUNDLE_NAME }}/include/temporal.h"
# Copy license file
cp "dependencies/sdk-core/LICENSE.txt" "${{ env.ARTIFACT_BUNDLE_NAME }}/include/LICENSE.txt"
# Create module map with correct header reference
cat > "${{ env.ARTIFACT_BUNDLE_NAME }}/include/module.modulemap" << 'EOF'
module Bridge {
header "temporal.h"
export *
}
EOF
- name: Copy platform libraries to bundle
run: |
# Copy all platform libraries to bundle
cp "dependencies/sdk-core/target/x86_64-apple-darwin/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}" \
"${{ env.ARTIFACT_BUNDLE_NAME }}/temporal/libTemporal-macos-x86_64.a"
cp "dependencies/sdk-core/target/aarch64-apple-darwin/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}" \
"${{ env.ARTIFACT_BUNDLE_NAME }}/temporal/libTemporal-macos-arm64.a"
cp "dependencies/sdk-core/target/x86_64-unknown-linux-gnu/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}" \
"${{ env.ARTIFACT_BUNDLE_NAME }}/temporal/libTemporal-linux-x86_64.a"
# cp "dependencies/sdk-core/target/aarch64-unknown-linux-gnu/release/${{ env.TEMPORAL_BUILT_LIB_NAME }}" \
# "${{ env.ARTIFACT_BUNDLE_NAME }}/temporal/libTemporal-linux-arm64.a"
- name: Generate artifact bundle manifest
run: |
cat > "${{ env.ARTIFACT_BUNDLE_NAME }}/info.json" << 'EOF'
{
"schemaVersion": "1.0",
"artifacts": {
"CTemporal": {
"type": "staticLibrary",
"version": "1.0.0",
"variants": [
{
"path": "temporal/libTemporal-macos-x86_64.a",
"supportedTriples": ["x86_64-apple-macosx"],
"staticLibraryMetadata": {
"headerPaths": ["include"],
"moduleMapPath": "include/module.modulemap"
}
},
{
"path": "temporal/libTemporal-macos-arm64.a",
"supportedTriples": ["arm64-apple-macosx"],
"staticLibraryMetadata": {
"headerPaths": ["include"],
"moduleMapPath": "include/module.modulemap"
}
},
{
"path": "temporal/libTemporal-linux-x86_64.a",
"supportedTriples": ["x86_64-unknown-linux-gnu"],
"staticLibraryMetadata": {
"headerPaths": ["include"],
"moduleMapPath": "include/module.modulemap"
}
},
{
"path": "temporal/libTemporal-linux-arm64.a",
"supportedTriples": ["aarch64-unknown-linux-gnu"],
"staticLibraryMetadata": {
"headerPaths": ["include"],
"moduleMapPath": "include/module.modulemap"
}
}
]
}
}
}
EOF
- name: Create archive
run: |
zip -r "${{ env.ARTIFACT_BUNDLE_NAME }}.zip" "${{ env.ARTIFACT_BUNDLE_NAME }}"
echo "βœ… Artifact archive created: ${{ env.ARTIFACT_BUNDLE_NAME }}.zip"
echo "πŸ“Š Archive size: $(du -h "${{ env.ARTIFACT_BUNDLE_NAME }}.zip" | cut -f1)"
- name: Upload artifact bundle to release
run: |
gh release upload "${{ needs.setup.outputs.release_tag }}" \
"${{ env.ARTIFACT_BUNDLE_NAME }}.zip" \
--clobber
echo "βœ… Artifact bundle uploaded to release"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Package and upload XCFramework
run: |
zip -r "${{ env.XCFRAMEWORK_NAME }}.zip" "xcframework/${{ env.XCFRAMEWORK_NAME }}"
gh release upload "${{ needs.setup.outputs.release_tag }}" \
"${{ env.XCFRAMEWORK_NAME }}.zip" \
--clobber
echo "βœ… XCFramework uploaded to release"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Print summary
run: |
echo "πŸŽ‰ Build completed successfully!"
echo ""
echo "πŸ“‹ Release Details:"
echo " Tag: ${{ needs.setup.outputs.release_tag }}"
echo " Core SHA: ${{ needs.setup.outputs.core_sha }}"
echo ""
echo "πŸ“ Review and publish the draft release when ready!"