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
12 changes: 12 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Self-hosted runner labels used by this repo's workflows so actionlint does
# not flag them as unknown. The prod-nixl-*/stg-nixl-* runners are velonix ARC
# runner scale sets (see velonix flux-apps/.../runner-scale-sets/nixl).
self-hosted-runner:
labels:
- gitlab
- blossom
- prod-nixl-builder-amd-v1
- prod-nixl-builder-arm-v1
- prod-nixl-tester-gpu-v1
- stg-nixl-builder-amd-v1
- stg-nixl-builder-arm-v1
345 changes: 345 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,345 @@
name: NIXL CI

# Native GitHub Actions replacement for the GitLab pipeline that previously ran
# in nixl-ci (.gitlab-ci.yml). Builds run on self-hosted velonix ARC runners
# (prod-nixl-builder-amd-v1 / prod-nixl-builder-arm-v1), which provide an
# in-pod Docker daemon (dind sidecar), so the build/test docker commands below
# work just as they did under GitLab.
#
# Repository configuration required (Settings -> Secrets and variables -> Actions):
# Variables:
# NIXL_ECR_IMAGE - ECR image base, e.g.
# 210086341041.dkr.ecr.us-west-2.amazonaws.com/nixl-ci
# ENABLE_GPU_CI - set to "true" to enable the (currently deferred)
# GPU test/verify jobs once GPU runners exist.
# Secrets:
# GITLAB_REGISTRY_USER - user for gitlab-master.nvidia.com:5005 (manylinux
# GITLAB_REGISTRY_TOKEN base images + wheeltamer scan image)
# ARTIFACTORY_URL - JFrog Artifactory base URL (release uploads)
# ARTIFACTORY_PYPI_TOKEN
# ARTIFACTORY_CARGO_TOKEN
# AWS/ECR push auth comes from the runner pod's IRSA service account, not a secret.

on:
pull_request:
push:
Comment on lines +23 to +25

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.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Add a trust gate before running PR code on privileged self-hosted runners.

pull_request currently executes repository code on ARC self-hosted runners that also perform IRSA-backed AWS/ECR operations. Without a fork/trust guard, untrusted PR code can run in a privileged environment.

🔒 Minimal hardening pattern
 jobs:
   version:
+    if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
     runs-on: ${{ vars.NIXL_RUNNER_PREFIX || 'prod' }}-nixl-builder-amd-v1
@@
   build:
+    if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
     needs: version
     runs-on: ${{ vars.NIXL_RUNNER_PREFIX || 'prod' }}-nixl-builder-${{ matrix.runner }}-v1

Also applies to: 57-58, 92-93

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 23-37: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting

(concurrency-limits)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 23 - 25, The pull_request trigger in
the on section of the workflow currently allows untrusted code from forks to
execute on privileged self-hosted runners with AWS/ECR access. Add conditional
checks to jobs that use self-hosted runners to ensure they only execute on
trusted PRs from the repository itself, not from forks. Specifically, add a
condition checking that the pull request head repository matches the current
repository (using github.event.pull_request.head.repo.full_name ==
github.repository) to any jobs running on ARC self-hosted runners. Apply this
same trust gate pattern to all locations in the workflow where self-hosted
runners are used (including the additional locations at lines 57-58 and 92-93)
to prevent untrusted PR code from accessing privileged AWS/ECR operations.

branches: [main, 'release/**']
tags: ['v*']

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Tag pushes are not treated as release builds, so scan/upload release jobs are skipped.

