bu
Multi-Platform CI / test-platforms (ubuntu-22.04) (push) Successful in 23s
Multi-Platform CI / test-platforms (windows-latest) (push) Successful in 18s
Multi-Platform CI / Package for Linux (push) Successful in 39s
Multi-Platform CI / Package for Windows (Cross-Compiled) (push) Successful in 55s

This commit is contained in:
2025-09-23 20:47:16 -07:00
parent 5f51ebd62f
commit 8785546403
2 changed files with 68 additions and 91 deletions
+52 -87
View File
@@ -6,6 +6,11 @@ on:
os:
required: true
type: string
target:
description: "The Rust compilation target (e.g., x86_64-pc-windows-gnu). Empty for native."
required: false
type: string
default: ''
upload-artifacts:
required: false
type: boolean
@@ -26,6 +31,7 @@ jobs:
with:
components: clippy, rustfmt
# Steps for linting, testing, etc. These are skipped in 'package-only' mode.
- name: Build
if: ${{ !inputs.package-only }}
run: cargo build --all-features
@@ -40,8 +46,7 @@ jobs:
- name: Fmt check
if: ${{ !inputs.package-only }}
run: |
cargo fmt --all -- --check
run: cargo fmt --all -- --check
- name: Security audit (Linux only)
if: ${{ !inputs.package-only && runner.os == 'Linux' }}
@@ -49,121 +54,81 @@ jobs:
cargo install cargo-audit
cargo audit
- name: Build FFI library
if: inputs.upload-artifacts
# --- Build & Package Logic ---
- name: Set up Windows cross-compilation environment
if: inputs.target == 'x86_64-pc-windows-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-mingw-w64-x86-64
rustup target add x86_64-pc-windows-gnu
- name: Build FFI library (Native)
if: inputs.upload-artifacts && inputs.target == ''
run: cargo build --release --features ffi
- name: Extract version and create package (non-Windows)
if: inputs.upload-artifacts && runner.os != 'Windows'
- name: Build FFI library (Cross-compile for Windows)
if: inputs.upload-artifacts && inputs.target == 'x86_64-pc-windows-gnu'
run: cargo build --release --features ffi --target=${{ inputs.target }}
env:
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc
- name: Extract version and create package (Linux)
if: inputs.upload-artifacts && inputs.target == ''
shell: bash
run: |
VERSION=$(sed -n 's/^version\s*=\s*"\([^"]\+\)"/\1/p' Cargo.toml | head -n1)
# Determine target directory and library extension
TARGET_DIR="target/release"
# Map runner.arch to Rust target arch
case "${{ runner.arch }}" in
ARM64) ARCH_TRIPLE="aarch64" ;;
X64) ARCH_TRIPLE="x86_64" ;;
*) ARCH_TRIPLE="unknown" ;;
esac
# Compose package basename with OS + arch
case "${{ runner.os }}" in
Linux) PKG_BASENAME="medicallib_rust-v${VERSION}-${ARCH_TRIPLE}-unknown-linux-gnu" ;;
macOS) PKG_BASENAME="medicallib_rust-v${VERSION}-${ARCH_TRIPLE}-apple-darwin" ;;
*) PKG_BASENAME="medicallib_rust-v${VERSION}-native" ;;
esac
PKG_BASENAME="medicallib_rust-v${VERSION}-${ARCH_TRIPLE}-unknown-linux-gnu"
PKG_DIR="dist/${PKG_BASENAME}"
echo "Creating package ${PKG_BASENAME}..."
mkdir -p "${PKG_DIR}/include" "${PKG_DIR}/lib" "${PKG_DIR}/examples/c"
# Copy header and example
mkdir -p "${PKG_DIR}/include" "${PKG_DIR}/lib"
cp ffi/medicallib.h "${PKG_DIR}/include/"
cp examples/c/ffi_example.c "${PKG_DIR}/examples/c/"
cp README.md INSTALL.md MIGRATION.md ARCHITECTURE.md "${PKG_DIR}/" || true
cp "target/release/libmedicallib_rust.so" "${PKG_DIR}/lib/"
# Copy library with proper extension detection
if [[ "${{ runner.os }}" == "macOS" ]]; then
cp "${TARGET_DIR}/libmedicallib_rust.dylib" "${PKG_DIR}/lib/"
else
cp "${TARGET_DIR}/libmedicallib_rust.so" "${PKG_DIR}/lib/"
fi
# Create archives
tar -C dist -czf "dist/${PKG_BASENAME}.tar.gz" "${PKG_BASENAME}"
if command -v zip >/dev/null 2>&1; then
(cd dist && zip -r9 "${PKG_BASENAME}.zip" "${PKG_BASENAME}")
fi
(cd dist && zip -r9 "${PKG_BASENAME}.zip" "${PKG_BASENAME}")
- name: Extract version and create package (Windows)
if: inputs.upload-artifacts && runner.os == 'Windows'
shell: pwsh
- name: Extract version and create package (Cross-compiled Windows)
if: inputs.upload-artifacts && inputs.target == 'x86_64-pc-windows-gnu'
shell: bash
run: |
$versionMatch = (Get-Content Cargo.toml | Select-String -Pattern '^version\s*=\s*"([^"]+)"' -AllMatches | ForEach-Object { $_.Matches } | Select-Object -First 1)
if (-not $versionMatch) { Write-Error "Unable to parse version from Cargo.toml"; exit 1 }
$VERSION = $versionMatch.Groups[1].Value
VERSION=$(sed -n 's/^version\s*=\s*"\([^"]\+\)"/\1/p' Cargo.toml | head -n1)
ARCH_TRIPLE="x86_64"
PKG_BASENAME="medicallib_rust-v${VERSION}-${ARCH_TRIPLE}-pc-windows-gnu"
PKG_DIR="dist/${PKG_BASENAME}"
switch ("${{ runner.arch }}") {
'ARM64' { $ARCH_TRIPLE = 'aarch64' }
'X64' { $ARCH_TRIPLE = 'x86_64' }
default { $ARCH_TRIPLE = 'unknown' }
}
echo "Creating package ${PKG_BASENAME}..."
mkdir -p "${PKG_DIR}/include" "${PKG_DIR}/lib"
cp ffi/medicallib.h "${PKG_DIR}/include/"
# The output path is different for cross-compilation
cp "target/x86_64-pc-windows-gnu/release/medicallib_rust.dll" "${PKG_DIR}/lib/"
$PKG_BASENAME = "medicallib_rust-v$VERSION-$ARCH_TRIPLE-pc-windows-msvc"
$PKG_DIR = Join-Path 'dist' $PKG_BASENAME
Write-Host "Creating package $PKG_BASENAME..."
New-Item -ItemType Directory -Force -Path (Join-Path $PKG_DIR 'include') | Out-Null
New-Item -ItemType Directory -Force -Path (Join-Path $PKG_DIR 'lib') | Out-Null
New-Item -ItemType Directory -Force -Path (Join-Path $PKG_DIR 'examples' 'c') | Out-Null
(cd dist && zip -r9 "${PKG_BASENAME}.zip" "${PKG_BASENAME}")
Copy-Item -Force -Path 'ffi/medicallib.h' -Destination (Join-Path $PKG_DIR 'include')
Copy-Item -Force -Path 'examples/c/ffi_example.c' -Destination (Join-Path $PKG_DIR 'examples/c')
Copy-Item -Force -Path 'README.md','INSTALL.md','MIGRATION.md','ARCHITECTURE.md' -Destination $PKG_DIR -ErrorAction SilentlyContinue
# --- Artifact Upload Logic ---
$TARGET_DIR = 'target\release'
$dllCandidates = @(
(Join-Path $TARGET_DIR 'medicallib_rust.dll'),
(Join-Path $TARGET_DIR 'libmedicallib_rust.dll')
)
$copied = $false
foreach ($file in $dllCandidates) {
if (Test-Path $file) {
Copy-Item -Force -Path $file -Destination (Join-Path $PKG_DIR 'lib')
$copied = $true
break
}
}
if (-not $copied) {
$found = Get-ChildItem -Path $TARGET_DIR -Filter '*medicallib_rust*.dll' -ErrorAction SilentlyContinue | Select-Object -First 1
if ($found) {
Copy-Item -Force $found.FullName -Destination (Join-Path $PKG_DIR 'lib')
$copied = $true
}
}
if (-not $copied) { Write-Error "Could not locate built DLL in $TARGET_DIR"; exit 1 }
$zipPath = Join-Path 'dist' ("{0}.zip" -f $PKG_BASENAME)
Compress-Archive -Path $PKG_DIR -DestinationPath $zipPath -Force
- name: Upload Linux/macOS Artifacts
if: inputs.upload-artifacts && runner.os != 'Windows'
- name: Upload Linux Artifact
if: inputs.upload-artifacts && inputs.target == ''
uses: https://github.com/christopherHX/gitea-upload-artifact@v4
with:
name: medicallib-rust-${{ runner.os }}-${{ github.run_number }}
name: medicallib-rust-Linux-${{ runner.arch }}-${{ github.run_number }}
path: |
dist/*.tar.gz
dist/*.zip
if-no-files-found: error
overwrite: false
- name: Upload Windows Artifact
if: inputs.upload-artifacts && runner.os == 'Windows'
if: inputs.upload-artifacts && inputs.target == 'x86_64-pc-windows-gnu'
uses: https://github.com/christopherHX/gitea-upload-artifact@v4
with:
name: medicallib-rust-${{ runner.os }}-${{ github.run_number }}
path: dist/*.zip # <-- Only look for the .zip file
if-no-files-found: error
overwrite: false
name: medicallib-rust-Windows-x86_64-${{ github.run_number }}
path: dist/*.zip
if-no-files-found: error
+16 -4
View File
@@ -26,14 +26,26 @@ jobs:
package:
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main')
needs: [test-platforms]
# Both jobs run on ubuntu, but with different targets
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
- os: windows-latest
# Configuration for the native Linux build
- name: Linux
target: '' # An empty target means native build
# Configuration for the Windows cross-compile build
- name: Windows (Cross-Compiled)
target: 'x86_64-pc-windows-gnu'
name: Package for ${{ matrix.name }}
uses: ./.gitea/workflows/ci-reusable.yml
with:
os: ${{ matrix.os }}
# Both jobs are sent to an ubuntu runner
os: ubuntu-22.04
# The target is passed to the reusable workflow
target: ${{ matrix.target }}
upload-artifacts: true
package-only: true
package-only: true