Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ runs:
brew update
brew trust aws/tap # suppress warning in github actions
brew install openmpi
xcodebuild -version
swift --version
xcodebuild -showComponent MetalToolchain
sysctl -a | grep machdep.cpu

Expand All @@ -75,17 +77,18 @@ runs:
:: Export to all steps.
>>%GITHUB_ENV% set

- uses: astral-sh/setup-uv@v8.2.0
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: false
quiet: true

- name: Use ccache
if: inputs.use-ccache == 'true'
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: v7-${{ inputs.ccache-key }}-${{ runner.os }}-${{ runner.arch }}-${{ inputs.ccache-toolkit || inputs.toolkit }}
max-size: |-
# The organization blocks hendrikmuhs/ccache-action. The next three steps
# do the same work with Homebrew and actions/cache. They run on macOS only.
- name: Install ccache
if: runner.os == 'macOS' && inputs.use-ccache == 'true'
shell: bash
env:
MAX_SIZE: |-
${{ case(inputs.ccache-key == 'release',
case(startsWith(inputs.toolkit, 'cuda'),
case(runner.os == 'Linux', '300MB',
Expand All @@ -98,13 +101,36 @@ runs:
runner.os == 'macOS' && inputs.toolkit == 'metal', '300MB',
'200MB'))
}}
save: ${{ !startsWith(github.ref, 'refs/pull/') && (inputs.ccache-save != 'false') }}
# ccache-action bug: running "apt-get update" fails on large arm runner.
update-package-index: false
run: |
brew install ccache
ccache --set-config=cache_dir="$GITHUB_WORKSPACE/.ccache"
ccache --set-config=max_size="$MAX_SIZE"
ccache --set-config=compression=true
ccache --set-config=compiler_check=content
ccache -p

- name: Restore the ccache files
# Pull requests only restore the cache. They do not save it.
if: runner.os == 'macOS' && inputs.use-ccache == 'true' && !(github.event_name == 'push' && github.ref == 'refs/heads/main' && inputs.ccache-save != 'false')
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: ${{ github.workspace }}/.ccache
key: ccache-${{ inputs.ccache-key }}-${{ runner.os }}-${{ runner.arch }}-${{ inputs.ccache-toolkit || inputs.toolkit }}-${{ github.sha }}
restore-keys: ccache-${{ inputs.ccache-key }}-${{ runner.os }}-${{ runner.arch }}-${{ inputs.ccache-toolkit || inputs.toolkit }}-

- name: Restore the ccache files and save them at the end of the job
# Pushes to main restore the cache. actions/cache saves it at the end
# of the job, and only when the job succeeds.
if: runner.os == 'macOS' && inputs.use-ccache == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' && inputs.ccache-save != 'false'
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: ${{ github.workspace }}/.ccache
key: ccache-${{ inputs.ccache-key }}-${{ runner.os }}-${{ runner.arch }}-${{ inputs.ccache-toolkit || inputs.toolkit }}-${{ github.sha }}
restore-keys: ccache-${{ inputs.ccache-key }}-${{ runner.os }}-${{ runner.arch }}-${{ inputs.ccache-toolkit || inputs.toolkit }}-

- name: Cache JIT-compiled CUDA kernels
if: runner.os == 'Linux' && startsWith(inputs.toolkit, 'cuda')
uses: actions/cache@v5
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: /tmp/mlx-ptx-cache
key: >-
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/fork-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Fork Tests

# Build the fork with Metal and run its C++ and Python tests on a
# GitHub-hosted macOS runner. The steps use the actions in .github/actions.

on:
pull_request:
push:
branches:
- main
workflow_dispatch:

jobs:
metal-build-and-test:
runs-on: macos-26
timeout-minutes: 60
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
# Cancel an older run of the same pull request. Let runs on main finish.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: ./.github/actions/setup
id: setup
with:
toolkit: metal
# This cache key is not an upstream key. The setup action saves
# the cache on pushes to main only, never on pull requests.
ccache-key: fork-tests

- uses: ./.github/actions/build-macos
with:
cmake-args: ${{ steps.setup.outputs.cmake-args }}
# The runner has macOS 26. Version 26.2 is the lowest target that
# builds all Metal kernels.
macos-target: '26.2'

- uses: ./.github/actions/test-macos
with:
toolkit: metal
9 changes: 8 additions & 1 deletion fork.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ def:
- ".github/actions/build/action.yml"
- ".github/actions/build-macos/action.yml"
- ".github/actions/build-wheel/action.yml"
- ".github/actions/setup/action.yml"
- ".github/actions/test-linux/action.yml"
- ".github/actions/test-macos/action.yml"
- ".github/actions/test-wheel/action.yml"
Expand Down Expand Up @@ -266,10 +265,18 @@ def:
The gate that keeps this page honest: `check_forkdiff.py` fails CI when `base.hash` is
not the merge-base with upstream, when a file the fork changes is not described by a
section above, or when a section names files the fork no longer changes.

`fork-tests.yml` builds the fork with Metal and runs its C++ and Python tests on a
GitHub-hosted macOS runner. The `setup` action pins its actions to full commit SHAs,
because the organization blocks actions that are not pinned. The organization also
blocks `hendrikmuhs/ccache-action`, so `setup` installs ccache with Homebrew and keeps
the ccache files with `actions/cache`.
globs:
- "scripts/check_forkdiff.py"
- "FORKDIFF.md"
- "README.md"
- ".github/actions/setup/action.yml"
- ".github/workflows/fork-tests.yml"

# ignored globally, does not count towards line count
ignore:
Expand Down
Loading