Skip to content

CI: pixi lockfile refresh #16

CI: pixi lockfile refresh

CI: pixi lockfile refresh #16

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
# Scheduled (and on-demand) pixi lockfile refresh. All workspaces are updated
# in one job and, when anything changes, one PR. See #2298 and #2849.
name: "CI: pixi lockfile refresh"
on:
schedule:
# Monday 03:17 Eastern. GitHub handles the DST offset for the IANA zone,
# and a non-zero minute avoids the start-of-hour window where GitHub
# documents scheduled runs being delayed or dropped.
- cron: "17 3 * * 1"
timezone: "America/New_York"
workflow_dispatch: {}
defaults:
run:
shell: bash --noprofile --norc -xeuo pipefail {0}
permissions: {}
jobs:
refresh:
name: pixi update (all workspaces)
if: ${{ github.repository_owner == 'nvidia' }}
runs-on: ubuntu-latest
timeout-minutes: 195
permissions:
contents: write
pull-requests: write
concurrency:
group: pixi-lock-refresh
cancel-in-progress: false
steps:
- name: Checkout ${{ github.event.repository.name }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history and tags for package metadata, without historical
# file contents. See ci/README.md for the checkout policy.
fetch-depth: 0
filter: blob:none
ref: ${{ github.event.repository.default_branch }}
- name: Setup pixi
id: setup-pixi
uses: ./.github/actions/setup-pixi
# Pixi 0.73.0's update and lock-read paths can serialize the same solve
# differently (#2804). Canonicalize with the same operation used by the
# freshness workflow before opening the PR. If cuda_core hits the exact
# samples-source pruning defect guarded there, retain its committed lock
# and continue refreshing the other workspaces.
- name: Update and canonicalize all lockfiles
id: update
env:
PIXI_VERSION: ${{ steps.setup-pixi.outputs.pixi-version }}
WORKSPACE_TIMEOUT: 30m
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}"
)"
while IFS= read -r workspace; do
manifest="$(jq -r '.manifest' <<<"${workspace}")"
lockfile="$(jq -r '.lockfile' <<<"${workspace}")"
echo "::group::pixi update (${manifest})"
workspace_status=0
# The single-quoted script expands its variables in the child shell.
# shellcheck disable=SC2016
timeout --kill-after=1m "${WORKSPACE_TIMEOUT}" \
bash --noprofile --norc -xeuo pipefail -c '
manifest="$1"
lockfile="$2"
pixi_version="$3"
committed_blob="$(git hash-object "${lockfile}")"
pixi update --no-install --manifest-path "${manifest}"
# The detector reads this uncommitted post-update state through
# git cat-file, so explicitly persist the blob in the runner-local
# temporary object database.
updated_blob="$(git hash-object -w "${lockfile}")"
check_status=0
pixi lock --check --manifest-path "${manifest}" \
|| check_status=$?
if ((check_status != 0)); then
defect_status=1
if [[ "${manifest}" == "cuda_core" ]]; then
defect_status=0
python3 ci/tools/check_pixi_samples_source_pruning.py \
--original-blob "${updated_blob}" \
--lockfile "${lockfile}" \
--manifest-path "${manifest}/pixi.toml" \
--pixi-version "${pixi_version}" \
--check-status "${check_status}" \
|| defect_status=$?
fi
if ((defect_status == 0)); then
echo "::warning title=Known Pixi samples lockfile bug::Pixi ${pixi_version} removed only the nine samples local-source references after updating ${lockfile}. Keeping the committed cuda_core lockfile and continuing with the other workspaces; all other refresh failures remain strict."
git cat-file blob "${committed_blob}" > "${lockfile}"
echo "known-defect-skipped=true" >> "${GITHUB_OUTPUT}"
exit 0
elif [[ "${manifest}" == "cuda_core" ]] && ((defect_status != 1)); then
echo "::error::Could not determine whether ${lockfile} matches the known Pixi samples-source pruning defect. Resolve the detector error above and rerun."
exit "${defect_status}"
fi
exit "${check_status}"
fi
canonical_blob="$(git hash-object "${lockfile}")"
verify_status=0
pixi lock --check --manifest-path "${manifest}" \
|| verify_status=$?
verified_blob="$(git hash-object "${lockfile}")"
if ((verify_status != 0)) || [[ "${canonical_blob}" != "${verified_blob}" ]]; then
echo "::error::pixi ${pixi_version} did not reach a successful byte-stable check for ${lockfile} (verification exit ${verify_status}, canonical blob ${canonical_blob}, verified blob ${verified_blob}); refusing to open an unstable refresh PR."
exit 1
fi
' bash "${manifest}" "${lockfile}" "${PIXI_VERSION}" \
|| workspace_status=$?
if ((workspace_status == 124 || workspace_status == 137)); then
echo "::error::Timed out after ${WORKSPACE_TIMEOUT} while refreshing '${manifest}'."
elif ((workspace_status != 0)); then
echo "::error::Failed to refresh '${manifest}' (exit ${workspace_status})."
fi
echo "::endgroup::"
if ((workspace_status != 0)); then
exit "${workspace_status}"
fi
done <<<"${workspace_rows}"
{
echo "lockfiles<<EOF"
jq -r '.[].lockfile' <<<"${workspaces}"
echo "EOF"
} >> "${GITHUB_OUTPUT}"
- name: Compose PR body
id: pr-body
env:
KNOWN_DEFECT_SKIPPED: ${{ steps.update.outputs.known-defect-skipped }}
PIXI_VERSION: ${{ steps.setup-pixi.outputs.pixi-version }}
run: |
body_path="${RUNNER_TEMP}/pixi-lock-refresh-body.md"
{
echo "Automated lockfile refresh using pixi" \
"\`${PIXI_VERSION}\` (\`pixi update --no-install\`, followed by" \
"byte-stable \`pixi lock --check\` canonicalization for each" \
"refreshed workspace)."
if [[ "${KNOWN_DEFECT_SKIPPED}" == "true" ]]; then
echo
echo "> [!NOTE]"
echo "> \`cuda_core/pixi.lock\` was left unchanged because Pixi" \
"\`${PIXI_VERSION}\` reproduced the exact known samples-source" \
"pruning defect. Other workspaces were refreshed normally."
fi
echo
echo "Lockfiles covered by the refresh:"
python3 ci/tools/list_pixi_workspaces.py \
| jq -r '.[] | "- `\(.lockfile)`"'
echo
echo "See #2298 and #2849."
echo
echo "> [!IMPORTANT]"
echo "> This PR was opened with \`GITHUB_TOKEN\`. A maintainer with write access must:"
echo ">"
echo "> 1. Select **Approve workflows to run** in the merge box."
echo "> 2. Assign themselves to this PR. The human-generated \`assigned\` event"
echo "> creates the required **PR has assignee, labels, and milestone** check"
echo "> and gives the PR a clear owner."
echo
echo "If the diff looks wrong, close this PR and leave the branch deleted; the"
echo "next scheduled run opens a fresh one if an update is still needed."
} > "${body_path}"
echo "path=${body_path}" >> "${GITHUB_OUTPUT}"
- name: Open or update a lockfile-only PR
id: cpr
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ github.token }}
add-paths: ${{ steps.update.outputs.lockfiles }}
commit-message: "chore: refresh pixi lockfiles"
signoff: true
sign-commits: true
branch: ci/pixi-lock-refresh/all
delete-branch: true
title: "chore: refresh pixi lockfiles"
labels: |
CI/CD
dependencies
body-path: ${{ steps.pr-body.outputs.path }}
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- name: Warn about required maintainer action
if: ${{ steps.cpr.outputs.pull-request-operation == 'created' || steps.cpr.outputs.pull-request-operation == 'updated' }}
run: echo "::warning::The refresh PR requires a maintainer to approve its workflow runs and assign themselves to create the required metadata check."
- name: Summarize
run: |
{
echo "### pixi lock refresh (all workspaces)"
echo ""
echo "- Operation: \`${{ steps.cpr.outputs.pull-request-operation }}\`"
if [ -n "${{ steps.cpr.outputs.pull-request-url }}" ]; then
echo "- PR: ${{ steps.cpr.outputs.pull-request-url }}"
else
echo "- No lockfile diff; PR not opened."
fi
if [[ "${{ steps.update.outputs.known-defect-skipped }}" == "true" ]]; then
echo "- \`cuda_core/pixi.lock\` retained its committed state because the exact known Pixi samples-source pruning defect was detected."
fi
} >> "$GITHUB_STEP_SUMMARY"