Skip to content

ci: gate PRs on Actions and bridge to Blossom - #1

Merged
letientai299 merged 3 commits into
mainfrom
tai/gh-actions
Aug 19, 2026
Merged

ci: gate PRs on Actions and bridge to Blossom#1
letientai299 merged 3 commits into
mainfrom
tai/gh-actions

Conversation

@letientai299

@letientai299 letientai299 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Description

Lint and pull-request hygiene only. GitLab stays the source of truth for
builds, GPU tests and benchmarks, so nothing here compiles the extension,
pulls LFS objects, or asks for a GPU.

Workflow Job Gate
style.yml prek prek run --all-files, the hooks pinned in prek.toml
pr.yml Title PR title is a Conventional Commits subject
pr.yml DCO every commit the PR adds carries a matching Signed-off-by

The prek pin is read out of requirements-dev.txt rather than repeated, so CI
cannot drift from what pip install -e '.[dev]' gives a contributor. The Title
job runs prek run commitizen --stage commit-msg against the title, so
commitizen's version and pattern stay single-sourced too; it strips a leading
[PROJ-123] / [5123456] first, which commitizen would otherwise reject.

A PR title is attacker-controlled, so it reaches the script through the
environment, never through ${{ }} interpolation inside a run: block.

Type of change

  • Build / CI

Checklist

  • My commits are signed off (DCO): git commit -s
  • I have read the Contributing Guidelines
  • For a new feature or breaking change, an issue was filed and approved first
  • I added or updated tests, and they pass locally
  • I updated documentation as needed

@letientai299 letientai299 changed the title ci: add GitHub Actions style and pull-request gates add github actions Aug 19, 2026
@letientai299 letientai299 changed the title add github actions ci: add GitHub Actions style and pull-request gates Aug 19, 2026
@letientai299
letientai299 force-pushed the tai/gh-actions branch 6 times, most recently from 7e71212 to f6f19c3 Compare August 19, 2026 14:32
@letientai299 letientai299 changed the title ci: add GitHub Actions style and pull-request gates ci: gate style, PR hygiene and build on Actions Aug 19, 2026
@letientai299

Copy link
Copy Markdown
Collaborator Author

/build-ci

Lint and pull-request hygiene, the slice of the suite that needs no hardware,
and the wheel — none of which needs a GPU. GitLab stays the source of truth for
the GPU suite and the benchmarks.

- prek runs the hooks prek.toml pins over the whole tree.
- Title lints the PR title, which squash-merge turns into the commit subject.
  That holds only because the repo sets squash_merge_commit_title = PR_TITLE;
  the COMMIT_OR_PR_TITLE default would take a single-commit PR's own subject,
  which nothing but the opt-in commit-msg hook lints.
- DCO checks every commit the PR adds carries a matching sign-off.
- contract runs tests/contract and tests/cubin, which import only the standard
  library and pytest.
- wheel builds the extension and imports it. cpp/CMakeLists.txt declares
  LANGUAGES CXX ASM, so nvcc compiles nothing: the kernels are precompiled
  CUBINs assembled in as .incbin shards, and the only CUDA dependency is
  CUDA::cuda_driver against the toolkit's libcuda stub. Nothing links PyTorch,
  which is why the GitLab job for this already runs on a CPU runner.

The first three plus contract share one always-on trigger, so they live in
ci.yml. The wheel keeps its own file: it is the only one worth starting by
hand, and workflow_dispatch there builds from any branch or tag without a pull
request to open first. Adding dispatch grants nothing new — a pull_request run
already executes the workflow file from the PR head — and it needs actions:
write, so it stays with write collaborators.

Both jobs that need LFS fetch the CUBIN packs by pattern rather than passing
lfs: true, which pulls 88.2 MB where 2.5 MB is read. They are also the two that
keep checkout's credentials, because git lfs pull authenticates with them on an
internal repo; the other three drop the token.

Every pin is read out of the file that declares it, so CI cannot drift from
what `pip install -e '.[dev]'` gives a contributor: prek from
requirements-dev.txt, pytest from the same, Python from pyproject.toml. The
Python floor rather than python-version-file, which resolves ">=3.12,<4.0" to
the newest 3.x the runner has — the published wheel is cp312, and a gate that
compiles a different ABI is not the gate docs/dev.md promises.

The prek hook cache carries restore-keys, so bumping one hook's rev rebuilds
that hook rather than all nine. Title opts out of the cache entirely: it builds
commitizen's environment and nothing else, which costs about what saving it
does, and skipping it removes the per-job cache key the two jobs otherwise
needed to avoid clobbering each other.

Jimver/cuda-toolkit is the only third-party action and is pinned to a commit,
per NVIDIA ProdSec and NVIDIA/warp's own practice. There is no first-party
alternative: the org pattern is to run inside nvcr.io/nvidia/cuda, which ships
neither git-lfs for the packs nor a Python setup-python recognises.

Signed-off-by: Tai Le <taile@nvidia.com>
The GPU suite, the image build and the extension build cannot run on GitHub
runners, so a maintainer asks for them with `/build-ci` and Blossom carries the
request to internal Jenkins. GitHub keeps the trigger, the authorization and
the result; nothing behind the firewall is exposed.

Two gates guard it: the actor must be in `BLOSSOM_AUTHORIZED_USERS`, and
`blossom-ci` re-checks them against Blossom's own database and Duo. The list is
a repository variable rather than a literal in this file, so on- and
offboarding is a settings edit. It is seeded from the `bioir` team but is
deliberately not the team -- approving a run spends GPU hours, which is a
narrower permission than reviewing code.

The chain stays advisory. It only reports once someone asks, so requiring it
would block every pull request until a maintainer typed the command.

Secrets `BLOSSOM_KEY` and `CI_SERVER` and the self-hosted runner are not in
place yet, so the first run of this will queue rather than start.

Signed-off-by: Tai Le <taile@nvidia.com>
Two values in .github/ were still written out by hand while everything around
them is read from where it is declared.

The LFS pack pattern appeared three times. Its source of truth is
.gitattributes, which a contract test pins, so a copy that drifts fails
quietly: the pull matches nothing, the packs stay pointers, and the error
arrives later as "is a Git LFS pointer" rather than as a stale glob. It now
lives in a composite action, next to the prek and python ones.

The wheel job installed a fixed CUDA 13.2.0 while docker/Dockerfile declares
13.0.2 as the runtime. setup.py turns the toolkit's `nvcc --version` into the
wheel's `+cuXYZ` local version segment, so that gap published a wheel labelled
for a CUDA no other build path here produces. Reading RUNTIME_TAG closes it;
the wheel this job builds is now `+cu130`.

Signed-off-by: Tai Le <taile@nvidia.com>
@letientai299 letientai299 changed the title ci: gate style, PR hygiene and build on Actions ci: gate PRs on Actions and bridge to Blossom Aug 19, 2026
@letientai299
letientai299 marked this pull request as ready for review August 19, 2026 16:56
@letientai299
letientai299 requested a review from a team as a code owner August 19, 2026 16:56
@letientai299
letientai299 merged commit 182e2bc into main Aug 19, 2026
9 of 10 checks passed
@letientai299
letientai299 deleted the tai/gh-actions branch August 28, 2026 21:54
@NVIDIA-BioNeMo NVIDIA-BioNeMo locked as resolved and limited conversation to collaborators Sep 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant