Skip to content

Use CPU torch for Linux release packaging #6

Use CPU torch for Linux release packaging

Use CPU torch for Linux release packaging #6

Workflow file for this run

name: Release
on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
permissions:
contents: write
jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.allow_failure }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
target: x86_64-unknown-linux-gnu
allow_failure: false
run_real_smoke: true
- os: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
allow_failure: true
run_real_smoke: false
- os: macos-15-intel
target: x86_64-apple-darwin
allow_failure: false
run_real_smoke: false
- os: macos-14
target: aarch64-apple-darwin
allow_failure: false
run_real_smoke: false
- os: windows-2022
target: x86_64-pc-windows-msvc
allow_failure: false
run_real_smoke: false
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
cache: "pip"
- name: Install dependencies
shell: bash
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Compile source tree
shell: bash
run: python -m compileall src scripts
- name: Real backend smoke before packaging
if: matrix.run_real_smoke
shell: bash
run: python scripts/real_backend_smoke.py --binary bitloops-embeddings
- name: Switch Linux packaging environment to CPU-only torch
if: runner.os == 'Linux'
shell: bash
run: |
TORCH_VERSION="$(python - <<'PY'
import importlib.metadata
print(importlib.metadata.version("torch"))
PY
)"
mapfile -t GPU_PACKAGES < <(python - <<'PY'
import subprocess
import sys
output = subprocess.check_output([sys.executable, "-m", "pip", "freeze"], text=True)
for line in output.splitlines():
name = line.split("==", 1)[0]
lower = name.lower()
if lower.startswith("nvidia-") or lower == "triton":
print(name)
PY
)
if ((${#GPU_PACKAGES[@]} > 0)); then
python -m pip uninstall -y "${GPU_PACKAGES[@]}"
fi
python -m pip uninstall -y torch
python -m pip install "torch==${TORCH_VERSION}" --index-url https://download.pytorch.org/whl/cpu
- name: Import Apple signing certificate
if: runner.os == 'macOS'
env:
APPLE_CERT_P12_BASE64: ${{ secrets.APPLE_CERT_P12_BASE64 }}
APPLE_CERT_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }}
shell: bash
run: |
echo "$APPLE_CERT_P12_BASE64" | base64 --decode > apple-cert.p12
security create-keychain -p temp123 build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p temp123 build.keychain
security set-keychain-settings -lut 21600 build.keychain
security import apple-cert.p12 \
-k build.keychain \
-P "$APPLE_CERT_PASSWORD" \
-T /usr/bin/codesign \
-T /usr/bin/security
security set-key-partition-list \
-S apple-tool:,apple: \
-s \
-k temp123 \
build.keychain
- name: Build packaged archive
id: package
env:
APPLE_SIGNING_IDENTITY: ${{ vars.APPLE_SIGNING_IDENTITY || secrets.APPLE_SIGNING_IDENTITY }}
shell: bash
run: |
python scripts/package_release.py \
--target "${{ matrix.target }}" \
--archive-dir build/artifacts \
--github-output "${GITHUB_OUTPUT}"
- name: Report packaged archive size
shell: bash
run: |
ls -lh "${{ steps.package.outputs.archive_path }}"
- name: Verify macOS packaged signature
if: runner.os == 'macOS'
shell: bash
run: |
codesign --verify --verbose=4 "${{ steps.package.outputs.bundle_executable }}"
codesign --display --verbose=4 "${{ steps.package.outputs.bundle_executable }}"
spctl -a -t exec -vv "${{ steps.package.outputs.bundle_executable }}" || true
- name: Smoke test packaged help output
shell: bash
run: |
"${{ steps.package.outputs.bundle_executable }}" --help
- name: Restore App Store Connect key
if: runner.os == 'macOS'
env:
APPSTORE_CONNECT_API_KEY_P8_BASE64: ${{ secrets.APPSTORE_CONNECT_API_KEY_P8_BASE64 }}
shell: bash
run: |
echo "$APPSTORE_CONNECT_API_KEY_P8_BASE64" | base64 --decode > AuthKey.p8
- name: Notarise macOS archive
if: runner.os == 'macOS'
env:
APPSTORE_CONNECT_KEY_ID: ${{ vars.APPSTORE_CONNECT_KEY_ID || secrets.APPSTORE_CONNECT_KEY_ID }}
APPSTORE_CONNECT_ISSUER_ID: ${{ vars.APPSTORE_CONNECT_ISSUER_ID || secrets.APPSTORE_CONNECT_ISSUER_ID }}
shell: bash
run: |
xcrun notarytool submit "${{ steps.package.outputs.archive_path }}" \
--key AuthKey.p8 \
--key-id "$APPSTORE_CONNECT_KEY_ID" \
--issuer "$APPSTORE_CONNECT_ISSUER_ID" \
--wait
- name: Real backend smoke after packaging
if: matrix.run_real_smoke
shell: bash
run: python scripts/real_backend_smoke.py --binary "${{ steps.package.outputs.bundle_executable }}"
- name: Upload packaged artefact
uses: actions/upload-artifact@v6
with:
name: ${{ matrix.target }}
path: ${{ steps.package.outputs.archive_path }}
publish:
if: startsWith(github.ref, 'refs/tags/v')
needs: build
runs-on: ubuntu-24.04
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:
- name: Download packaged artefacts
uses: actions/download-artifact@v8
with:
path: release-artifacts
merge-multiple: true
- name: Filter release assets to GitHub size limit
id: release_assets
shell: bash
run: |
mkdir -p release-upload
LIMIT_BYTES=2147483647
for path in release-artifacts/*; do
if [[ ! -f "$path" ]]; then
continue
fi
size_bytes="$(stat -c %s "$path")"
name="$(basename "$path")"
if (( size_bytes > LIMIT_BYTES )); then
echo "Skipping oversized release asset: ${name} (${size_bytes} bytes)" >&2
if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then
echo "- skipped \`${name}\` because it exceeds the GitHub Release asset limit (${size_bytes} bytes)" >> "$GITHUB_STEP_SUMMARY"
fi
continue
fi
cp "$path" "release-upload/$name"
done
if ! compgen -G "release-upload/*" > /dev/null; then
echo "No release assets fit within the GitHub Release size limit." >&2
exit 1
fi
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: release-upload/*
- name: Send Slack notification
if: env.SLACK_WEBHOOK_URL != ''
uses: slackapi/slack-github-action@v2.1.1
with:
webhook: ${{ env.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
text: "🚀 bitloops-embeddings ${{ github.ref_name }} has been released!"