Skip to content
Closed
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
36 changes: 36 additions & 0 deletions .github/actions/setup-cuda-container/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
---
name: Set up the CUDA devel container
description: >-
Installs the host packages the nvidia/cuda devel image lacks, marks the
workspace safe for git, and installs rustup. The caller checks the
repository out first: a local action is resolved from the workspace, so
this action cannot be the job's first step. The image already contains
the CUDA toolkit. Later steps pick up rust-toolchain.toml from their
working directory.

runs:
using: composite
steps:
- name: Install host packages
shell: bash
run: |
apt-get update -qq
apt-get install -y -qq --no-install-recommends \
build-essential ca-certificates curl git pkg-config libclang-dev wget

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems like every place this is called installs ca-certificates and git beforehand anyway due to this being in the repo that needs to be checked out. Same with the mark as a safe git repository (maybe I missed some). I think that the duplication should be removed from here as you state it cannot be called until after the checkotu.


- name: Mark the workspace as a safe git directory
shell: bash
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

- name: Install Rust
shell: bash
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --no-modify-path --profile minimal --default-toolchain none
echo "${HOME}/.cargo/bin" >> "${GITHUB_PATH}"
# Root rust-toolchain.toml is the stable pin. cuda-oxide/ selects the
# nightly when a later step sets that working directory.
"${HOME}/.cargo/bin/rustup" show
(cd cuda-oxide && "${HOME}/.cargo/bin/rustup" show)
33 changes: 13 additions & 20 deletions .github/workflows/book.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
name: Deploy CUDA Rust Docs

