Restore native packaging project and fix CI solution path #18
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| jobs: | |
| build-test: | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: 9.0.x | |
| - name: Show .NET info | |
| run: dotnet --info | |
| - name: Restore dependencies | |
| run: dotnet restore MLXSharp.slnx | |
| - name: Build C# projects (initial validation) | |
| run: dotnet build MLXSharp.slnx --configuration Release --no-restore | |
| - name: Install CMake | |
| run: brew install cmake | |
| - name: Build native stub library | |
| run: | | |
| cmake -S native -B native/build -DCMAKE_BUILD_TYPE=Release | |
| cmake --build native/build --target mlxsharp --config Release | |
| mkdir -p src/MLXSharp.Native/runtimes/osx-arm64/native | |
| cp native/build/libmlxsharp.dylib src/MLXSharp.Native/runtimes/osx-arm64/native/ | |
| echo "Native library built:" | |
| ls -la src/MLXSharp.Native/runtimes/osx-arm64/native/ | |
| - name: Rebuild solution with native libraries | |
| run: dotnet build MLXSharp.slnx --configuration Release --no-restore | |
| - name: Setup Python for HuggingFace | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install HuggingFace CLI | |
| run: pip install huggingface_hub | |
| - name: Download test model from HuggingFace | |
| run: | | |
| mkdir -p models | |
| huggingface-cli download mlx-community/Qwen1.5-0.5B-Chat-4bit --local-dir models/Qwen1.5-0.5B-Chat-4bit | |
| echo "Model files:" | |
| ls -la models/Qwen1.5-0.5B-Chat-4bit/ | |
| - name: Copy native library to test output | |
| run: | | |
| TEST_OUTPUT="src/MLXSharp.Tests/bin/Release/net9.0" | |
| mkdir -p "$TEST_OUTPUT/runtimes/osx-arm64/native" | |
| cp src/MLXSharp.Native/runtimes/osx-arm64/native/libmlxsharp.dylib "$TEST_OUTPUT/runtimes/osx-arm64/native/" | |
| ls -la "$TEST_OUTPUT/runtimes/osx-arm64/native/" | |
| - name: Run tests | |
| run: dotnet test MLXSharp.slnx --configuration Release --no-build --logger "trx;LogFileName=TestResults.trx" --results-directory artifacts/test-results | |
| env: | |
| MLXSHARP_MODEL_PATH: ${{ github.workspace }}/models/Qwen1.5-0.5B-Chat-4bit | |
| - name: Prepare artifact folders | |
| run: | | |
| mkdir -p artifacts/test-results | |
| mkdir -p artifacts/packages | |
| mkdir -p artifacts/native | |
| cp src/MLXSharp.Native/runtimes/osx-arm64/native/libmlxsharp.dylib artifacts/native/ | |
| - name: Pack MLXSharp library | |
| run: dotnet pack src/MLXSharp/MLXSharp.csproj --configuration Release --output artifacts/packages -p:MLXSharpMacNativeBinary=$GITHUB_WORKSPACE/native/build/libmlxsharp.dylib | |
| - name: Pack MLXSharp.SemanticKernel library | |
| run: dotnet pack src/MLXSharp.SemanticKernel/MLXSharp.SemanticKernel.csproj --configuration Release --output artifacts/packages -p:MLXSharpMacNativeBinary=$GITHUB_WORKSPACE/native/build/libmlxsharp.dylib | |
| - name: Verify package contains native libraries | |
| run: | | |
| echo "Checking package contents..." | |
| shopt -s nullglob | |
| packages=(artifacts/packages/*.nupkg) | |
| if [ ${#packages[@]} -eq 0 ]; then | |
| echo "✗ ERROR: No packages were produced" | |
| exit 1 | |
| fi | |
| missing=0 | |
| for package in "${packages[@]}"; do | |
| echo "Inspecting ${package}" | |
| filename=$(basename "${package}") | |
| case "${filename}" in | |
| MLXSharp.*.nupkg) | |
| if unzip -l "${package}" | grep -q "runtimes/osx-arm64/native/libmlxsharp.dylib"; then | |
| echo " ✓ Native library found" | |
| else | |
| echo " ✗ Native library NOT found" | |
| unzip -l "${package}" | |
| missing=1 | |
| fi | |
| ;; | |
| *) | |
| echo " ↷ Skipping native check for ${filename}" | |
| ;; | |
| esac | |
| done | |
| if [ $missing -ne 0 ]; then | |
| exit 1 | |
| fi | |
| - name: Upload native artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: native-libs | |
| path: artifacts/native | |
| - name: Upload packages artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: packages | |
| path: artifacts/packages | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results | |
| path: artifacts/test-results | |
| release: | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| needs: build-test | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Extract version from Directory.Build.props | |
| id: version | |
| run: | | |
| VERSION=$(grep -oP '<Version>\K[^<]+' Directory.Build.props) | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "Extracted version: $VERSION" | |
| # - name: Check if tag exists | |
| # id: check_tag | |
| # run: | | |
| # if git ls-remote --tags origin | grep -q "refs/tags/v${{ steps.version.outputs.version }}"; then | |
| # echo "exists=true" >> $GITHUB_OUTPUT | |
| # echo "Tag v${{ steps.version.outputs.version }} already exists" | |
| # else | |
| # echo "exists=false" >> $GITHUB_OUTPUT | |
| # echo "Tag v${{ steps.version.outputs.version }} does not exist" | |
| # fi | |
| # - name: Download package artifacts | |
| # if: steps.check_tag.outputs.exists == 'false' | |
| # uses: actions/download-artifact@v4 | |
| # with: | |
| # name: packages | |
| # path: artifacts/packages | |
| # - name: Publish to NuGet | |
| # if: steps.check_tag.outputs.exists == 'false' | |
| # run: | | |
| # for package in artifacts/packages/*.nupkg; do | |
| # echo "Publishing $package..." | |
| # dotnet nuget push "$package" \ | |
| # --api-key ${{ secrets.NUGET_API_KEY }} \ | |
| # --source https://api.nuget.org/v3/index.json \ | |
| # --skip-duplicate || true | |
| # done | |
| # - name: Create Git tag | |
| # if: steps.check_tag.outputs.exists == 'false' | |
| # run: | | |
| # git config user.name "github-actions[bot]" | |
| # git config user.email "github-actions[bot]@users.noreply.github.com" | |
| # git tag -a "v${{ steps.version.outputs.version }}" -m "Release v${{ steps.version.outputs.version }}" | |
| # git push origin "v${{ steps.version.outputs.version }}" | |
| # - name: Generate release notes | |
| # if: steps.check_tag.outputs.exists == 'false' | |
| # id: release_notes | |
| # run: | | |
| # PREVIOUS_TAG=$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1) 2>/dev/null || echo "") | |
| # if [ -z "$PREVIOUS_TAG" ]; then | |
| # COMMITS=$(git log --pretty=format:"- %s (%h)" --reverse) | |
| # else | |
| # COMMITS=$(git log ${PREVIOUS_TAG}..HEAD --pretty=format:"- %s (%h)" --reverse) | |
| # fi | |
| # echo "## What's Changed" > release_notes.md | |
| # echo "" >> release_notes.md | |
| # echo "$COMMITS" >> release_notes.md | |
| # echo "" >> release_notes.md | |
| # echo "## NuGet Packages" >> release_notes.md | |
| # echo "- [MLXSharp v${{ steps.version.outputs.version }}](https://www.nuget.org/packages/MLXSharp/${{ steps.version.outputs.version }})" >> release_notes.md | |
| # echo "- [MLXSharp.SemanticKernel v${{ steps.version.outputs.version }}](https://www.nuget.org/packages/MLXSharp.SemanticKernel/${{ steps.version.outputs.version }})" >> release_notes.md | |
| # cat release_notes.md | |
| # - name: Create GitHub Release | |
| # if: steps.check_tag.outputs.exists == 'false' | |
| # uses: softprops/action-gh-release@v1 | |
| # with: | |
| # tag_name: v${{ steps.version.outputs.version }} | |
| # name: Release v${{ steps.version.outputs.version }} | |
| # body_path: release_notes.md | |
| # files: artifacts/packages/* | |
| # env: | |
| # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |