Skip to content

Use default setuptools-scm tag parsing #82

Use default setuptools-scm tag parsing

Use default setuptools-scm tag parsing #82

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
# Fails when a committed pixi.lock is out of date with its pixi.toml, or when
# its bytes are not what the pinned pixi version generates.
# Remediation for both: regenerate and commit the lockfile with that pixi
# version, e.g.
# pixi lock --manifest-path <path>
# Keep this check advisory during its initial rollout. Before making it
# required, expose a stable aggregate check, account for the path filters, and
# record the decision in #2804 after the workflow has operational history.
# See #2298.
name: "CI: pixi lockfile freshness check"
concurrency:
# Keyed on the event as well as the ref so a manual dispatch and a push to
# the same branch do not cancel each other.
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
on:
pull_request:
# `pyproject.toml` is a lockfile input too: the manifests consume sibling
# packages (including cuda_python_test_helpers) as path dependencies, so
# their metadata can stale a lock without any pixi.toml edit. Matched by
# glob rather than by name so the filter cannot drift as packages move.
paths: &lockfile_inputs
- "**/pixi.toml"
- "**/pixi.lock"
- "**/pyproject.toml"
- "ci/tools/list_pixi_workspaces.py"
- "ci/pixi-version.env"
- ".github/actions/setup-pixi/action.yml"
- ".github/workflows/ci-pixi-lockfile-freshness-check.yml"
push:
# `pull_request` already covers PRs, including those from forks: this check
# needs no secrets or GPU runner. Watching copy-pr-bot's `pull-request/N`
# mirror too would run the whole check a second time per PR.
branches:
- "main"
paths: *lockfile_inputs
workflow_dispatch: {}
defaults:
run:
shell: bash --noprofile --norc -xeuo pipefail {0}
env:
REFRESH_WORKFLOW_URL: "https://github.com/NVIDIA/cuda-python/actions/workflows/ci-pixi-lockfile-refresh.yml"
permissions: {}
jobs:
lockfile-fresh:
name: pixi lock --check (all workspaces)
if: ${{ github.repository_owner == 'nvidia' }}
runs-on: ubuntu-latest
timeout-minutes: 135
permissions:
contents: read
steps:
- name: Checkout ${{ github.event.repository.name }}
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
persist-credentials: false
- name: Setup pixi
id: setup-pixi
uses: ./.github/actions/setup-pixi
# `pixi lock --check` exits 0 on a semantically current lock even when it
# rewrites the file into the pinned version's canonical form (lockfile
# format upgrades, platform alias renames). Without this guard that drift
# is invisible: the check prints "Updated lock file" and still passes,
# while every later pixi run keeps rewriting the committed file (#2298).
- name: Check all lockfiles
env:
PIXI_VERSION: ${{ steps.setup-pixi.outputs.pixi-version }}
WORKSPACE_TIMEOUT: 20m
run: |
workspaces="$(python3 ci/tools/list_pixi_workspaces.py)"
workspace_rows="$(
jq -ce '
if type != "array" or length == 0 then
error("workspace inventory must be a non-empty array")
elif any(.[];
type != "object"
or (.manifest | type != "string")
or (.lockfile | type != "string")
or .manifest == ""
or .lockfile == ""
) then
error("each workspace must have non-empty string manifest and lockfile fields")
else
.[]
end
' <<<"${workspaces}"
)"
failed=0
while IFS= read -r workspace; do
manifest="$(jq -r '.manifest' <<<"${workspace}")"
lockfile="$(jq -r '.lockfile' <<<"${workspace}")"
echo "::group::pixi lock --check (${manifest})"
check_status=0
timeout --kill-after=1m "${WORKSPACE_TIMEOUT}" \
pixi lock --check --manifest-path "${manifest}" \
|| check_status=$?
if ((check_status == 124 || check_status == 137)); then
echo "::error::Timed out after ${WORKSPACE_TIMEOUT} while checking '${manifest}'."
failed=1
elif ((check_status != 0)); then
echo "::error::Lockfile is stale for '${manifest}'. Regenerate with: pixi lock --manifest-path ${manifest}. For default-branch dependency drift, maintainers can run ${REFRESH_WORKFLOW_URL}"
failed=1
elif ! git diff --exit-code -- "${lockfile}"; then
echo "::error::pixi ${PIXI_VERSION} rewrote ${lockfile} during the check, so the committed bytes are not what it generates. Regenerate with pixi ${PIXI_VERSION}: pixi lock --manifest-path ${manifest}. For default-branch dependency drift, maintainers can run ${REFRESH_WORKFLOW_URL}"
failed=1
fi
echo "::endgroup::"
done <<<"${workspace_rows}"
exit "${failed}"