# Path-filtered lane: only documentation sources can change what this builds.
# Self-hosted runners reject pull_request. copy-pr-bot mirrors trusted PRs to
# pull-request/<n>, and the build job triggers on that push. `deploy` stays on
# main: a mirror push is a push event, so an event-name check would publish it.
on:
push:
branches: [main]
paths:
- 'cuda-oxide/cuda-oxide-book/**'
- 'cutile-rs/cutile-book/**'
- 'cutile-rs/scripts/build_versioned_book.sh'
- 'docs/**'
- '.github/workflows/book.yml'
# Validate the book on PRs too. The build job alone runs there; `deploy` is
# gated below, so a pull request never publishes. Without this the book was
# only ever built after merge, so a PR that broke it could not be caught by
# review or by CI.
pull_request:
branches: [main]
branches:
- main
- "pull-request/[0-9]+"
paths:
- 'cuda-oxide/cuda-oxide-book/**'
- 'cutile-rs/cutile-book/**'
Expand All @@ -39,11 +32,11 @@ permissions:
# a slower older commit deploy after a newer one and replace the published site.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
build:
runs-on: ubuntu-latest
runs-on: linux-amd64-cpu4
# An umbrella page plus two Sphinx books. Bound the job so a
# wedged install or a sphinx that never returns fails instead of burning to
# the 6-hour default.
Expand Down Expand Up @@ -76,17 +69,17 @@ jobs:
run: |
# Unset CUTILE_DOCS_TAGS → build every tag matching the pattern.
# Empty CUTILE_DOCS_TAGS → current tree only (fast PR check).
if [ "${{ github.event_name }}" = "pull_request" ]; then
export CUTILE_DOCS_TAGS=""
fi
case "${{ github.ref }}" in
refs/heads/pull-request/*) export CUTILE_DOCS_TAGS="" ;;
esac
bash docs/build_all_docs.sh

# Only `deploy` consumes this, and `deploy` is skipped on pull requests,
# so uploading it there produces an artifact nothing can ever read. A PR's
# job is to prove both Sphinx builds succeed, which the steps above already
# did; gate the upload on the same condition `deploy` uses so the two
# cannot drift apart.
- if: github.event_name != 'pull_request'
- if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v3
with:
path: docs/build/html
Expand All @@ -96,7 +89,7 @@ jobs:
# Publishing is for main only. A pull request builds the book to prove it
# is sound and stops there; it never touches the Pages environment or
# holds the deployment permissions below.
if: github.event_name != 'pull_request'
if: github.ref == 'refs/heads/main'
permissions:
pages: write
id-token: write
Expand Down
37 changes: 31 additions & 6 deletions .github/workflows/cargo-deny.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: cargo-deny

# Runs as a job of the top-level CI workflow (.github/workflows/ci.yml) on
# push/pull_request, plus a standalone weekly security scan via schedule.
# Runs as a job of the top-level CI workflow (.github/workflows/ci.yml),
# plus a standalone weekly security scan via schedule.
# Concurrency for the CI path is governed by CI's own group.
#
# Four parts of the same concern. `check` enforces the license *policy* over
Expand Down Expand Up @@ -30,14 +30,24 @@ on:
permissions:
contents: read

# A container job's default shell is dash; use bash, as on ubuntu-latest.
defaults:
run:
shell: bash

jobs:
check:
runs-on: ubuntu-latest
runs-on: linux-amd64-cpu4
container:
image: rust:1.98.0-bookworm
timeout-minutes: 10
steps:
- name: Clone repository
uses: actions/checkout@v4

- name: Mark the workspace as a safe git directory
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

- name: Install cargo-deny
run: cargo install cargo-deny --locked

Expand Down Expand Up @@ -94,25 +104,35 @@ jobs:

license-manifest:
name: dependency-licenses.csv covers every declared crate
runs-on: ubuntu-latest
runs-on: linux-amd64-cpu4
container:
image: rust:1.98.0-bookworm
timeout-minutes: 10
steps:
- name: Clone repository
uses: actions/checkout@v4

- name: Mark the workspace as a safe git directory
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

# Only reads manifests: `cargo metadata` resolves the graph without
# running build scripts, so this needs no CUDA toolkit and no LLVM.
- name: Verify the license inventory covers the workspace
run: bash cuda-oxide/scripts/check-dependency-licenses.sh

example-policy:
name: deny.toml governs the example workspaces
runs-on: ubuntu-latest
runs-on: linux-amd64-cpu4
container:
image: rust:1.98.0-bookworm
timeout-minutes: 15
steps:
- name: Clone repository
uses: actions/checkout@v4

- name: Mark the workspace as a safe git directory
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

- name: Install cargo-deny
run: cargo install cargo-deny --locked

Expand All @@ -125,12 +145,17 @@ jobs:

source-headers:
name: every source file carries the SPDX header
runs-on: ubuntu-latest
runs-on: linux-amd64-cpu4
container:
image: rust:1.98.0-bookworm
timeout-minutes: 5
steps:
- name: Clone repository
uses: actions/checkout@v4

- name: Mark the workspace as a safe git directory
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

# Pure text check over tracked files: no toolchain, no network. The OSRB
# review fixed 32 missing headers in #812 and the next two scripts to
# land (#819, #835) drifted again; this makes the third time the last.
Expand Down
10 changes: 4 additions & 6 deletions .github/workflows/ci-status.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ name: CI status

# One status for the whole repository, so the README needs one badge.
#
# Badges are per workflow file, and the two pipelines have to stay separate
# for now: ci.yml (SIMT and the shared host crates) runs on GitHub-hosted
# runners on push and pull_request; cutile-rs.yml (Tile) runs on NVIDIA
# self-hosted runners, which cannot run on pull_request events, so it
# triggers on push to main and to the copy-pr-bot mirror branches.
# Badges are per workflow file. ci.yml and cutile-rs.yml both run on NVIDIA
# self-hosted runners, which reject pull_request, so both trigger on push to
# main and to the copy-pr-bot mirror branches.
#
# This workflow runs whenever either of them completes on main. For each
# pipeline it finds the newest completed push run on main that actually
Expand All @@ -34,7 +32,7 @@ permissions:
jobs:
status:
name: combined CI status on main
runs-on: ubuntu-latest
runs-on: linux-amd64-cpu4
timeout-minutes: 5
steps:
- name: Report the newest executed main run of each pipeline
Expand Down
19 changes: 7 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,15 @@ name: CI
# Path-filtered SIMT lane: skip when a change cannot affect cuda-oxide or the
# shared host crates. `cuda-oxide/**` is deliberately broad (prose as well as
# code) because guard scripts cross-check the book against the crates.
#
# Self-hosted runners reject pull_request. copy-pr-bot mirrors trusted PRs to
# pull-request/<n>, and this workflow triggers on that push
# (config: .github/copy-pr-bot.yaml).
on:
push:
branches: [main]
paths:
- 'cuda-oxide/**'
- 'cuda-bindings/**'
- 'cuda-core/**'
- 'cuda-core-derive/**'
- 'cuda-async/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/**'
pull_request:
branches: [main]
branches:
- main
- "pull-request/[0-9]+"
paths:
- 'cuda-oxide/**'
- 'cuda-bindings/**'
Expand Down
43 changes: 26 additions & 17 deletions .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
---
name: clippy

# Runs as a job of the top-level CI workflow (.github/workflows/ci.yml),
# which is the single push/pull_request entry point. Concurrency is governed
# by CI's own group, so this workflow declares none of its own.
# Runs as a job of the top-level CI workflow (.github/workflows/ci.yml).
# Concurrency is governed by CI's own group, so this workflow declares none
# of its own.
on:
workflow_call:

permissions:
contents: read

# A container job's default shell is dash. The example loop uses bash
# process substitution.
defaults:
run:
shell: bash

jobs:
clippy:
runs-on: ubuntu-latest
runs-on: linux-amd64-cpu4
# CUDA 13.1.1, the toolkit pin these jobs already used. The devel image
# carries nvcc, cudart, and libcurand. rustup is installed in the
# container; the image itself has no Rust.
container:
image: nvidia/cuda:13.1.1-devel-ubuntu24.04
env:
DEBIAN_FRONTEND: noninteractive
env:
CUDA_TOOLKIT_PATH: /usr/local/cuda
timeout-minutes: 30
steps:
# A local action is loaded from the workspace, so checkout comes first.
# The CUDA image has no git; without it checkout stores a tarball.
- name: Install git
run: |
apt-get update -qq
apt-get install -y -qq --no-install-recommends ca-certificates git
- name: Clone repository
uses: actions/checkout@v4

- name: Install CUDA toolkit
uses: Jimver/cuda-toolkit@v0.2.35
id: cuda-toolkit
with:
cuda: "13.1.1"
method: network
sub-packages: '["nvcc", "cudart-dev"]'
non-cuda-sub-packages: '["libcurand-dev"]'
- uses: ./.github/actions/setup-cuda-container

# `--all-targets` covers tests, benches and examples, matching the two
# steps below and the `just clippy` recipe. Without it a lint that fires
# only in a test target passes here and fails for anyone running the
# recipe locally.
- name: Run clippy (workspace crates)
env:
CUDA_TOOLKIT_PATH: ${{ steps.cuda-toolkit.outputs.CUDA_PATH }}
working-directory: cuda-oxide
run: cargo clippy --workspace --all-targets -- -D warnings

Expand All @@ -55,14 +66,12 @@ jobs:
# well-defined `target/` under cuda-oxide.
- name: Run clippy (rustc-codegen-cuda)
env:
CUDA_TOOLKIT_PATH: ${{ steps.cuda-toolkit.outputs.CUDA_PATH }}
CARGO_TARGET_DIR: ${{ runner.temp }}/clippy-shared-target
working-directory: cuda-oxide/crates/rustc-codegen-cuda
run: cargo clippy --all-targets -- -D warnings

- name: Run clippy (rustc-codegen-cuda examples)
env:
CUDA_TOOLKIT_PATH: ${{ steps.cuda-toolkit.outputs.CUDA_PATH }}
CARGO_TARGET_DIR: ${{ runner.temp }}/clippy-shared-target
run: |
set -e
Expand Down
Loading
Loading