Line 27 triggers on v* tags, but Line 50 and the release job if conditions only check dispatch input or release/** branches. A tag push will build but not run release scan/publish paths.

✅ Suggested fix
-  RELEASE_BUILD: ${{ github.event.inputs.release_build == true || github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') }}
+  RELEASE_BUILD: ${{ github.event.inputs.release_build == true || github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') || startsWith(github.ref, 'refs/tags/v') }}

-    if: ${{ github.event.inputs.security_scan == 'true' || github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') }}
+    if: ${{ github.event.inputs.security_scan == 'true' || github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') || startsWith(github.ref, 'refs/tags/v') }}

-    if: ${{ github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') }}
+    if: ${{ github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') || startsWith(github.ref, 'refs/tags/v') }}

Also applies to: 50-50, 185-185, 228-228, 266-266, 309-309

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 27, The workflow is triggered on version
tags (v*) at line 27, but the release job conditions at lines 50, 185, 228, 266,
and 309 only check for dispatch input or release/** branches, causing release
scan and publish jobs to be skipped on tag pushes. Update all the if condition
statements in the release jobs to also check for version tag triggers by adding
a condition that detects when the workflow was triggered by a tag matching the
v* pattern, ensuring the release jobs execute properly when tags are pushed.

workflow_dispatch:
inputs:
release_build:
description: "Build/publish release artifacts (maps to GitLab RELEASE_BUILD)"
type: boolean
default: false
security_scan:
description: "Run the wheel security scan (maps to GitLab SECURITY_SCAN)"
type: boolean
default: false

permissions:
contents: read

# Cancel superseded runs on the same ref. PRs cancel-in-progress (latest push
# wins); release/** + main pushes do NOT cancel, so an in-flight RC upload isn't
# interrupted mid-publish.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
Comment on lines +45 to +47

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Use a PR-unique concurrency key to avoid cross-PR cancellations.

At Line 46, github.head_ref is only the branch name. Two PRs with the same source branch name can cancel each other unintentionally.

🛠️ Proposed fix
 concurrency:
-  group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
   cancel-in-progress: ${{ github.event_name == 'pull_request' }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 45 - 47, The concurrency group at line
46 uses only the branch name (github.head_ref), which causes unintended
cancellations when multiple PRs are created from the same source branch. Modify
the concurrency group key to include a PR-specific identifier (such as the pull
request number from github.event.pull_request.number) in addition to or instead
of just the branch reference, ensuring that each PR has a unique concurrency key
while still allowing cancellation of previous runs within the same PR.


env:
AWS_REGION: us-west-2
REPO_NAME: nixl
WHL_PYTHON_VERSIONS: "3.10,3.11,3.12,3.13,3.14"
IMAGE_BASE: ${{ vars.NIXL_ECR_IMAGE }}
# Release flag, normalized to a plain "true"/"false" string usable in shells.
# True on a push to a release/** branch (e.g. a PR merged into release/1.3.0 triggers
# RC generation on the merge commit) or an explicit workflow_dispatch release_build.
RELEASE_BUILD: ${{ github.event.inputs.release_build == true || github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') }}

Comment thread
coderabbitai[bot] marked this conversation as resolved.
jobs:
# ----------------------------------------------------------------------------
# version: replicate the GitLab before_script version computation.
# ----------------------------------------------------------------------------
version:
runs-on: ${{ vars.NIXL_RUNNER_PREFIX || 'prod' }}-nixl-builder-amd-v1
outputs:
version: ${{ steps.compute.outputs.version }}
steps:
- uses: actions/checkout@v4

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.

🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Consider pinning actions to SHA hashes for supply-chain security.

All action references use mutable tags (@v4, @v2). Pinning to full commit SHAs prevents malicious tag modifications. Example for actions/checkout:

- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

This applies to all 16 action references flagged by static analysis. Tools like Dependabot or Renovate can auto-update pinned hashes.

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 63-65: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 63-63: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 63, Replace all mutable action tag
references (such as `@v4`, `@v2`) with their full commit SHA hashes in the
GitHub Actions workflow file to improve supply-chain security. For each action
reference throughout the workflow, update the tag to use the complete commit SHA
followed by a comment indicating the version (e.g., `# v4.2.2`). This applies to
all 16 action references in the file, including `actions/checkout` and any other
actions used. Verify each SHA corresponds to the correct version tag before
committing.

Source: Linters/SAST tools

with:
fetch-depth: 0
Comment thread
coderabbitai[bot] marked this conversation as resolved.
persist-credentials: false
- name: Compute version
id: compute
run: |
set -e
git fetch --tags --force || true
RELEASE_TAG=$(git tag --sort=-v:refname | head -n 1 | sed 's/^v//' | tr -d '\n')
if [ -z "$RELEASE_TAG" ]; then RELEASE_TAG="0.0.1"; fi
if [ "${RELEASE_BUILD}" != "true" ]; then
BASE_VERSION=$(echo "$RELEASE_TAG" | awk -F. '{$NF = $NF + 1;} 1' OFS=.)
VERSION="${BASE_VERSION}.dev${{ github.run_id }}+$(git rev-parse --short HEAD)"
else
VERSION="${RELEASE_TAG}"
fi
echo -n "$VERSION" > version.txt
echo "Computed VERSION=$VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: version
path: version.txt
retention-days: 1

# ----------------------------------------------------------------------------
# build: five container builds (the GitLab build stage), pushed to ECR with a
# unique per-variant tag; dist/ extracted and uploaded as an artifact.
# ----------------------------------------------------------------------------
build:
needs: version
runs-on: ${{ vars.NIXL_RUNNER_PREFIX || 'prod' }}-nixl-builder-${{ matrix.runner }}-v1
timeout-minutes: 120 # ARM manylinux builds everything from source (~60min); was timing out at the push step
strategy:
fail-fast: false
matrix:
include:
- name: build-nixl
dockerfile: contrib/Dockerfile
base_image: nvcr.io/nvidia/cuda-dl-base
base_image_tag: 25.06-cuda12.9-devel-ubuntu24.04
whl_base: manylinux_2_39
cuda_version: "12.9"
arch: x86_64
runner: amd
# Option B: manylinux jobs build on the public PyPA manylinux_2_28 base
# (Dockerfile.manylinux) and pull CUDA from a public NGC image — no GitLab.
# VERIFY the nvcr.io/nvidia/cuda el8/ubi8 devel tags below actually exist.
- name: build-nixl-manylinux
dockerfile: contrib/Dockerfile.manylinux
base_image: nvcr.io/nvidia/cuda
base_image_tag: 12.9.1-devel-ubi8
whl_base: manylinux_2_28
cuda_version: "12.9"
arch: x86_64
runner: amd
- name: build-nixl-manylinux-cuda13
dockerfile: contrib/Dockerfile.manylinux
base_image: nvcr.io/nvidia/cuda
base_image_tag: 13.0.1-devel-ubi8
whl_base: manylinux_2_28
cuda_version: "13.0"
arch: x86_64
runner: amd
- name: build-nixl-arm-manylinux
dockerfile: contrib/Dockerfile.manylinux
base_image: nvcr.io/nvidia/cuda
base_image_tag: 12.9.1-devel-ubi8
whl_base: manylinux_2_28
cuda_version: "12.9"
arch: aarch64
runner: arm
- name: build-nixl-arm-manylinux-cuda13
dockerfile: contrib/Dockerfile.manylinux
base_image: nvcr.io/nvidia/cuda
base_image_tag: 13.0.1-devel-ubi8
whl_base: manylinux_2_28
cuda_version: "13.0"
arch: aarch64
runner: arm
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Log in to ECR
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push image
run: |
set -e
IMAGE_NAME="${IMAGE_BASE}:${{ matrix.name }}-${{ github.sha }}-${{ github.run_id }}"
echo "IMAGE_NAME=$IMAGE_NAME" >> "$GITHUB_ENV"
chmod +x contrib/build-container.sh
bash contrib/build-container.sh \
--base-image "${{ matrix.base_image }}" \
--base-image-tag "${{ matrix.base_image_tag }}" \
--cuda-version "${{ matrix.cuda_version }}" \
--wheel-base "${{ matrix.whl_base }}" \
--python-versions "${WHL_PYTHON_VERSIONS}" \
--tag "${IMAGE_NAME}" \
--os "ubuntu24" \

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.

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how --os flag is used in build-container.sh
rg -n -A5 '\-\-os\)' contrib/build-container.sh
rg -n 'OS=' contrib/build-container.sh

Repository: ai-dynamo/nixl

Length of output: 300


🏁 Script executed:

#!/bin/bash
# Get context around line 162 in ci.yml
sed -n '150,175p' .github/workflows/ci.yml

# Check the matrix definition and how --os is used
sed -n '88,165p' .github/workflows/ci.yml | grep -n "matrix\|dockerfile\|--os\|ubuntu\|manylinux"

Repository: ai-dynamo/nixl

Length of output: 2839


🏁 Script executed:

#!/bin/bash
# Get the full matrix definition
sed -n '88,130p' .github/workflows/ci.yml

Repository: ai-dynamo/nixl

Length of output: 2026


🏁 Script executed:

#!/bin/bash
# Check how OS is used in build-container.sh
rg -n '\$OS' contrib/build-container.sh
cat -n contrib/build-container.sh | sed -n '235,245p'

Repository: ai-dynamo/nixl

Length of output: 686


🏁 Script executed:

#!/bin/bash
# Check if OS build arg is used in Dockerfile.manylinux
rg -n '\$OS\|ARG OS' contrib/Dockerfile.manylinux
# Check the regular Dockerfile too
rg -n '\$OS\|ARG OS' contrib/Dockerfile

Repository: ai-dynamo/nixl

Length of output: 40


🏁 Script executed:

#!/bin/bash
# Check if OS argument is defined in Dockerfiles
grep -n "ARG OS" contrib/Dockerfile.manylinux contrib/Dockerfile
# Check the full content for OS usage
head -50 contrib/Dockerfile.manylinux | cat -n
head -50 contrib/Dockerfile | cat -n

Repository: ai-dynamo/nixl

Length of output: 5423


🏁 Script executed:

#!/bin/bash
# Check if OS is used in Dockerfile.manylinux at all
grep -n "OS" contrib/Dockerfile.manylinux
# Check what the OS==ubuntu22 check does in build-container.sh
sed -n '166,180p' contrib/build-container.sh

Repository: ai-dynamo/nixl

Length of output: 481


The --os "ubuntu24" parameter is unused in Dockerfile.manylinux and can be omitted for manylinux builds.

The manylinux matrix entries use nvcr.io/nvidia/cuda:*-ubi8 base images, but Dockerfile.manylinux does not declare or use the OS build argument, making --os "ubuntu24" harmless but unnecessary for those builds. The parameter is only meaningful for the primary Ubuntu-based build (contrib/Dockerfile), where it is appropriate. Consider making the parameter conditional on the Dockerfile being used to avoid passing unused arguments.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 162, The `--os "ubuntu24"` parameter at
line 162 in the CI workflow is being passed unconditionally to Docker build
commands, but it is only meaningful when using `contrib/Dockerfile` for the
primary Ubuntu-based build. The `Dockerfile.manylinux` used by manylinux matrix
entries does not declare or use an OS build argument, making this parameter
unused for those builds. Modify the workflow to conditionally include the `--os
"ubuntu24"` parameter only when the build is using `contrib/Dockerfile`, and
omit it for manylinux builds that use `Dockerfile.manylinux`. This can be
achieved by adding a conditional check based on the dockerfile being used or the
build matrix configuration.

--arch "${{ matrix.arch }}" \
--dockerfile "${{ matrix.dockerfile }}"
docker push "$IMAGE_NAME"
- name: Extract build artifacts
run: |
set -e
CN="nixl-extract-${{ github.run_id }}-${{ strategy.job-index }}"
docker rm -f "$CN" || true
docker create --name "$CN" "$IMAGE_NAME"
# Don't mask a build that produced no wheels: fail if dist is absent/empty.
docker cp "$CN:/workspace/nixl/dist" ./dist
docker cp "$CN:/usr/local/nixl" ./nixl_install || true
docker rm -f "$CN" || true
ls dist/*.whl >/dev/null 2>&1 || { echo "ERROR: no wheels in dist/"; exit 1; }
- uses: actions/upload-artifact@v4
with:
name: dist-${{ matrix.name }}
path: dist
retention-days: 1
if-no-files-found: error

# ----------------------------------------------------------------------------
# scan-wheels: GitLab "security scan" stage. Runs only on release builds or
# when security_scan is explicitly requested.
# ----------------------------------------------------------------------------
scan-wheels:
needs: build
if: ${{ github.event.inputs.security_scan == 'true' || github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') }}
runs-on: ${{ vars.NIXL_RUNNER_PREFIX || 'prod' }}-nixl-builder-amd-v1
env:
PACKAGE_LICENSE: "Apache-2.0"
SKIPPED_SECURITY_RULES: "B404,B603,B108"
ALLOWED_NOSEC_COUNT: "0"
IGNORE_FAILED_PIP_INSTALL: "1"
steps:
- name: Download manylinux wheels
uses: actions/download-artifact@v4
with:
name: dist-build-nixl-manylinux
path: dist
Comment on lines +205 to +209

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.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Scan only covers x86 CUDA 12.9 wheels.

The scan downloads only dist-build-nixl-manylinux artifacts. CUDA 13 and ARM wheel variants are not scanned. If this is intentional (same source code, different binary targets), consider adding a comment. Otherwise, consider scanning all variants or at least one per CUDA major version.

🧰 Tools
🪛 zizmor (1.26.1)

[error] 196-196: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 195 - 199, The "Download manylinux
wheels" step only downloads the dist-build-nixl-manylinux artifact, which covers
only x86 CUDA 12.9 wheels. Either add a comment explaining why only this variant
is being scanned if this limitation is intentional, or modify the workflow to
download and scan additional wheel variants by adding more download-artifact
steps or modifying the artifact name pattern to include CUDA 13 and ARM wheel
variants to ensure comprehensive coverage across different CUDA versions and
architectures.

- name: Log in to ECR
uses: aws-actions/amazon-ecr-login@v2
- name: Scan wheels with wheeltamer
run: |
set -e
# wheeltamer is mirrored into ECR (gitlab-master is unreachable from the
# AWS runners). Mirror with: crane copy
# gitlab-master.nvidia.com:5005/dl/pypi/wheel-ci-cd:wheeltamer
# ${NIXL_ECR_IMAGE}:wheeltamer
CN="wheeltamer_${{ github.run_id }}"
docker rm -f "$CN" || true
docker create --name="$CN" \
-e EXPECTED_PKG_LICENSE="${PACKAGE_LICENSE}" \
-e SKIPPED_SECURITY_RULES="${SKIPPED_SECURITY_RULES}" \
-e ALLOWED_NOSEC_COUNT="${ALLOWED_NOSEC_COUNT}" \
-e IGNORE_FAILED_PIP_INSTALL="${IGNORE_FAILED_PIP_INSTALL}" \
--pull=always \
"${{ vars.NIXL_ECR_IMAGE }}:wheeltamer"
docker cp "$PWD/dist/." "$CN:/workspace"
docker start -a "$CN"
- name: Cleanup
if: always()
run: docker rm -f "wheeltamer_${{ github.run_id }}" || true

# ----------------------------------------------------------------------------
# upload: GitLab upload stage. Release-only. Wheels -> Artifactory (JFrog CLI),
# crates -> Artifactory cargo registry (manual approval via environment).
# ----------------------------------------------------------------------------
upload-x86-wheels:
needs: build
if: ${{ github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') }}
Comment on lines +239 to +240

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.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Make wheel/crate publishing depend on the scan job.

At Lines 239/278/319, publish jobs depend only on build, so releases can publish before scan-wheels finishes (or even if it fails).

🛠️ Proposed fix
   upload-x86-wheels:
-    needs: build
+    needs: [build, scan-wheels]
@@
   upload-arm-wheels:
-    needs: build
+    needs: [build, scan-wheels]
@@
   upload-crates:
-    needs: build
+    needs: [build, scan-wheels]

Also applies to: 278-279, 319-320

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 239 - 240, The publish jobs at lines
239, 278, and 319 currently only depend on the build job, allowing them to
publish before the scan-wheels job completes or even if it fails. Update the
needs field in each of these publish job definitions to include both build and
scan-wheels as dependencies, ensuring the scanning completes successfully before
any publishing occurs.

runs-on: ${{ vars.NIXL_RUNNER_PREFIX || 'prod' }}-nixl-builder-amd-v1
timeout-minutes: 30
env:
ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }}
ARTIFACTORY_PYPI_TOKEN: ${{ secrets.ARTIFACTORY_PYPI_TOKEN }}
ARCH: x86_64
steps:
- name: Download x86 wheels
uses: actions/download-artifact@v4
with:
pattern: dist-build-nixl-manylinux*
path: dist
merge-multiple: true
- name: Upload wheels to Artifactory
run: |
set -e
cd dist
ls -la *.whl
WHEEL_VERSION=$(ls nixl*.whl | head -n 1 | cut -d'-' -f2)
CN="upload_nixl_build_${{ github.run_id }}"
docker rm -f "$CN" || true
docker create --name "$CN" -w /workspace -e CI=true -e JFROG_CLI_LOG_LEVEL=INFO \
-e ARTIFACTORY_PYPI_TOKEN -e ARTIFACTORY_URL \
releases-docker.jfrog.io/jfrog/jfrog-cli-v2-jf bash -c "
TARGET_PROPS=\"CI_PIPELINE_ID=${{ github.run_id }};component_name=nixl;os=linux;arch=${ARCH};version=${WHEEL_VERSION}\" &&
jf rt upload '*.whl' 'sw-dynamo-nixl-pypi-local/release/${WHEEL_VERSION}/${{ github.run_id }}/${ARCH}/' \
--target-props=\"\$TARGET_PROPS\" \
--access-token \"\$ARTIFACTORY_PYPI_TOKEN\" --url \"\$ARTIFACTORY_URL\" \
--flat --fail-no-op=true --detailed-summary
"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
docker cp . "$CN:/workspace/"
docker start -a "$CN"
- name: Cleanup
if: always()
run: docker rm -f "upload_nixl_build_${{ github.run_id }}" || true

upload-arm-wheels:
needs: build
if: ${{ github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') }}
# amd runner: the jfrog-cli-v2-jf image is amd64-only. This job only uploads the
# already-built arm wheel files (downloaded as artifacts), so the host arch is irrelevant.
runs-on: ${{ vars.NIXL_RUNNER_PREFIX || 'prod' }}-nixl-builder-amd-v1
timeout-minutes: 30
env:
ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }}
ARTIFACTORY_PYPI_TOKEN: ${{ secrets.ARTIFACTORY_PYPI_TOKEN }}
ARCH: aarch64
steps:
- name: Download arm wheels
uses: actions/download-artifact@v4
with:
pattern: dist-build-nixl-arm-manylinux*
path: dist
merge-multiple: true
- name: Upload wheels to Artifactory
run: |
set -e
cd dist
ls -la *.whl
WHEEL_VERSION=$(ls nixl*.whl | head -n 1 | cut -d'-' -f2)
CN="upload_arm_nixl_build_${{ github.run_id }}"
docker rm -f "$CN" || true
docker create --name "$CN" -w /workspace -e CI=true -e JFROG_CLI_LOG_LEVEL=INFO \
-e ARTIFACTORY_PYPI_TOKEN -e ARTIFACTORY_URL \
releases-docker.jfrog.io/jfrog/jfrog-cli-v2-jf bash -c "
TARGET_PROPS=\"CI_PIPELINE_ID=${{ github.run_id }};component_name=nixl;os=linux;arch=${ARCH};version=${WHEEL_VERSION}\" &&
jf rt upload '*.whl' 'sw-dynamo-nixl-pypi-local/release/${WHEEL_VERSION}/${{ github.run_id }}/${ARCH}/' \
--target-props=\"\$TARGET_PROPS\" \
--access-token \"\$ARTIFACTORY_PYPI_TOKEN\" --url \"\$ARTIFACTORY_URL\" \
--flat --fail-no-op=true --detailed-summary
"
docker cp . "$CN:/workspace/"
docker start -a "$CN"
- name: Cleanup
if: always()
run: docker rm -f "upload_arm_nixl_build_${{ github.run_id }}" || true

upload-crates:
needs: build
# GitLab marked this job `when: manual` on release builds. The `release`
# environment provides the equivalent manual approval gate (configure
# required reviewers under Settings -> Environments -> release).
if: ${{ github.event.inputs.release_build == 'true' || startsWith(github.ref, 'refs/heads/release/') }}
runs-on: ${{ vars.NIXL_RUNNER_PREFIX || 'prod' }}-nixl-builder-amd-v1
environment: release
env:
ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }}
ARTIFACTORY_CARGO_TOKEN: ${{ secrets.ARTIFACTORY_CARGO_TOKEN }}
steps:
- name: Log in to ECR
uses: aws-actions/amazon-ecr-login@v2
- name: Publish crates to Artifactory
run: |
set -e
IMAGE_NAME="${IMAGE_BASE}:build-nixl-${{ github.sha }}-${{ github.run_id }}"
docker run -e ARTIFACTORY_CARGO_TOKEN -e ARTIFACTORY_URL \
-e CI_PIPELINE_ID="${{ github.run_id }}" "$IMAGE_NAME" /bin/bash -c "set -e &&
grep '^version = ' Cargo.toml &&
sed -i -E 's/^(version = \"([^\"]+)\")/version = \"\2-rc.${{ github.run_id }}\"/' Cargo.toml &&
grep '^version = ' Cargo.toml &&
cargo check --manifest-path src/bindings/rust/Cargo.toml &&
cargo publish --manifest-path src/bindings/rust/Cargo.toml \
--token \"Bearer \$ARTIFACTORY_CARGO_TOKEN\" \
--index \"sparse+\$ARTIFACTORY_URL/api/cargo/sw-dynamo-nixl-cargo-local/index/\" \
--no-verify --allow-dirty"
Loading
Loading