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
92 changes: 65 additions & 27 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
PIXI_VERSION: "v0.63.0"

jobs:
clear-cache:
runs-on: ubuntu-slim
Expand Down Expand Up @@ -44,12 +41,48 @@ jobs:
fi
echo "Cache cleared"

cache-pixi-lock:
test-cache-restore-install:
needs: clear-cache
runs-on: ubuntu-slim
outputs:
cache-key: ${{ steps.create-and-cache.outputs.cache-key }}
pixi-version: ${{ steps.create-and-cache.outputs.pixi-version }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Test OS values with fixed test-folder and pixi-version
- os: ubuntu-latest
test-folder: just-pixi-toml
expected-hash: "pixi-lock__69110db0bf39d7ce64fd774c7078ccd56ebf8542d9a1e86f84e63011634dc43f_2026-02-24"
pixi-version: ""
- os: macos-latest
test-folder: just-pixi-toml
expected-hash: "pixi-lock__69110db0bf39d7ce64fd774c7078ccd56ebf8542d9a1e86f84e63011634dc43f_2026-02-24"
pixi-version: ""
- os: windows-latest
test-folder: just-pixi-toml
expected-hash: "pixi-lock__adbacdefe20c62f204989acf366ef09911f3af89f066088613341b946be131e8_2026-02-24"
pixi-version: ""
# Test test-folder values with fixed OS and pixi-version
- os: ubuntu-latest
test-folder: just-pixi-toml
expected-hash: "pixi-lock__69110db0bf39d7ce64fd774c7078ccd56ebf8542d9a1e86f84e63011634dc43f_2026-02-24"
pixi-version: ""
- os: ubuntu-latest
test-folder: just-pyproject-toml
expected-hash: "pixi-lock__4a057faded2062ff018955c0be1db1b9e1d2fb8d1fe4303d8b778af7fd9e411d_2026-02-24"
pixi-version: ""
- os: ubuntu-latest
test-folder: pyproject-and-pixi-toml
expected-hash: "pixi-lock__b5bae43771086cb1dd79c43dc06881f8b0e006ad8c54e7269dad1a4f8ce96522_2026-02-24"
pixi-version: ""
# Test pixi-version values with fixed OS and test-folder
- os: ubuntu-latest
test-folder: just-pixi-toml
expected-hash: "pixi-lock__69110db0bf39d7ce64fd774c7078ccd56ebf8542d9a1e86f84e63011634dc43f_2026-02-24"
pixi-version: ""
- os: ubuntu-latest
test-folder: just-pixi-toml
expected-hash: "pixi-lock_v0.63.2_69110db0bf39d7ce64fd774c7078ccd56ebf8542d9a1e86f84e63011634dc43f_2026-02-24"
pixi-version: "v0.63.2"
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand All @@ -58,13 +91,27 @@ jobs:

- name: Copy test files to working directory
shell: bash
run: cp -r pixi-lock/ci/test/* .
run: cp -r pixi-lock/ci/test/${{ matrix.test-folder }}/* .

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

- name: Verify cache key hash matches expected
shell: bash
run: |
actual_hash="${{ steps.create-and-cache.outputs.cache-key }}"
expected_hash="${{ matrix.expected-hash }}"
echo "Expected hash: $expected_hash"
echo "Actual hash: $actual_hash"
if [ "$actual_hash" != "$expected_hash" ]; then
echo "ERROR: Hash mismatch!"
echo "Please update the expected-hash in the workflow matrix to: $actual_hash"
exit 1
fi
echo "Hash matches expected value"

- name: Verify pixi.lock exists
shell: bash
Expand All @@ -76,29 +123,20 @@ jobs:
exit 1
fi

restore-and-install:
needs: cache-pixi-lock
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-slim, macos-latest, windows-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
path: pixi-lock
- name: Cleanup pixi.lock
shell: bash
run: rm pixi.lock

- name: Copy test files to working directory
- name: Cleanup pixi install
shell: bash
run: cp -r pixi-lock/ci/test/* .
run: rm -rf ~/.pixi

- name: Restore pixi.lock from cache
uses: ./pixi-lock/restore
with:
cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }}
cache-key: ${{ steps.create-and-cache.outputs.cache-key }}

- name: Verify pixi.lock exists
- name: Verify pixi.lock exists after restore
shell: bash
run: |
if [ -f "pixi.lock" ]; then
Expand All @@ -111,7 +149,7 @@ jobs:
- name: Setup pixi and install environment
uses: prefix-dev/setup-pixi@v0.9.3
with:
pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }}
pixi-version: ${{ matrix.pixi-version }}

- name: Verify environment installed
shell: bash
Expand Down
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ This repo provides two GitHub Actions for generating and caching `pixi.lock` fil

This two-action pattern is so that the lockfile can be omitted from the git
history, but still be generated in a performant manner (i.e., regenerated
and cached with a key that depends on `pixi.toml` and the date -
and cached with a key that depends on `pixi.toml` and the date -
then shared across jobs).


## Usage

```yaml
Expand All @@ -25,7 +24,7 @@ jobs:
pixi-version: ${{ steps.pixi-lock.outputs.pixi-version }}
steps:
- uses: actions/checkout@v4
- uses: Parcels-code/pixi-lock/create-and-cache@... # TODO: Copy the hash for the rev you want to install from
- uses: Parcels-code/pixi-lock/create-and-cache@... # TODO: Copy the hash for the rev you want to install from
id: pixi-lock
with:
pixi-version: ... # TODO: update with your selected pixi version
Expand All @@ -45,7 +44,7 @@ jobs:
- uses: Parcels-code/pixi-lock/restore@ # TODO: Copy the hash for the rev you want to install from (same as above)
with:
cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }}
- uses: prefix-dev/setup-pixi@v... # TODO: update with your selected setup-pixi version
- uses: prefix-dev/setup-pixi@v... # TODO: update with your selected setup-pixi version
with:
pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }}
# ... your CI steps
Expand All @@ -55,20 +54,21 @@ jobs:

#### `create-and-cache`

| Input | Description | Required | Default |
|-------|-------------|----------|---------|
| `pixi-version` | Version of pixi to use for generating the lock file | No | `latest` |
| Input | Description | Required | Default |
| -------------- | ------------------------------------------------------- | -------- | -------------------------------- |
| `pixi-version` | Version of pixi to use for generating the lock file | No | `latest` |
| `hash-files` | Files to use to generate the hash key for the lock file | No | `pixi.toml` and `pyproject.toml` |

| Output | Description |
|--------|-------------|
| `pixi-version` | The pixi version used |
| `cache-key` | The cache key (includes today's date) |
| Output | Description |
| -------------- | ------------------------------------- |
| `pixi-version` | The pixi version used |
| `cache-key` | The cache key (includes today's date) |

#### `restore`

| Input | Description | Required |
|-------|-------------|----------|
| `cache-key` | The cache key from `create-and-cache` | Yes |
| Input | Description | Required |
| ----------- | ------------------------------------- | -------- |
| `cache-key` | The cache key from `create-and-cache` | Yes |

> [!NOTE]
> The cache key includes the current date, so the lock file is regenerated daily.
Expand All @@ -83,6 +83,7 @@ When developing and testing _library_ code, we don't want our environments to st
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 much simpler setup forgoes perfect reprodubility between developer machines, and with CI machines - which may be a worthwhile tradeoff for your project.

See the following threads for more detailed discussion:

- [prefix.dev Discord: Should you commit the lockfile](https://discord.com/channels/1082332781146800168/1462778624212996209)
- [Scientific Python Discord: lock files for libraries](https://discord.com/channels/786703927705862175/1450619697224487083)
- https://github.com/prefix-dev/pixi/issues/5325
File renamed without changes.
22 changes: 22 additions & 0 deletions ci/test/just-pyproject-toml/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[project]
name = "just-pyproject-toml"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []

[tool.pixi.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"

[tool.pixi.tasks]

[tool.pixi.dependencies]
python = "*"
numpy = "*"
pandas = "*"
xarray = "*"
14 changes: 14 additions & 0 deletions ci/test/pyproject-and-pixi-toml/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 = "*"
7 changes: 7 additions & 0 deletions ci/test/pyproject-and-pixi-toml/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[project]
name = "pyproject-and-pixi-toml"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
8 changes: 7 additions & 1 deletion create-and-cache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ inputs:
description: "Version of pixi to use for generating the lock file"
required: false
default: "latest"
hash-files:
description: "Files to use to generate the hash key for the lock file."
required: false
default: |
pixi.toml
pyproject.toml

outputs:
pixi-version:
Expand All @@ -23,7 +29,7 @@ runs:
shell: bash
run: |
today=$(date +'%Y-%m-%d')
key="pixi-lock_${{ inputs.pixi-version }}_${{ hashFiles('pixi.toml') }}_${today}"
key="pixi-lock_${{ inputs.pixi-version }}_${{ hashFiles(inputs.hash-files) }}_${today}"
echo "key=${key}" >> "$GITHUB_OUTPUT"

- name: Restore pixi.lock from cache
Expand Down
Loading