Skip to content

docs: pull our documentation and comment guidance into STYLE_GUIDE.md #7131

docs: pull our documentation and comment guidance into STYLE_GUIDE.md

docs: pull our documentation and comment guidance into STYLE_GUIDE.md #7131

Workflow file for this run

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
name: NICo REST CI
on:
workflow_dispatch:
push:
branches:
- main
- 'pull-request/[0-9]+'
tags:
- "v[0-9]*.[0-9]*.[0-9]*"
- "v[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]*"
- "v[0-9].[0-9].[0-9]-rc[0-9]*"
concurrency:
group: ${{ github.event_name == 'push' && github.run_attempt == '1' && startsWith(github.ref, 'refs/heads/pull-request/') && format('rest-pr-{0}', github.ref_name) || format('rest-run-{0}-{1}', github.run_id, github.run_attempt) }}
cancel-in-progress: ${{ github.event_name == 'push' && github.run_attempt == '1' && startsWith(github.ref, 'refs/heads/pull-request/') }}
jobs:
changes:
name: Detect REST CI Gate
runs-on: ubuntu-latest
outputs:
run_rest_ci: ${{ steps.gate.outputs.run_rest_ci }}
rest_api_changed: ${{ steps.filter.outputs.rest_api }}
core_proto_changed: ${{ steps.filter.outputs.core_proto }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
- name: Check REST CI final-gate inventory
run: python3 -B .github/ci/check_ci_gate.py inventory --policy rest .github/workflows/rest-ci.yml
- name: Check REST CI concurrency policy
run: bash scripts/check-ci-concurrency.sh rest
- name: Detect rest-api changes
id: filter
if: startsWith(github.ref, 'refs/heads/pull-request/')
uses: dorny/paths-filter@v3
with:
base: main
filters: |
rest_api:
- 'rest-api/**'
- '.github/ci/rest-command-*'
- '.github/ci/rest_command_bundle.py'
- '.github/ci/test_rest_command_bundle.py'
- '.github/workflows/rest-*.yml'
- 'helm/rest/**'
core_proto:
- 'crates/rpc/proto/**'
- name: Decide whether REST CI should run
id: gate
env:
REF: ${{ github.ref }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message || '' }}
REST_API_CHANGED: ${{ steps.filter.outputs.rest_api }}
CORE_PROTO_CHANGED: ${{ steps.filter.outputs.core_proto }}
run: |
run_rest_ci=true
if [[ "${REF}" =~ ^refs/heads/pull-request/[0-9]+$ ]]; then
run_rest_ci=false
if [[ "${REST_API_CHANGED:-false}" == "true" || "${CORE_PROTO_CHANGED:-false}" == "true" ]]; then
run_rest_ci=true
fi
fi
if [[ "${COMMIT_MESSAGE}" =~ ci-run-complete-pipeline ]]; then
run_rest_ci=true
fi
echo "run_rest_ci=${run_rest_ci}" >> "$GITHUB_OUTPUT"
echo "REST CI gate: ${run_rest_ci}"
prepare:
name: Prepare Build Info
needs:
- changes
if: ${{ needs.changes.outputs.run_rest_ci == 'true' }}
uses: ./.github/workflows/rest-prepare-build-info.yml
with:
# GitHub-hosted: the job is a checkout and a `git describe`, but on the
# self-hosted pool it waited 91 seconds for a runner to do 24 seconds of
# work — and everything downstream waits on it. `changes` above already
# does a full-depth checkout of this repo on a hosted runner in ten
# seconds.
runner: ubuntu-latest
lint-and-test:
name: Lint and Test
needs: prepare
uses: ./.github/workflows/rest-lint-and-test.yml
# Not gated on lint-and-test: this job publishes nothing, it only uploads
# GitHub artifacts with a 7-day retention, so a test gate protects nothing.
# Gating it also made it the tail of the run — it started only once the
# slowest test finished and then ran for another four minutes.
build-binaries:
name: Build Go Binaries
needs:
- prepare
with:
upload_artifact: true
binary_version: ${{ needs.prepare.outputs.binary_version }}
build_timestamp: ${{ needs.prepare.outputs.build_timestamp }}
short_sha: ${{ needs.prepare.outputs.short_sha }}
full_sha: ${{ needs.prepare.outputs.full_sha }}
uses: ./.github/workflows/rest-build-binaries.yml
security-secret-scan:
name: REST Secret Scan with TruffleHog
needs: prepare
runs-on: linux-amd64-cpu4
timeout-minutes: 30
permissions:
actions: read
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
- name: Compute TruffleHog scan range
id: scan-range
if: startsWith(github.ref, 'refs/heads/pull-request/') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
env:
GH_TOKEN: ${{ github.token }}
run: bash .github/ci/resolve-secret-scan-range.sh >> "$GITHUB_OUTPUT"
- name: Run TruffleHog Scan
uses: dsx-ai-factory/dsx-github-actions/.github/actions/trufflehog-scan@f435aa6bf125fe6f9e5ac438f8cef75f90e29a2b
with:
base: ${{ steps.scan-range.outputs.base }}
head: ${{ steps.scan-range.outputs.head }}
extra-args: '--results=verified,unknown --only-verified'
post-pr-comment: 'true'
fail-on-findings: 'true'
# Push refs (main, tags, dispatch). Stays behind lint-and-test so a red test
# run cannot publish an image or move `latest`.
#
# Keep in sync with `build-and-push-pr` below, which is the same call for
# pull requests. The two exist because `needs` is unconditional — a job waits
# for every entry regardless of `if` — so a dependency that applies only to
# push refs has to be expressed as two mutually exclusive jobs.
build-and-push:
name: Build and Push Docker Images
if: ${{ !startsWith(github.ref, 'refs/heads/pull-request/') }}
needs:
- prepare
- lint-and-test
permissions:
contents: read
packages: write
security-events: write
uses: ./.github/workflows/rest-build-push-docker.yml
with:
runner: linux-amd64-cpu4
semantic_version: ${{ needs.prepare.outputs.semantic_version }}
short_sha: ${{ needs.prepare.outputs.short_sha }}
branch_sha_tag: ${{ needs.prepare.outputs.branch_sha_tag }}
target_registry: ${{ needs.prepare.outputs.target_registry }}
ngc_path: ${{ needs.prepare.outputs.target_ngc_path }}
branch_name: ${{ needs.prepare.outputs.branch_name }}
is_main_branch: ${{ needs.prepare.outputs.is_main_branch }}
push_enabled: ${{ github.event_name != 'workflow_dispatch' && !contains(github.ref, 'pull-request/') }}
release_tag: ${{ needs.prepare.outputs.release_tag }}
helm_version: ${{ needs.prepare.outputs.helm_version }}
secrets:
NVCR_USERNAME: ${{ secrets.NVCR_USERNAME }}
NVCR_TOKEN: ${{ secrets.NVCR_TOKEN }}
NICO_TARGET_REGISTRY_USERNAME: ${{ secrets.NICO_TARGET_REGISTRY_USERNAME }}
NICO_TARGET_REGISTRY_TOKEN: ${{ secrets.NICO_TARGET_REGISTRY_TOKEN }}
NICO_NGC_TOKEN: ${{ secrets.NICO_NGC_TOKEN }}
# Pull requests. Same build as `build-and-push` above — keep the two in sync —
# but it starts as soon as `prepare` is done instead of waiting for the tests.
# The images take about as long to build as the slowest test takes to run, so
# gating them was costing roughly six minutes of wall clock for a build whose
# result is discarded either way: a pull request never pushes.
#
# No secrets are passed. Every step that consumes them (registry login, the
# image push, the NGC resource uploads, and the whole `merge` job) is already
# gated on `push_enabled`, which is hard-coded false here.
#
# The write scopes below go unused for the same reason, but they cannot be
# dropped: the nested `build` job in rest-build-push-service.yml declares
# `packages` and `security-events` itself, and a called workflow requesting
# more than its caller grants fails validation before the run starts. The
# `permissions` key takes no expressions, so the callee cannot ask for less
# when `push_enabled` is false either.
build-and-push-pr:
name: Build Docker Images
if: ${{ startsWith(github.ref, 'refs/heads/pull-request/') }}
needs:
- prepare
permissions:
contents: read
packages: write
security-events: write
uses: ./.github/workflows/rest-build-push-docker.yml
with:
runner: linux-amd64-cpu4
semantic_version: ${{ needs.prepare.outputs.semantic_version }}
short_sha: ${{ needs.prepare.outputs.short_sha }}
branch_sha_tag: ${{ needs.prepare.outputs.branch_sha_tag }}
target_registry: ${{ needs.prepare.outputs.target_registry }}
ngc_path: ${{ needs.prepare.outputs.target_ngc_path }}
branch_name: ${{ needs.prepare.outputs.branch_name }}
is_main_branch: ${{ needs.prepare.outputs.is_main_branch }}
push_enabled: false
release_tag: ${{ needs.prepare.outputs.release_tag }}
helm_version: ${{ needs.prepare.outputs.helm_version }}
helm:
name: Helm Charts
needs:
- prepare
if: ${{ !cancelled() && needs.prepare.result == 'success' }}
uses: ./.github/workflows/rest-helm-workflows.yml
with:
ngc_path: ${{ needs.prepare.outputs.target_ngc_path }}
app_version: ${{ needs.prepare.outputs.semantic_version }}
chart_version: ${{ needs.prepare.outputs.helm_version }}
secrets:
NVCR_STG_TOKEN: ${{ secrets.NVCR_TOKEN }}
NICO_NGC_TOKEN: ${{ secrets.NICO_NGC_TOKEN }}
# ============================================================================
# AGGREGATOR — single required check for branch protection
# ============================================================================
# Passes only when every required job reports `success` or `skipped`.
# `skipped` counts as pass — that's how core-only PRs unblock when the
# `changes` gate intentionally skips the REST pipeline, and it is also what
# lets `build-and-push` and `build-and-push-pr` both sit in needs when
# exactly one of the two ever runs.
# Any other result, plus missing or malformed data, fails closed.
# Every job that can determine REST CI health is listed so an upstream
# failure cannot be hidden when its downstream jobs become `skipped`.
# The checker in `changes` rejects every job that is neither gated nor
# exempted and protects `if: always()` so a failed dependency cannot skip
# this required check.
rest-ci-pass:
name: rest-ci-pass
runs-on: ubuntu-latest
if: always()
needs:
- changes
- prepare
- lint-and-test
- build-binaries
- security-secret-scan
- build-and-push
- build-and-push-pr
- helm
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Decide pass/fail
env:
NEEDS_JSON: ${{ toJson(needs) }}
run: python3 -B .github/ci/check_ci_gate.py results