Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a0aa0a8
ci(rest): add prepare-build-info workflow (#1756)
lachen-nv May 19, 2026
82ebaf7
ci(rest): add lint-and-test workflow (#1756)
lachen-nv May 19, 2026
3a9542e
ci(rest): add build-binaries workflow (#1756)
lachen-nv May 19, 2026
2d276b5
ci(rest): add build-push-service workflow (#1756)
lachen-nv May 19, 2026
7a6cb96
ci(rest): add build-push-docker workflow (#1756)
lachen-nv May 19, 2026
a61cc64
ci(rest): add helm-workflows with push disabled (#1756)
lachen-nv May 19, 2026
9bd977a
ci(rest): add rest-ci entry workflow with build-only mock (#1756)
lachen-nv May 19, 2026
03e662a
ci(rest): trigger on push to pull-request/* branches (#1756)
lachen-nv May 19, 2026
8050ab9
ci(rest): fix protobuf cd path (workflow-schema/flow not rest-api/flo…
lachen-nv May 19, 2026
2e80712
ci(rest): use core repo's NVCR_USERNAME/NVCR_TOKEN secrets (#1756)
lachen-nv May 19, 2026
9438c7f
ci(rest): prefix dockerfile paths with rest-api/ for buildx (#1756)
lachen-nv May 20, 2026
b767a05
chore: add root VERSION file (1.5.0); prepare-build-info reads root f…
lachen-nv May 20, 2026
294fdad
ci(core): add changes gate to skip core CI on rest-only PRs (#1756)
lachen-nv May 20, 2026
3a74b98
ci(rest): extend triggers to main/release/tags + add changes gate (#1…
lachen-nv May 20, 2026
f1eb47d
ci: track primary_tag in build-push-service; simplify promotion helm_…
lachen-nv May 20, 2026
c8470aa
revert: drop root VERSION file, use git describe for versioning (#1756)
lachen-nv May 20, 2026
ede0dcf
ci(rest): switch test to make rest-api/test-<module>; skip 3 untestab…
lachen-nv May 20, 2026
2c1e90b
ci(rest): restore CI=false + DB env vars so tests use localhost postg…
lachen-nv May 20, 2026
590d19e
ci: add per-workflow aggregators + dorny base:main + symmetric escape…
lachen-nv May 20, 2026
4136d64
test(phase2.3): mixed path-trigger smoke marker (#1756)
lachen-nv May 21, 2026
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
98 changes: 90 additions & 8 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ on:
- release/*
- "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]*"

Expand All @@ -35,11 +36,58 @@ env:


jobs:
changes:
runs-on: ubuntu-latest
outputs:
run_core_ci: ${{ steps.gate.outputs.run_core_ci }}
non_rest_changed: ${{ steps.non-rest-changes.outputs.non_rest }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Detect non-rest changes
id: non-rest-changes
if: startsWith(github.ref, 'refs/heads/pull-request/')
uses: dorny/paths-filter@v3
with:
base: main
predicate-quantifier: every
filters: |
non_rest:
- '**'
- '!rest-api/**'
- '!.github/workflows/rest-*.yml'

- name: Decide whether Core CI should run
id: gate
env:
REF: ${{ github.ref }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message || '' }}
NON_REST_CHANGED: ${{ steps.non-rest-changes.outputs.non_rest }}
run: |
run_core_ci=true

if [[ "${REF}" =~ ^refs/heads/pull-request/[0-9]+$ ]]; then
run_core_ci="${NON_REST_CHANGED}"
fi

if [[ "${COMMIT_MESSAGE}" =~ ci-run-complete-pipeline ]]; then
run_core_ci=true
fi

echo "run_core_ci=${run_core_ci}" >> "$GITHUB_OUTPUT"
echo "Core CI gate: ${run_core_ci}"

# ============================================================================
# PREPARE STAGE
# ============================================================================

prepare:
needs:
- changes
if: ${{ needs.changes.outputs.run_core_ci == 'true' }}
runs-on: linux-amd64-cpu4
outputs:
version: ${{ steps.version.outputs.version }}
Expand Down Expand Up @@ -106,14 +154,11 @@ jobs:

set -euo pipefail

# Fetch tags for accurate git describe
git fetch --tags --force
# Get short SHA
SHORT_SHA=$(git rev-parse --short=7 HEAD)
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "Using Git describe to extract version as VERSION and HELM_VERSION"
VERSION=$(git describe --tags --first-parent --always --long)
# HELM_VERSION strips leading 'v' for strict SemVer and replaces the last '-' with '.'
HELM_VERSION_BASE="${VERSION#v}"
HELM_VERSION=$(echo "$HELM_VERSION_BASE" | sed 's/\(.*\)-/\1./')

Expand Down Expand Up @@ -440,7 +485,7 @@ jobs:
# BUILD STAGE - Release Container
# ============================================================================
build-release-container-x86_64:
if: ${{ always() && github.event_name != 'schedule' }}
if: ${{ always() && github.event_name != 'schedule' && needs.prepare.result == 'success' }}
needs:
- prepare
- build-container-x86_64
Expand All @@ -461,7 +506,7 @@ jobs:
secrets: inherit

build-release-container-aarch64:
if: ${{ always() && github.event_name != 'schedule' }}
if: ${{ always() && github.event_name != 'schedule' && needs.prepare.result == 'success' }}
needs:
- prepare
- build-container-aarch64
Expand All @@ -488,7 +533,7 @@ jobs:
needs:
- prepare
- build-artifacts-container-x86_64
if: ${{ always() && github.event_name != 'schedule' }}
if: ${{ always() && github.event_name != 'schedule' && needs.prepare.result == 'success' }}
uses: ./.github/workflows/docker-build.yml
with:
dockerfile_path: dev/docker/Dockerfile.release-forge-cli
Expand All @@ -505,7 +550,7 @@ jobs:
needs:
- prepare
- build-artifacts-container-aarch64
if: ${{ always() && github.event_name != 'schedule' }}
if: ${{ always() && github.event_name != 'schedule' && needs.prepare.result == 'success' }}
uses: ./.github/workflows/docker-build.yml
with:
dockerfile_path: dev/docker/Dockerfile.release-forge-cli
Expand Down Expand Up @@ -1230,8 +1275,9 @@ jobs:

build-summary:
runs-on: linux-amd64-cpu4
if: ${{ always() && github.event_name != 'schedule' }}
if: ${{ always() && github.event_name != 'schedule' && needs.prepare.result == 'success' }}
needs:
- prepare
- build-container-x86_64
- build-container-aarch64
- build-runtime-container-x86_64
Expand Down Expand Up @@ -1383,3 +1429,39 @@ jobs:
notify-on-failure: true
secrets:
slack-bot-token: ${{ secrets.CDS_SLACK_BOT_OAUTH_TOKEN }}

# ============================================================================
# AGGREGATOR — single required check for branch protection
# ============================================================================
# Fails iff any leaf job's result is `failure` or `cancelled`.
# `skipped` counts as pass — that's how rest-only PRs unblock when the
# `changes` gate intentionally skips the core pipeline.
# Scope: 1:1 with the existing ruleset's required checks. Wrapping them in
# a single context lets us require ONE name in branch protection and avoid
# the "Expected — Waiting for status" failure mode if any of those jobs is
# ever renamed or workflow-level-filtered away.
carbide-ci-pass:
name: carbide-ci-pass
runs-on: ubuntu-latest
if: always()
needs:
- build-release-container-x86_64
- build-release-container-aarch64
- security-secret-scan
- lint-police
steps:
- name: Decide pass/fail
env:
NEEDS_JSON: ${{ toJson(needs) }}
run: |
set -euo pipefail
echo "$NEEDS_JSON" | jq -r 'to_entries[] | "\(.key): \(.value.result)"'
if echo "$NEEDS_JSON" | jq -e '
to_entries
| map(select(.value.result == "failure" or .value.result == "cancelled"))
| length > 0
' >/dev/null; then
echo "::error::One or more required jobs failed or were cancelled"
exit 1
fi
echo "All required jobs OK (success or skipped)"
2 changes: 1 addition & 1 deletion .github/workflows/promotion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ on:
workflow_dispatch:
inputs:
version:
description: 'Version to promote (e.g., v0.1.0-rc2-0-g85ed21555)'
description: 'Version to promote (e.g., 1.5.0-85ed215)'
required: true
type: string

Expand Down
92 changes: 92 additions & 0 deletions .github/workflows/rest-build-binaries.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

name: Build Go Binaries

on:
workflow_dispatch:
workflow_call:
inputs:
runner:
description: 'Runner type for the build job'
required: false
default: 'ubuntu-latest'
type: string
upload_artifact:
description: 'Whether to upload artifacts'
required: false
default: false
type: boolean

defaults:
run:
working-directory: rest-api

env:
GO_VERSION: "1.25.4"

jobs:
build-binaries:
name: Build Binaries (${{ matrix.name }}, ${{ matrix.path }})
runs-on: ${{ inputs.runner }}
strategy:
fail-fast: false
matrix:
include:
- name: api
path: ./api/cmd/api
- name: migrations
path: ./db/cmd/migrations
- name: sitemgr
path: ./site-manager/cmd/sitemgr
- name: workflow
path: ./workflow/cmd/workflow
- name: site-agent
path: ./site-agent/cmd/site-agent
- name: mock-core
path: ./site-agent/cmd/mock-core
- name: mock-flow
path: ./site-agent/cmd/mock-flow
- name: credsmgr
path: ./cert-manager/cmd/credsmgr
- name: flow
path: ./flow
- name: psm
path: ./powershelf-manager
- name: nsm
path: ./nvswitch-manager

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
cache-dependency-path: rest-api/go.sum

- name: Download dependencies
run: go mod download

- name: Build ${{ matrix.name }} (linux/amd64)
run: |
mkdir -p dist
GOOS=linux GOARCH=amd64 go build -o dist/${{ matrix.name }}-linux-amd64 ${{ matrix.path }}

- name: Build ${{ matrix.name }} (linux/arm64)
run: |
GOOS=linux GOARCH=arm64 go build -o dist/${{ matrix.name }}-linux-arm64 ${{ matrix.path }}

- name: Build ${{ matrix.name }} (darwin/arm64)
run: |
GOOS=darwin GOARCH=arm64 go build -o dist/${{ matrix.name }}-darwin-arm64 ${{ matrix.path }}

- name: Upload ${{ matrix.name }} binaries
if: inputs.upload_artifact == true
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}-binaries
path: rest-api/dist/${{ matrix.name }}-*
retention-days: 7
Loading
Loading