name: Reusable CI on: workflow_call: inputs: os: required: true type: string target: description: "The Rust compilation target. Empty for native test builds." required: false type: string default: '' upload-artifacts: required: false type: boolean default: false package-only: description: "Skip tests/lints; build + package only" required: false type: boolean default: false jobs: ci: runs-on: ${{ inputs.os }} steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: components: clippy, rustfmt # Normal tests and lints (these will run on the runner's native ARM architecture) - name: Build if: ${{ !inputs.package-only }} run: cargo build --all-features - name: Test if: ${{ !inputs.package-only }} run: cargo test --all-features - name: Clippy if: ${{ !inputs.package-only }} run: cargo clippy --all-targets --all-features -- -D warnings - name: Fmt check if: ${{ !inputs.package-only }} run: cargo fmt --all -- --check - name: Security audit (Linux only) if: ${{ !inputs.package-only && runner.os == 'Linux' }} run: | cargo install cargo-audit cargo audit # --- Build & Package Logic --- - name: Set up Linux x86_64 cross-compilation if: inputs.target == 'x86_64-unknown-linux-gnu' run: | sudo apt-get update sudo apt-get install -y g++-x86-64-linux-gnu rustup target add x86_64-unknown-linux-gnu - name: Set up Windows x86_64 cross-compilation 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 (Cross-Compile) if: inputs.upload-artifacts run: cargo build --release --features ffi --target=${{ inputs.target }} env: # Set the correct linker for each target CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: x86_64-linux-gnu-g++ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc - name: Extract version and create package if: inputs.upload-artifacts shell: bash run: | VERSION=$(sed -n 's/^version\s*=\s*"\([^"]\+\)"/\1/p' Cargo.toml | head -n1) TARGET_ARCH="x86_64" TARGET_TRIPLE="${{ inputs.target }}" # Determine package name and library extension based on target if [[ "$TARGET_TRIPLE" == "x86_64-unknown-linux-gnu" ]]; then PKG_BASENAME="medicallib_rust-v${VERSION}-${TARGET_ARCH}-unknown-linux-gnu" LIB_NAME="libmedicallib_rust.so" ARCHIVE_TYPE="tar.gz" elif [[ "$TARGET_TRIPLE" == "x86_64-pc-windows-gnu" ]]; then PKG_BASENAME="medicallib_rust-v${VERSION}-${TARGET_ARCH}-pc-windows-gnu" LIB_NAME="medicallib_rust.dll" ARCHIVE_TYPE="zip" else echo "::error::Unsupported target for packaging: $TARGET_TRIPLE" exit 1 fi PKG_DIR="dist/${PKG_BASENAME}" echo "Creating package ${PKG_BASENAME}..." mkdir -p "${PKG_DIR}/include" "${PKG_DIR}/lib" # Copy header and the compiled library from the correct target-specific directory cp ffi/medicallib.h "${PKG_DIR}/include/" cp "target/${TARGET_TRIPLE}/release/${LIB_NAME}" "${PKG_DIR}/lib/" # Create the appropriate archive if [[ "$ARCHIVE_TYPE" == "tar.gz" ]]; then tar -C dist -czf "dist/${PKG_BASENAME}.tar.gz" "${PKG_BASENAME}" elif [[ "$ARCHIVE_TYPE" == "zip" ]]; then (cd dist && zip -r9 "${PKG_BASENAME}.zip" "${PKG_BASENAME}") fi - name: Upload Artifact if: inputs.upload-artifacts uses: https://github.com/christopherHX/gitea-upload-artifact@v4 with: # Create a unique name based on the target OS name: medicallib-rust-${{ contains(inputs.target, 'windows') && 'Windows' || 'Linux' }}-x86_64-${{ github.run_number }} path: | dist/*.tar.gz dist/*.zip if-no-files-found: error