Skip to content
Closed
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SCM syntax highlighting & preventing 3-way merges
pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff
64 changes: 64 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Test cache-pixi-lock action

on:
push:
branches: [main, test-me/*]
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
PIXI_VERSION: "v0.63.0"
Comment on lines +13 to +14
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Pinning the version of Pixi for now. Thinking of making dependabot manage this - though that would come in a future PR


jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
cache-frequency: [daily, weekly, monthly]
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
path: create-pixi-lock

- name: Copy test files to working directory
shell: bash
run: cp -r create-pixi-lock/ci/test/* .

- name: Run create-pixi-lock action
uses: ./create-pixi-lock
with:
cache-frequency: ${{ matrix.cache-frequency }}
pixi-version: ${{ env.PIXI_VERSION }}

- name: Verify pixi.lock exists
shell: bash
run: |
if [ -f "pixi.lock" ]; then
echo "pixi.lock exists"
else
echo "pixi.lock does not exist"
exit 1
fi

- name: Setup pixi and install environment
uses: prefix-dev/setup-pixi@v0.9.3
with:
pixi-version: ${{ env.PIXI_VERSION }}
Comment on lines +50 to +53
Copy link
Collaborator Author

@VeckoTheGecko VeckoTheGecko Jan 16, 2026

Choose a reason for hiding this comment

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

I do get an error

Run prefix-dev/setup-pixi@v0.9.3
  with:
    pixi-version: v0.63.0
  env:
    PIXI_VERSION: v0.63.0
Downloading Pixi
  Destination file path /Users/runner/.pixi/bin/pixi already exists
  Waiting 16 seconds before trying again
  Destination file path /Users/runner/.pixi/bin/pixi already exists
  Waiting 13 seconds before trying again

which to be honest I did expect - I didn't think setup-pixi would be idempotent .

Also I just saw

Since pixi is not yet stable, the API of this action may change between minor versions. Please pin the versions of this action to a specific version (i.e., prefix-dev/setup-pixi@v0.9.3) to avoid breaking changes.

in the README.md - making using setup-pixi two times like we do here less viable an option.

Is there a way that we can, in the lock generation, install pixi to a set location (unlikely to interfere with other things), generate the lock file, all while being cross platform?

Copy link
Collaborator Author

@VeckoTheGecko VeckoTheGecko Jan 16, 2026

Choose a reason for hiding this comment

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

generate the lock file, all while being cross platform?

Looking at the guts of setup-pixi https://github.com/prefix-dev/setup-pixi/blob/51b98037a96d8c8de9468a767400f984d173fd90/src/util.ts#L60-L71 - uhhhh, maybe not as simple as I hoped! 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

And looks like Docker container actions are Linux only - that was going to be my next try 😭

https://docs.github.com/en/actions/concepts/workflows-and-actions/custom-actions#types-of-actions

Hopefully someone has more ideas



- name: Verify environment installed
shell: bash
run: |
if [ -d ".pixi/envs/default" ]; then
echo "Environment installed successfully"
else
echo "Environment not installed"
exit 1
fi
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# pixi environments
.pixi/*
!.pixi/config.toml

pixi.lock
26 changes: 26 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-ast
- id: check-json
types: [text]
files: \.(json|ipynb)$
- repo: https://github.com/rbubley/mirrors-prettier # Update mirror as official mirror is deprecated
rev: v3.6.2
hooks:
- id: prettier
- repo: https://github.com/ComPWA/taplo-pre-commit
rev: v0.9.3
hooks:
- id: taplo-format
args:
[
"--option",
"array_auto_collapse=false",
"--option",
"align_comments=false",
]
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# create-pixi-lock

> [!NOTE]
> This repo is likely to be moved to https://github.com/xarray-contrib
Copy link

Choose a reason for hiding this comment

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

depending on how useful this is it might actually make sense to ask the pixi devs whether they would like to move it to the official pixi org


This action creates a `pixi.lock` file and caches it for future use. Subsequent runs of this action on the same day restore the lock file instead of generating it anew.


## Usage

Basic usage with a set version of Pixi as well as daily cached lockfile:

```yaml
env:
PIXI_VERSION: "v0.63.0"

# ...
steps:
- uses: actions/checkout@v4

- uses: Parcels-code/create-pixi-lock@v1
with:
pixi-version: ${{ env.PIXI_VERSION }} # Default is latest - same as setup-pixi
cache-frequency: daily # options are "daily", "weekly", "monthly". Default "daily"
- uses: prefix-dev/setup-pixi@v0.9.3
with:
pixi-version: ${{ env.PIXI_VERSION }}
```

> [!NOTE]
> Pinning your Pixi version in CI and updating this pin manually ensures better
> stability. Otherwise updates to Pixi which introduce breaking changes in:
> - (a) the format of the lock file - which would break your CI for a period of `cache-frequency`, or
> - (b) the format of `pixi.toml` - which would break your CI until you fix it.

## Why not commit the lock file?

Committing your lock file is considered good practice when working on application code. Providing fixed package versions results in perfect reproducibility of environments between machines, and hence also reproducibility of results.

When developing and testing _library_ code, we don't want our environments to stay completely fixed - we want to test against environments covering a wide range of package versions to ensure compatability, including an environment that includes the latest available versions of packages.

The easiest way to test against the latest versions of packages - and avoid the noisy commit history (and additional overhead) of regularly updating a lock file in git - is instead to ignore the lock file and rely on developers and CI to generate their own lock files. This forgoes perfect reprodubility between developer machines, and with CI machines.


## Dev notes

### Release checklist

- Update the `README.md` bumping the version of action
- Cut release
62 changes: 62 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Create Pixi Lock
description: Generate and cache a pixi.lock file, restoring from cache when available.

inputs:
pixi-version:
description: "Version of pixi to use for generating the lock file"
required: false
default: "latest"
cache-frequency:
description: "How often to regenerate the lock file: 'daily', 'weekly', or 'monthly'"
required: false
default: "daily"

runs:
using: "composite"
steps:
- name: Get cache key
id: cache-key
shell: bash
run: |
case "${{ inputs.cache-frequency }}" in
daily)
key=$(date +'%Y-%m-%d')
;;
weekly)
key=$(date +'%Y-week-%V')
;;
monthly)
key=$(date +'%Y-month-%m')
;;
*)
echo "Invalid cache-frequency: ${{ inputs.cache-frequency }}. Must be 'daily', 'weekly', or 'monthly'."
exit 1
;;
esac
echo "key=$key" >> "$GITHUB_OUTPUT"

- name: Restore pixi.lock from cache
uses: actions/cache/restore@v5
id: restore
with:
path: pixi.lock
key: ${{ steps.cache-key.outputs.key }}_${{ inputs.pixi-version }}_${{ hashFiles('pixi.toml') }}

- name: Setup pixi
uses: prefix-dev/setup-pixi@v0.9.3
if: ${{ !steps.restore.outputs.cache-hit }}
with:
pixi-version: ${{ inputs.pixi-version }}
run-install: false
Comment on lines +45 to +50
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Is there a concern with using prefix-dev/setup-pixi@v0.9.3 here - with knowledge that it will be called again in the users workflow later?


- name: Run pixi lock
if: ${{ !steps.restore.outputs.cache-hit }}
shell: bash
run: pixi lock

- name: Save pixi.lock to cache
uses: actions/cache/save@v5
if: ${{ !steps.restore.outputs.cache-hit }}
with:
path: pixi.lock
key: ${{ steps.cache-key.outputs.key }}_${{ inputs.pixi-version }}_${{ hashFiles('pixi.toml') }}
14 changes: 14 additions & 0 deletions ci/test/pixi.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[workspace]
authors = ["Vecko <36369090+VeckoTheGecko@users.noreply.github.com>"]
channels = ["conda-forge"]
name = "test"
platforms = ["win-64", "linux-64", "osx-64", "osx-arm64", "linux-aarch64"]
version = "0.1.0"

[tasks]

[dependencies]
python = "*"
numpy = "*"
pandas = "*"
xarray = "*"
Loading