Merge pull request #11 from SharpAI/feature/gemma-4-inference-ahan-mo… #20
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: Release | |
| # Auto-release on every push to main (like llama.cpp) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| create_release: | |
| description: 'Create new release' | |
| required: true | |
| type: boolean | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - '**/*.swift' | |
| - 'Package.swift' | |
| - '.github/workflows/release.yml' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: write | |
| jobs: | |
| build-and-release: | |
| runs-on: macos-15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Full history for build number | |
| submodules: recursive | |
| - name: Install Metal Toolchain | |
| run: xcodebuild -downloadComponent MetalToolchain || true | |
| - name: Determine tag name | |
| id: tag | |
| run: | | |
| BUILD_NUMBER="$(git rev-list --count HEAD)" | |
| SHORT_HASH="$(git rev-parse --short=7 HEAD)" | |
| echo "name=b${BUILD_NUMBER}" >> $GITHUB_OUTPUT | |
| echo "full=b${BUILD_NUMBER}-${SHORT_HASH}" >> $GITHUB_OUTPUT | |
| echo "Build: b${BUILD_NUMBER} (${SHORT_HASH})" | |
| - name: Generate changelog | |
| id: changelog | |
| run: | | |
| # Find the previous release tag | |
| PREV_TAG=$(git tag --sort=-creatordate | head -1 2>/dev/null || echo "") | |
| if [ -z "$PREV_TAG" ]; then | |
| # First release — all commits | |
| CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges -20) | |
| else | |
| CHANGELOG=$(git log "${PREV_TAG}..HEAD" --pretty=format:"- %s (%h)" --no-merges) | |
| fi | |
| # Write to file (multi-line safe) | |
| echo "$CHANGELOG" > /tmp/changelog.txt | |
| echo "Generated changelog with $(echo "$CHANGELOG" | wc -l | tr -d ' ') entries" | |
| - name: Build (Release) | |
| run: swift build -c release | |
| - name: Verify binary | |
| run: | | |
| ls -lh .build/release/SwiftLM | |
| file .build/release/SwiftLM | |
| .build/release/SwiftLM --help || true | |
| - name: Compile default.metallib from source | |
| run: | | |
| # The .metal shader sources are committed to git but the binary | |
| # output (default.metallib) is gitignored. Compile fresh from the | |
| # tracked sources so the metallib is version-matched to the Swift | |
| # binary by construction. | |
| KERNELS="LocalPackages/mlx-swift/Source/Cmlx/mlx/mlx/backend/metal/kernels" | |
| MLX_ROOT="LocalPackages/mlx-swift/Source/Cmlx/mlx" | |
| echo "Compiling $(find "$KERNELS" -name '*.metal' | wc -l | tr -d ' ') Metal shaders..." | |
| mkdir -p /tmp/mlx_air | |
| find "$KERNELS" -name "*.metal" | while read -r f; do | |
| name=$(basename "$f" .metal) | |
| xcrun -sdk macosx metal \ | |
| -I "$KERNELS" \ | |
| -I "$MLX_ROOT" \ | |
| -c "$f" \ | |
| -o "/tmp/mlx_air/${name}.air" 2>&1 || echo "WARN: failed to compile $f" | |
| done | |
| AIR_COUNT=$(ls /tmp/mlx_air/*.air 2>/dev/null | wc -l | tr -d ' ') | |
| echo "Linking $AIR_COUNT .air files into default.metallib..." | |
| xcrun -sdk macosx metallib /tmp/mlx_air/*.air -o default.metallib | |
| file default.metallib | |
| ls -lh default.metallib | |
| - name: Package binary | |
| run: | | |
| mkdir -p release | |
| cp .build/release/SwiftLM release/ | |
| cp default.metallib release/ | |
| cp LICENSE README.md release/ | |
| cd release | |
| # Verify the tarball will be self-contained before archiving | |
| ls -lh | |
| tar -czvf ../SwiftLM-${{ steps.tag.outputs.name }}-macos-arm64.tar.gz . | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: SwiftLM-${{ steps.tag.outputs.name }}-macos-arm64 | |
| path: SwiftLM-${{ steps.tag.outputs.name }}-macos-arm64.tar.gz | |
| retention-days: 90 | |
| - name: Prepare release notes | |
| id: notes | |
| run: | | |
| CHANGELOG=$(cat /tmp/changelog.txt) | |
| cat > /tmp/release_notes.md << 'RELEASE_EOF' | |
| ## SwiftLM ${{ steps.tag.outputs.full }} | |
| <details open> | |
| ${{ github.event.head_commit.message }} | |
| </details> | |
| ### Changelog | |
| RELEASE_EOF | |
| cat /tmp/changelog.txt >> /tmp/release_notes.md | |
| cat >> /tmp/release_notes.md << 'RELEASE_EOF' | |
| ### Download | |
| - [macOS Apple Silicon (arm64)](https://github.com/SharpAI/SwiftLM/releases/download/${{ steps.tag.outputs.name }}/SwiftLM-${{ steps.tag.outputs.name }}-macos-arm64.tar.gz) | |
| ### Quick Start | |
| ```bash | |
| tar -xzf SwiftLM-${{ steps.tag.outputs.name }}-macos-arm64.tar.gz | |
| # default.metallib is included — run from the extracted directory | |
| ./SwiftLM --model mlx-community/Qwen2.5-3B-Instruct-4bit --port 5413 | |
| ``` | |
| > **Note:** `default.metallib` is bundled in this archive. Keep it in the same directory as the `SwiftLM` binary — Metal GPU compute will fail if it is missing. | |
| RELEASE_EOF | |
| - name: Create release | |
| if: ${{ github.event_name == 'push' || github.event.inputs.create_release == 'true' }} | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.tag.outputs.name }} | |
| name: "SwiftLM ${{ steps.tag.outputs.name }}" | |
| body_path: /tmp/release_notes.md | |
| files: | | |
| SwiftLM-${{ steps.tag.outputs.name }}-macos-arm64.tar.gz | |
| draft: false | |
| prerelease: false |