Skip to content

Use Pixi in macOS-intel CI - #13704

Draft
scott-huberty wants to merge 114 commits into
mne-tools:mainfrom
scott-huberty:pixi
Draft

Use Pixi in macOS-intel CI#13704
scott-huberty wants to merge 114 commits into
mne-tools:mainfrom
scott-huberty:pixi

Conversation

@scott-huberty

Copy link
Copy Markdown
Contributor

I'm exploring the feasibility of using Pixi to resolve the virtual environment and run tests specifically for the MacOS Intel CI, which currently uses Mamba to create the virtual environment.

My initial strategy was to just to do pixi init --import environment.yml, so that we can leverage our already defined YAML config file to pull in all the necessary dependencies, as well as configuring prefix-dev/setup-pixi to automatically activate our virtual environment, so that we can run commands like pytest etc without having to prepend pixi run everywhere for the pixi CI...

Unfortunately the only way I could get this to work was to disable use of a login shell.. Which of course makes all the condo-like CI's fail!!

@scott-huberty
scott-huberty marked this pull request as draft February 28, 2026 00:28
@tsbinns

tsbinns commented Feb 28, 2026

Copy link
Copy Markdown
Contributor

Hey @scott-huberty, looking at the current diff I noticed you're setting up pixi without activating the env, initing with environment.yml, then setting up again with env activation.

Found when switching to uv for the old job that the env can be activated at setup with a given Python ver and then have the required packages installed in github_actions_dependencies.sh:

- uses: astral-sh/setup-uv@v7
with:
version: ">=0.9"
activate-environment: true
cache-dependency-glob: |
**/pylock.ci-old.toml
python-version: ${{ matrix.python }}
if: matrix.kind == 'old'
- run: bash ./tools/github_actions_dependencies.sh

Wondered if a similar thing could work for pixi rather than needing 2 setups. Haven't looked through diffs for all commits, so apologies if you tried this already.

run: |
pixi run python tools/write-pixi-toml.py
pixi lock --no-install --manifest-path tools/ci/macos-intel/
if: steps.status.outputs.dirty == 'true'

@drammock drammock Jun 11, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PR the steps are:

  1. run spec_zero_update_versions.py (which may change pyproject.toml)
  2. run tools/sync_dependencies.py (updates README)
  3. create lockfile for old CI and check its pins
  4. check for dirty files
  5. install pixi (if dirty)
  6. update the pixi.toml file for macos-intel CI (if dirty)
  7. run pre-commit (if dirty); specifically for tools/hooks/update_environment_file.py
  8. create PR (if dirty)

I'm wondering if we should instead:

  • check for dirty repo immediately after step 1
  • gate steps 2 & 3 on (if dirty)
  • (optional) use a faster way of checking for dirty files, namely:
if $(git diff --quiet HEAD -- pyproject.toml); then
  echo "dirty=true" >> $GITHUB_OUTPUT
fi

@scott-huberty @larsoner @tsbinns WDYT?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be the case where tools/sync_dependencies.py creates a diff independently from spec_zero_update_versions.py if a change was made in a PR to a dep specifier in pyproject.toml, but the README wasn't updated at the same time.

Currently, the missing update of the README would get caught and fixed the next time the SPEC0 action gets run, but the suggested change would gate this behind spec_zero_update_versions.py introducing some changes.

This could lead to deps listed in README being out-of-date for several weeks/months, which was what we tried to resolve in #13832 by adding the README syncing to the SPEC0 action.

Maybe it is safer therefore to only gate step 3 on whether it is dirty?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok right, thanks for the reminder. so we do want step 2 to always run. And it seems like the same logic could also apply to step 3? E.g., someone changes a minimum pin manually in a PR but then spec_zero_update_versions.py happens not to bump anything, then pyproject.toml wouldn't show up as dirty when this action runs (but we'd still want to update the old CI pins). This makes me think that we should not even gate steps 5-7 either; they should all just run and we should only use the dirty check to decide whether the action needs to make a commit.

notes:

  1. keeping the gating for step 7 is probably fine, since currently it's run via pre-commit, so environment.yml doesn't risk getting out of sync the same way that the README does... but I'd actually lean toward removing the environment.yml updater from pre-commit, and standardizing our procedure as "all of the trickle-down effects of dep/pin changes in pyproject.toml happen at the same time (weekly cron job)" instead of some-but-not-all being part of our pre-commit checks.
  2. if we do switch to the faster way of checking for dirty files (and I'd like us to, because the faster way also avoids false positives when testing locally in the presence of untracked files), it shouldn't only look at pyproject.toml anymore, it should just be: git diff --quiet HEAD

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, all tests are passing!

So we should we remove the dirty gate from the install pixi / update pixi.toml steps (steps 5-6)?

@drammock

Copy link
Copy Markdown
Member

TODO @scott-huberty make it so that the matrix python version specified in tests.yml gets inserted into the pixi.toml file

scott-huberty and others added 5 commits July 8, 2026 21:17
- The Pixi job replaces teh MacOS pip job on main.

- The MacOS pip job on main does not set MNE_TEST_ALLOW_SKIP

- mne/conftest.py:1357 treats unset MNE_TEST_ALLOW_SKIP as “allow all skips"

@scott-huberty scott-huberty left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doh... Never submitted this review, which was just 1 comment!!

run: |
pixi run python tools/write-pixi-toml.py
pixi lock --no-install --manifest-path tools/ci/macos-intel/
if: steps.status.outputs.dirty == 'true'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, all tests are passing!

So we should we remove the dirty gate from the install pixi / update pixi.toml steps (steps 5-6)?

@drammock

Copy link
Copy Markdown
Member

after adding a "this is autogenerated" comment to the top of pixi.toml (which may need slightly altering how we write it with tomlkit, i.e., dumping a tomlkit.document() instead of a dict), I think we'll be ready to merge here. @scott-huberty and I discussed migrating some of this into mne-tools/mne-tools already, and will do that in follow-up PRs

@scott-huberty

Copy link
Copy Markdown
Contributor Author

after adding a "this is autogenerated" comment to the top of pixi.toml ... I think we'll be ready to merge here.

done in e5bd471

Comment thread tools/write-pixi-toml.py Outdated
@drammock

Copy link
Copy Markdown
Member

@scott-huberty

scott-huberty commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

possible problem: seems like environment is getting MNE stable release (not main/PR):

https://github.com/mne-tools/mne-python/actions/runs/30474035062/job/90651542841?pr=13704#step:18:61

probably because of this:

https://github.com/mne-tools/mne-python/actions/runs/30474035062/job/90651542841?pr=13704#step:9:372

hmm The pixi.lock file has: - conda: https://conda.anaconda.org/conda-forge/noarch/mne-base-1.12.1-pyh694c41f_200.conda

EDIT: Maybe because pixi.toml requests mne-qt-browser = "*" which pulls in MNE stable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants