feat: derive bluefield service versions from build-time git describe #2787
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # | |
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # | |
| name: Carbide CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - release/* | |
| - "pull-request/[0-9]+" | |
| tags: | |
| - "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]*" | |
| env: | |
| # Build configuration | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_HOME: ${{ github.workspace }}/cargo | |
| FF_USE_FASTZIP: "true" | |
| GIT_SUBMODULE_STRATEGY: recursive | |
| jobs: | |
| # ============================================================================ | |
| # PREPARE STAGE | |
| # ============================================================================ | |
| prepare: | |
| runs-on: linux-amd64-cpu4 | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| helm_version: ${{ steps.version.outputs.helm_version }} | |
| short_sha: ${{ steps.version.outputs.short_sha }} | |
| extras_container_ref: ${{ steps.resolve-extras.outputs.extras_container_ref }} | |
| build_container_x86_64_run: ${{ steps.base-container-gate.outputs.build_container_x86_64_run }} | |
| build_container_x86_64_version: ${{ steps.base-container-gate.outputs.build_container_x86_64_version }} | |
| runtime_container_x86_64_run: ${{ steps.base-container-gate.outputs.runtime_container_x86_64_run }} | |
| runtime_container_x86_64_version: ${{ steps.base-container-gate.outputs.runtime_container_x86_64_version }} | |
| build_container_aarch64_run: ${{ steps.base-container-gate.outputs.build_container_aarch64_run }} | |
| build_container_aarch64_version: ${{ steps.base-container-gate.outputs.build_container_aarch64_version }} | |
| build_artifacts_container_x86_64_run: ${{ steps.base-container-gate.outputs.build_artifacts_container_x86_64_run }} | |
| build_artifacts_container_x86_64_version: ${{ steps.base-container-gate.outputs.build_artifacts_container_x86_64_version }} | |
| build_artifacts_container_aarch64_run: ${{ steps.base-container-gate.outputs.build_artifacts_container_aarch64_run }} | |
| build_artifacts_container_aarch64_version: ${{ steps.base-container-gate.outputs.build_artifacts_container_aarch64_version }} | |
| runtime_container_aarch64_run: ${{ steps.base-container-gate.outputs.runtime_container_aarch64_run }} | |
| runtime_container_aarch64_version: ${{ steps.base-container-gate.outputs.runtime_container_aarch64_version }} | |
| powerdns_container_run: ${{ steps.base-container-gate.outputs.powerdns_container_run }} | |
| proto_files_changed: ${{ steps.base-container-gate.outputs.proto_files_changed }} | |
| source_files_changed: ${{ steps.base-container-gate.outputs.source_files_changed }} | |
| release_build_args: ${{ steps.release-metadata.outputs.build_args }} | |
| release_build_args_aarch64: ${{ steps.release-metadata.outputs.build_args_aarch64 }} | |
| sbom_container_run: ${{ steps.base-container-gate.outputs.sbom_container_run }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Detect build-container-x86_64 changes | |
| id: build-container-changes | |
| uses: dorny/paths-filter@v3 | |
| with: | |
| filters: | | |
| build_container: | |
| - 'dev/docker/Dockerfile.build-container-x86_64' | |
| runtime_container: | |
| - 'dev/docker/Dockerfile.runtime-container-x86_64' | |
| runtime_container_aarch64: | |
| - 'dev/docker/Dockerfile.runtime-container-aarch64' | |
| build_container_aarch64: | |
| - 'dev/docker/Dockerfile.build-container-aarch64' | |
| build_artifacts_x86_64: | |
| - 'dev/docker/Dockerfile.build-artifacts-container-x86_64' | |
| build_artifacts_aarch64: | |
| - 'dev/docker/Dockerfile.build-artifacts-container-aarch64' | |
| powerdns_container: | |
| - 'dev/docker/Dockerfile-powerdns' | |
| proto_files: | |
| - '**/*.proto' | |
| source_files: | |
| - 'crates/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'Makefile.toml' | |
| - 'rust-toolchain.toml' | |
| sbom_container: | |
| - 'dev/docker/sbom-tools/Dockerfile' | |
| - name: Calculate version | |
| id: version | |
| run: | | |
| 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./') | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "helm_version=${HELM_VERSION}" >> $GITHUB_OUTPUT | |
| echo "Calculated VERSION: ${VERSION}" | |
| echo "Calculated HELM_VERSION: ${HELM_VERSION}" | |
| # Output to GitHub Summary | |
| echo "## 📦 Build Version" >> $GITHUB_STEP_SUMMARY | |
| echo "| Variable | Value |" >> $GITHUB_STEP_SUMMARY | |
| echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| VERSION | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY | |
| echo "| HELM_VERSION | \`${HELM_VERSION}\` |" >> $GITHUB_STEP_SUMMARY | |
| - name: Login to NVCR | |
| uses: ./.github/actions/docker-auth | |
| with: | |
| username: ${{ secrets.NVCR_USERNAME }} | |
| token: ${{ secrets.NVCR_TOKEN }} | |
| - name: Resolve pinned carbide-extras image digest | |
| id: resolve-extras | |
| env: | |
| EXTRAS_IMAGE: nvcr.io/0837451325059433/carbide-dev/nvmetal-carbide-extras:latest | |
| run: | | |
| set -euo pipefail | |
| docker pull "${EXTRAS_IMAGE}" | |
| EXTRAS_REF="$(docker inspect --format='{{index .RepoDigests 0}}' "${EXTRAS_IMAGE}")" | |
| if [ -z "${EXTRAS_REF}" ]; then | |
| echo "::error::Failed to resolve digest for ${EXTRAS_IMAGE}" | |
| exit 1 | |
| fi | |
| echo "extras_container_ref=${EXTRAS_REF}" >> "$GITHUB_OUTPUT" | |
| echo "Resolved extras image to pinned digest: ${EXTRAS_REF}" | |
| echo "## 📌 Carbide Extras Image" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Requested | Pinned |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "|-----------|--------|" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| \`${EXTRAS_IMAGE}\` | \`${EXTRAS_REF}\` |" >> "$GITHUB_STEP_SUMMARY" | |
| - name: Decide if build-container-x86_64 must run | |
| id: base-container-gate | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| COMMIT_MESSAGE: ${{ github.event.head_commit.message || '' }} | |
| VERSION: ${{ steps.version.outputs.version }} | |
| BUILD_CONTAINER_X86_64_DOCKERFILE_CHANGED: ${{ steps.build-container-changes.outputs.build_container }} | |
| RUNTIME_CONTAINER_X86_64_DOCKERFILE_CHANGED: ${{ steps.build-container-changes.outputs.runtime_container }} | |
| RUNTIME_CONTAINER_AARCH64_DOCKERFILE_CHANGED: ${{ steps.build-container-changes.outputs.runtime_container_aarch64 }} | |
| BUILD_CONTAINER_AARCH64_DOCKERFILE_CHANGED: ${{ steps.build-container-changes.outputs.build_container_aarch64 }} | |
| BUILD_ARTIFACTS_X86_64_DOCKERFILE_CHANGED: ${{ steps.build-container-changes.outputs.build_artifacts_x86_64 }} | |
| BUILD_ARTIFACTS_AARCH64_DOCKERFILE_CHANGED: ${{ steps.build-container-changes.outputs.build_artifacts_aarch64 }} | |
| POWERDNS_DOCKERFILE_CHANGED: ${{ steps.build-container-changes.outputs.powerdns_container }} | |
| PROTO_FILES_CHANGED: ${{ steps.build-container-changes.outputs.proto_files }} | |
| SOURCE_FILES_CHANGED: ${{ steps.build-container-changes.outputs.source_files }} | |
| run: | | |
| build_container_x86_64_run=false | |
| runtime_container_x86_64_run=false | |
| build_container_aarch64_run=false | |
| runtime_container_aarch64_run=false | |
| build_artifacts_container_x86_64_run=false | |
| build_artifacts_container_aarch64_run=false | |
| powerdns_container_run=false | |
| proto_files_changed=false | |
| source_files_changed=false | |
| if [[ "${COMMIT_MESSAGE}" =~ ci-rebuild-base-containers ]]; then | |
| build_container_x86_64_run=true | |
| runtime_container_x86_64_run=true | |
| build_container_aarch64_run=true | |
| runtime_container_aarch64_run=true | |
| build_artifacts_container_x86_64_run=true | |
| build_artifacts_container_aarch64_run=true | |
| elif [[ "${BUILD_CONTAINER_X86_64_DOCKERFILE_CHANGED}" == "true" ]]; then | |
| build_container_x86_64_run=true | |
| fi | |
| if [[ "${COMMIT_MESSAGE}" =~ ci-rebuild-sbom-tools ]]; then | |
| sbom_container_run=true | |
| fi | |
| if [[ "${COMMIT_MESSAGE}" =~ ci-rebuild-powerdns ]] || [[ "${POWERDNS_DOCKERFILE_CHANGED}" == "true" ]]; then | |
| powerdns_container_run=true | |
| fi | |
| if [[ "${PROTO_FILES_CHANGED}" == "true" ]]; then | |
| proto_files_changed=true | |
| fi | |
| if [[ "${SOURCE_FILES_CHANGED}" == "true" ]]; then | |
| source_files_changed=true | |
| fi | |
| if [[ "${RUNTIME_CONTAINER_X86_64_DOCKERFILE_CHANGED}" == "true" ]]; then | |
| runtime_container_x86_64_run=true | |
| fi | |
| if [[ "${RUNTIME_CONTAINER_AARCH64_DOCKERFILE_CHANGED}" == "true" ]]; then | |
| runtime_container_aarch64_run=true | |
| fi | |
| if [[ "${BUILD_CONTAINER_AARCH64_DOCKERFILE_CHANGED}" == "true" ]]; then | |
| build_container_aarch64_run=true | |
| fi | |
| if [[ "${BUILD_ARTIFACTS_X86_64_DOCKERFILE_CHANGED}" == "true" ]]; then | |
| build_artifacts_container_x86_64_run=true | |
| fi | |
| if [[ "${BUILD_ARTIFACTS_AARCH64_DOCKERFILE_CHANGED}" == "true" ]]; then | |
| build_artifacts_container_aarch64_run=true | |
| fi | |
| if [[ "${SBOM_CONTAINER_DOCKERFILE_CHANGED}" == "true" ]]; then | |
| sbom_container_run=true | |
| fi | |
| echo "build_container_x86_64_run=${build_container_x86_64_run}" >> "$GITHUB_OUTPUT" | |
| echo "runtime_container_x86_64_run=${runtime_container_x86_64_run}" >> "$GITHUB_OUTPUT" | |
| echo "build_container_aarch64_run=${build_container_aarch64_run}" >> "$GITHUB_OUTPUT" | |
| echo "runtime_container_aarch64_run=${runtime_container_aarch64_run}" >> "$GITHUB_OUTPUT" | |
| echo "build_artifacts_container_x86_64_run=${build_artifacts_container_x86_64_run}" >> "$GITHUB_OUTPUT" | |
| echo "build_artifacts_container_aarch64_run=${build_artifacts_container_aarch64_run}" >> "$GITHUB_OUTPUT" | |
| echo "powerdns_container_run=${powerdns_container_run}" >> "$GITHUB_OUTPUT" | |
| echo "proto_files_changed=${proto_files_changed}" >> "$GITHUB_OUTPUT" | |
| echo "source_files_changed=${source_files_changed}" >> "$GITHUB_OUTPUT" | |
| echo "sbom_container_run=${sbom_container_run}" >> "$GITHUB_OUTPUT" | |
| if [[ "$build_container_x86_64_run" == "true" ]]; then | |
| echo "build_container_x86_64_version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "build_container_x86_64_version=latest" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [[ "$runtime_container_x86_64_run" == "true" ]]; then | |
| echo "runtime_container_x86_64_version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "runtime_container_x86_64_version=latest" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [[ "$build_container_aarch64_run" == "true" ]]; then | |
| echo "build_container_aarch64_version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "build_container_aarch64_version=latest" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [[ "$runtime_container_aarch64_run" == "true" ]]; then | |
| echo "runtime_container_aarch64_version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "runtime_container_aarch64_version=latest" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [[ "$build_artifacts_container_x86_64_run" == "true" ]]; then | |
| echo "build_artifacts_container_x86_64_version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "build_artifacts_container_x86_64_version=latest" >> "$GITHUB_OUTPUT" | |
| fi | |
| if [[ "$build_artifacts_container_aarch64_run" == "true" ]]; then | |
| echo "build_artifacts_container_aarch64_version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "build_artifacts_container_aarch64_version=latest" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Decide release container publish strategy | |
| id: release-gate | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| REF: ${{ github.ref }} | |
| COMMIT_MESSAGE: ${{ github.event.head_commit.message || '' }} | |
| run: | | |
| PUBLISH=false | |
| if [[ "${EVENT_NAME}" == "pull_request" ]] || [[ "${REF}" =~ pull-request/[0-9]+ ]] ; then | |
| PUBLISH=false | |
| elif [[ "${REF}" == "refs/heads/main" ]] || [[ "${REF}" =~ ^refs/heads/release/ ]] || [[ "${REF}" =~ ^refs/tags/ ]] || [[ "${COMMIT_MESSAGE}" =~ ci-run-complete-pipeline ]]; then | |
| PUBLISH=true | |
| fi | |
| echo "publish_built_container=${PUBLISH}" >> "$GITHUB_OUTPUT" | |
| - name: Prepare release container build args | |
| id: release-metadata | |
| env: | |
| VERSION: ${{ steps.version.outputs.version }} | |
| SHORT_SHA: ${{ steps.version.outputs.short_sha }} | |
| BUILD_VERSION: ${{ steps.base-container-gate.outputs.build_container_x86_64_version }} | |
| RUNTIME_VERSION: ${{ steps.base-container-gate.outputs.runtime_container_x86_64_version }} | |
| BUILD_VERSION_AARCH64: ${{ steps.base-container-gate.outputs.build_container_aarch64_version }} | |
| RUNTIME_VERSION_AARCH64: ${{ steps.base-container-gate.outputs.runtime_container_aarch64_version }} | |
| run: | | |
| set -euo pipefail | |
| # x86_64 build args | |
| BUILD_REF="nvcr.io/0837451325059433/carbide-dev/build-container-x86_64:${BUILD_VERSION}" | |
| RUNTIME_REF="nvcr.io/0837451325059433/carbide-dev/runtime-container-x86_64:${RUNTIME_VERSION}" | |
| BUILD_ARGS=$(jq -n -c \ | |
| --arg VERSION "$VERSION" \ | |
| --arg SHORT_SHA "$SHORT_SHA" \ | |
| --arg BUILD "$BUILD_REF" \ | |
| --arg RUNTIME "$RUNTIME_REF" \ | |
| '{VERSION: $VERSION, CI_COMMIT_SHORT_SHA: $SHORT_SHA, CONTAINER_BUILD_X86_64: $BUILD, CONTAINER_RUNTIME_X86_64: $RUNTIME}') | |
| echo "build_args=${BUILD_ARGS}" >> "$GITHUB_OUTPUT" | |
| # aarch64 build args | |
| BUILD_REF_AARCH64="nvcr.io/0837451325059433/carbide-dev/build-container-aarch64:${BUILD_VERSION_AARCH64}" | |
| RUNTIME_REF_AARCH64="nvcr.io/0837451325059433/carbide-dev/runtime-container-aarch64:${RUNTIME_VERSION_AARCH64}" | |
| BUILD_ARGS_AARCH64=$(jq -n -c \ | |
| --arg VERSION "$VERSION" \ | |
| --arg SHORT_SHA "$SHORT_SHA" \ | |
| --arg BUILD "$BUILD_REF_AARCH64" \ | |
| --arg RUNTIME "$RUNTIME_REF_AARCH64" \ | |
| '{VERSION: $VERSION, CI_COMMIT_SHORT_SHA: $SHORT_SHA, CONTAINER_BUILD_AARCH64: $BUILD, CONTAINER_RUNTIME_AARCH64: $RUNTIME}') | |
| echo "build_args_aarch64=${BUILD_ARGS_AARCH64}" >> "$GITHUB_OUTPUT" | |
| # ============================================================================ | |
| # BUILD STAGE - Base Containers | |
| # ============================================================================ | |
| build-container-x86_64: | |
| if: needs.prepare.outputs.build_container_x86_64_run == 'true' | |
| needs: | |
| - prepare | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.build-container-x86_64 | |
| image_name: nvcr.io/0837451325059433/carbide-dev/build-container-x86_64 | |
| image_tag: ${{ needs.prepare.outputs.build_container_x86_64_version }} | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: true | |
| load: true | |
| tag_latest: ${{ github.ref == 'refs/heads/main' }} | |
| secrets: inherit | |
| build-container-aarch64: | |
| if: needs.prepare.outputs.build_container_aarch64_run == 'true' | |
| needs: | |
| - prepare | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.build-container-aarch64 | |
| image_name: nvcr.io/0837451325059433/carbide-dev/build-container-aarch64 | |
| image_tag: ${{ needs.prepare.outputs.build_container_aarch64_version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: true | |
| load: false | |
| tag_latest: ${{ github.ref == 'refs/heads/main' }} | |
| secrets: inherit | |
| build-runtime-container-x86_64: | |
| if: needs.prepare.outputs.runtime_container_x86_64_run == 'true' | |
| needs: | |
| - prepare | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.runtime-container-x86_64 | |
| image_name: nvcr.io/0837451325059433/carbide-dev/runtime-container-x86_64 | |
| image_tag: ${{ needs.prepare.outputs.runtime_container_x86_64_version }} | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: true | |
| load: true | |
| tag_latest: ${{ github.ref == 'refs/heads/main' }} | |
| secrets: inherit | |
| build-runtime-container-aarch64: | |
| if: needs.prepare.outputs.runtime_container_aarch64_run == 'true' | |
| needs: | |
| - prepare | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.runtime-container-aarch64 | |
| image_name: nvcr.io/0837451325059433/carbide-dev/runtime-container-aarch64 | |
| image_tag: ${{ needs.prepare.outputs.runtime_container_aarch64_version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: true | |
| load: false | |
| tag_latest: ${{ github.ref == 'refs/heads/main' }} | |
| secrets: inherit | |
| build-artifacts-container-x86_64: | |
| if: needs.prepare.outputs.build_artifacts_container_x86_64_run == 'true' | |
| needs: | |
| - prepare | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.build-artifacts-container-x86_64 | |
| image_name: nvcr.io/0837451325059433/carbide-dev/build-artifacts-container-x86_64 | |
| image_tag: ${{ needs.prepare.outputs.build_artifacts_container_x86_64_version }} | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: true | |
| load: true | |
| tag_latest: ${{ github.ref == 'refs/heads/main' }} | |
| secrets: inherit | |
| build-artifacts-container-aarch64: | |
| if: needs.prepare.outputs.build_artifacts_container_aarch64_run == 'true' | |
| needs: | |
| - prepare | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.build-artifacts-container-aarch64 | |
| image_name: nvcr.io/0837451325059433/carbide-dev/build-artifacts-container-aarch64 | |
| image_tag: ${{ needs.prepare.outputs.build_artifacts_container_aarch64_version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: true | |
| load: false | |
| tag_latest: ${{ github.ref == 'refs/heads/main' }} | |
| secrets: inherit | |
| # ============================================================================ | |
| # BUILD STAGE - Release Container | |
| # ============================================================================ | |
| build-release-container-x86_64: | |
| if: ${{ always() && github.event_name != 'schedule' }} | |
| needs: | |
| - prepare | |
| - build-container-x86_64 | |
| - build-runtime-container-x86_64 | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.release-container-x86_64 | |
| context_path: . | |
| build_args: ${{ needs.prepare.outputs.release_build_args }} | |
| image_name: nvcr.io/0837451325059433/carbide-dev/nvmetal-carbide | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu16 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: true | |
| tag_latest: false | |
| timeout_minutes: 120 | |
| secrets: inherit | |
| build-release-container-aarch64: | |
| if: ${{ always() && github.event_name != 'schedule' }} | |
| needs: | |
| - prepare | |
| - build-container-aarch64 | |
| - build-runtime-container-aarch64 | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.release-container-aarch64 | |
| context_path: . | |
| build_args: ${{ needs.prepare.outputs.release_build_args_aarch64 }} | |
| image_name: nvcr.io/0837451325059433/carbide-dev/nvmetal-carbide-aarch64 | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu16 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| tag_latest: false | |
| secrets: inherit | |
| # ============================================================================ | |
| # BUILD STAGE - Forge CLI (Multi-arch) | |
| # ============================================================================ | |
| build-forge-cli-x86_64: | |
| needs: | |
| - prepare | |
| - build-artifacts-container-x86_64 | |
| if: ${{ always() && github.event_name != 'schedule' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.release-forge-cli | |
| image_name: nvcr.io/0837451325059433/carbide-dev/forge-admin-cli-x86_64 | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| build_args: '{"CI_COMMIT_SHORT_SHA":"${{ needs.prepare.outputs.short_sha }}","CONTAINER_BUILD":"nvcr.io/0837451325059433/carbide-dev/build-artifacts-container-x86_64:${{ needs.prepare.outputs.build_artifacts_container_x86_64_version }}"}' | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: true | |
| secrets: inherit | |
| build-forge-cli-aarch64: | |
| needs: | |
| - prepare | |
| - build-artifacts-container-aarch64 | |
| if: ${{ always() && github.event_name != 'schedule' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.release-forge-cli | |
| image_name: nvcr.io/0837451325059433/carbide-dev/forge-admin-cli-aarch64 | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| build_args: '{"CI_COMMIT_SHORT_SHA":"${{ needs.prepare.outputs.short_sha }}","CONTAINER_BUILD":"nvcr.io/0837451325059433/carbide-dev/build-artifacts-container-aarch64:${{ needs.prepare.outputs.build_artifacts_container_aarch64_version }}"}' | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: true | |
| secrets: inherit | |
| merge-manifests-forge-cli: | |
| needs: | |
| - prepare | |
| - build-forge-cli-x86_64 | |
| - build-forge-cli-aarch64 | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && !contains(github.ref, 'pull-request/') && needs.build-forge-cli-x86_64.result == 'success' && needs.build-forge-cli-aarch64.result == 'success' }} | |
| runs-on: linux-amd64-cpu4 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to NVCR | |
| uses: ./.github/actions/docker-auth | |
| with: | |
| username: ${{ secrets.NVCR_USERNAME }} | |
| token: ${{ secrets.NVCR_TOKEN }} | |
| - name: Create and push multi-arch manifest | |
| uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 | |
| with: | |
| max_attempts: 3 | |
| timeout_minutes: 10 | |
| retry_wait_seconds: 20 | |
| command: | | |
| docker buildx imagetools create -t \ | |
| nvcr.io/0837451325059433/carbide-dev/forge-admin-cli:${{ needs.prepare.outputs.version }} \ | |
| nvcr.io/0837451325059433/carbide-dev/forge-admin-cli-x86_64:${{ needs.prepare.outputs.version }} \ | |
| nvcr.io/0837451325059433/carbide-dev/forge-admin-cli-aarch64:${{ needs.prepare.outputs.version }} | |
| docker buildx imagetools create -t \ | |
| nvcr.io/0837451325059433/carbide-dev/forge-admin-cli:latest \ | |
| nvcr.io/0837451325059433/carbide-dev/forge-admin-cli-x86_64:${{ needs.prepare.outputs.version }} \ | |
| nvcr.io/0837451325059433/carbide-dev/forge-admin-cli-aarch64:${{ needs.prepare.outputs.version }} | |
| # ============================================================================ | |
| # BUILD STAGE - Boot Artifacts | |
| # ============================================================================ | |
| build-boot-artifacts-x86: | |
| needs: | |
| - prepare | |
| - build-artifacts-container-x86_64 | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && contains('success,skipped', needs.build-artifacts-container-x86_64.result) }} | |
| uses: ./.github/workflows/build-boot-artifacts.yml | |
| with: | |
| arch: x86_64 | |
| build_type: boot | |
| cargo_make_task: build-boot-artifacts-x86-host-ci | |
| build_container: nvcr.io/0837451325059433/carbide-dev/build-artifacts-container-x86_64:${{ needs.prepare.outputs.build_artifacts_container_x86_64_version }} | |
| runner: linux-amd64-cpu4 | |
| version: ${{ needs.prepare.outputs.version }} | |
| use_container: true | |
| inject_extras: true | |
| extras_container: ${{ needs.prepare.outputs.extras_container_ref }} | |
| secrets: inherit | |
| build-boot-artifacts-bfb: | |
| needs: | |
| - prepare | |
| - build-artifacts-container-aarch64 | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && contains('success,skipped', needs.build-artifacts-container-aarch64.result) }} | |
| uses: ./.github/workflows/build-boot-artifacts.yml | |
| with: | |
| arch: aarch64 | |
| build_type: boot | |
| cargo_make_task: build-boot-artifacts-bfb-ci | |
| build_container: nvcr.io/0837451325059433/carbide-dev/build-artifacts-container-aarch64:${{ needs.prepare.outputs.build_artifacts_container_aarch64_version }} | |
| runner: linux-arm64-cpu8 | |
| version: ${{ needs.prepare.outputs.version }} | |
| use_container: true | |
| inject_extras: true | |
| extras_container: ${{ needs.prepare.outputs.extras_container_ref }} | |
| secrets: inherit | |
| # ============================================================================ | |
| # BUILD STAGE - Ephemeral Images | |
| # ============================================================================ | |
| # These builds create bootable ephemeral images (scout.efi, qcow-imager.efi) | |
| # using mkosi. They run on standard Ubuntu runners with mkosi installed. | |
| build-boot-artifacts-ephemeral-image-x86-host: | |
| needs: | |
| - prepare | |
| - build-boot-artifacts-x86 | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-boot-artifacts-x86.result == 'success' }} | |
| uses: ./.github/workflows/build-boot-artifacts.yml | |
| with: | |
| arch: x86_64 | |
| build_type: ephemeral | |
| cargo_make_task: create-ephemeral-image-x86-host-ci | |
| version: ${{ needs.prepare.outputs.version }} | |
| runner: linux-amd64-cpu8 | |
| use_container: false | |
| sa_enablement: true | |
| inject_extras: true | |
| extras_container: ${{ needs.prepare.outputs.extras_container_ref }} | |
| secrets: inherit | |
| build-boot-artifacts-ephemeral-image-arm-host: | |
| needs: | |
| - prepare | |
| - build-boot-artifacts-bfb | |
| # Run only if boot artifacts succeeded (we need those artifacts); skip if cancelled | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-boot-artifacts-bfb.result == 'success' }} | |
| uses: ./.github/workflows/build-boot-artifacts.yml | |
| with: | |
| arch: aarch64 | |
| build_type: ephemeral | |
| cargo_make_task: create-ephemeral-image-arm-host-ci | |
| version: ${{ needs.prepare.outputs.version }} | |
| runner: linux-arm64-cpu8 | |
| use_container: false | |
| sa_enablement: true | |
| inject_extras: true | |
| extras_container: ${{ needs.prepare.outputs.extras_container_ref }} | |
| secrets: inherit | |
| # ============================================================================ | |
| # BUILD STAGE - Release Artifacts | |
| # ============================================================================ | |
| build-release-artifacts-x86-host: | |
| needs: | |
| - prepare | |
| - build-boot-artifacts-x86 | |
| - build-boot-artifacts-ephemeral-image-x86-host | |
| # Run only if both boot and ephemeral jobs succeeded (we need those artifacts); skip if failed/cancelled | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-boot-artifacts-x86.result == 'success' && needs.build-boot-artifacts-ephemeral-image-x86-host.result == 'success' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.release-artifacts-x86_64 | |
| image_name: nvcr.io/0837451325059433/carbide-dev/boot-artifacts-x86_64 | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: true | |
| download_artifacts: true # Download boot and ephemeral artifacts for packaging | |
| build_args: | | |
| { | |
| "VERSION": "${{ needs.prepare.outputs.version }}", | |
| "CI_COMMIT_SHORT_SHA": "${{ needs.prepare.outputs.short_sha }}", | |
| "CONTAINER_RUNTIME_X86_64": "alpine:latest" | |
| } | |
| secrets: inherit | |
| build-release-artifacts-arm-host: | |
| needs: | |
| - prepare | |
| - build-boot-artifacts-bfb | |
| - build-boot-artifacts-ephemeral-image-arm-host | |
| # Run only if both boot and ephemeral jobs succeeded (we need those artifacts); skip if failed/cancelled | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-boot-artifacts-bfb.result == 'success' && needs.build-boot-artifacts-ephemeral-image-arm-host.result == 'success' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.release-artifacts-aarch64 | |
| image_name: nvcr.io/0837451325059433/carbide-dev/boot-artifacts-aarch64 | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/amd64 # Note: aarch64 artifacts packaged in x86_64 image | |
| runner: linux-amd64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: true | |
| download_artifacts: true # Download boot and ephemeral artifacts for packaging | |
| build_args: | | |
| { | |
| "VERSION": "${{ needs.prepare.outputs.version }}", | |
| "CI_COMMIT_SHORT_SHA": "${{ needs.prepare.outputs.short_sha }}", | |
| "CONTAINER_RUNTIME_AARCH64": "alpine:latest" | |
| } | |
| secrets: inherit | |
| # ============================================================================ | |
| # BUILD STAGE - Publish Documentation | |
| # ============================================================================ | |
| build-publish-documentation: | |
| if: false | |
| needs: | |
| - prepare | |
| - build-container-x86_64 | |
| uses: ./.github/workflows/docs.yml | |
| with: | |
| build_container: ${{ format('nvcr.io/0837451325059433/carbide-dev/build-container-x86_64:{0}', (needs['build-container-x86_64'].result == 'success' && needs.prepare.outputs.version) || 'latest') }} | |
| runner: linux-amd64-cpu4 | |
| secrets: inherit | |
| # ============================================================================ | |
| # SECURITY STAGE | |
| # ============================================================================ | |
| security-secret-scan: | |
| name: 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: | |
| fetch-depth: 0 # Full history for secret scanning | |
| - name: Run TruffleHog Scan | |
| uses: NVIDIA/dsx-github-actions/.github/actions/trufflehog-scan@9a9ce3a7770a8b53d2726afa920be3276bc3ddd7 | |
| with: | |
| extra-args: '--results=verified,unknown --only-verified' | |
| post-pr-comment: 'true' | |
| fail-on-findings: 'true' | |
| security-codeql-scan: | |
| name: CodeQL Security Analysis | |
| needs: prepare | |
| runs-on: linux-amd64-cpu4 | |
| timeout-minutes: 360 | |
| permissions: | |
| actions: read | |
| contents: read | |
| security-events: write | |
| packages: read | |
| pull-requests: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Run CodeQL Scan | |
| uses: NVIDIA/dsx-github-actions/.github/actions/codeql-scan@20dc10dda4fa9f8f0380a47cd9a7800d3da3dcf3 | |
| with: | |
| languages: 'rust' | |
| build-mode: 'none' | |
| category: '/language:rust' | |
| upload-sarif: 'false' # Disable upload until GHAS is enabled, such as the repo be public | |
| post-pr-comment: 'false' | |
| fail-on-findings: 'true' # Enforce quality gate | |
| fail-on-severity: 'error' # Only fail on critical/high severity issues | |
| # ============================================================================ | |
| # BUILD STAGE - Machine Validation | |
| # ============================================================================ | |
| build-release-machine-validation-runner: | |
| needs: | |
| - prepare | |
| - build-runtime-container-x86_64 | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && contains('success,skipped', needs.build-runtime-container-x86_64.result) }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.machine-validation-runner | |
| image_name: nvcr.io/0837451325059433/carbide-dev/machine-validation-runner | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| build_args: '{"CI_COMMIT_SHORT_SHA":"${{ needs.prepare.outputs.short_sha }}","CONTAINER_RUNTIME_X86_64":"nvcr.io/0837451325059433/carbide-dev/runtime-container-x86_64:${{ needs.prepare.outputs.runtime_container_x86_64_version }}"}' | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| secrets: inherit | |
| build-release-machine-validation-artifacts-x86-host: | |
| needs: | |
| - prepare | |
| - build-release-machine-validation-runner | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-release-machine-validation-runner.result == 'success' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile.machine-validation-config | |
| image_name: nvcr.io/0837451325059433/carbide-dev/machine_validation | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| build_args: '{"CI_COMMIT_SHORT_SHA":"${{ needs.prepare.outputs.short_sha }}","CONTAINER_RUNTIME_X86_64":"nvcr.io/0837451325059433/carbide-dev/runtime-container-x86_64:${{ needs.prepare.outputs.runtime_container_x86_64_version }}"}' | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| secrets: inherit | |
| # ============================================================================ | |
| # BUILD STAGE - PowerDNS | |
| # ============================================================================ | |
| build-powerdns-container: | |
| needs: | |
| - prepare | |
| if: needs.prepare.outputs.powerdns_container_run == 'true' | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/Dockerfile-powerdns | |
| image_name: nvcr.io/0837451325059433/carbide-dev/powerdns | |
| image_tag: "4.9.3" | |
| build_args: '{"CI_COMMIT_SHORT_SHA":"${{ needs.prepare.outputs.short_sha }}"}' | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| secrets: inherit | |
| proto-police: | |
| needs: | |
| - prepare | |
| if: ${{ needs.prepare.outputs.proto_files_changed == 'true' && contains(github.ref, 'pull-request/') }} | |
| runs-on: linux-amd64-cpu4 | |
| container: | |
| image: yoheimuta/protolint | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Protolint | |
| run: protolint lint -config_path=.protolint.yaml crates/rpc/proto/ | |
| lint-police: | |
| needs: | |
| - prepare | |
| - build-container-x86_64 | |
| if: ${{ !failure() && !cancelled() && needs.prepare.outputs.source_files_changed == 'true' && contains(github.ref, 'pull-request/') }} | |
| runs-on: linux-amd64-cpu16 | |
| container: | |
| image: nvcr.io/0837451325059433/carbide-dev/build-container-x86_64:${{ needs.prepare.outputs.build_container_x86_64_version }} | |
| credentials: | |
| username: ${{ secrets.NVCR_USERNAME }} | |
| password: ${{ secrets.NVCR_TOKEN }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| # PostgreSQL is required because sqlx proc macros (sqlx::query!) connect to | |
| # a local database at compile time to validate SQL queries and return types. | |
| - name: Start PostgreSQL | |
| run: | | |
| /etc/init.d/postgresql start | |
| sudo -u postgres psql -c "ALTER USER root WITH SUPERUSER;" | |
| createdb root | |
| - name: Run clippy | |
| env: | |
| DATABASE_URL: "postgresql://%2Fvar%2Frun%2Fpostgresql" | |
| run: cargo make --no-workspace clippy-flow | |
| - name: Run carbide lints | |
| run: cargo make carbide-lints | |
| - name: Check TOML formatting | |
| run: taplo fmt --check || echo "Please format toml files" | |
| - name: Check Rust formatting | |
| run: cargo make --no-workspace check-format-nightly | |
| - name: Check workspace deps | |
| run: cargo xtask check-workspace-deps | |
| - name: Check licenses | |
| run: cargo make --no-workspace check-licenses | |
| - name: Check bans | |
| run: cargo make --no-workspace check-bans | |
| # ============================================================================ | |
| # BUILD STAGE - Helm Chart | |
| # ============================================================================ | |
| build-validate-helm-chart: | |
| needs: | |
| - prepare | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' }} | |
| runs-on: linux-amd64-cpu4 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Validate Helm chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-validate@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: helm | |
| lint: 'true' | |
| template: 'true' | |
| build-push-helm-chart: | |
| needs: | |
| - prepare | |
| - build-validate-helm-chart | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-validate-helm-chart.result == 'success' && !contains(github.ref, 'pull-request/') }} | |
| runs-on: linux-amd64-cpu4 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Package and push Helm chart to NGC | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-package-push@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: helm | |
| chart-version: ${{ needs.prepare.outputs.helm_version }} | |
| app-version: ${{ needs.prepare.outputs.version }} | |
| lint: 'false' | |
| ngc-key: ${{ secrets.NVCR_TOKEN }} | |
| ngc-path: 0837451325059433/carbide-dev | |
| ngc-duplicate: fail | |
| # ============================================================================ | |
| # BUILD STAGE - Bluefield Images | |
| # ============================================================================ | |
| build-bluefield-binaries: | |
| needs: | |
| - prepare | |
| - build-artifacts-container-aarch64 | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && contains('success,skipped', needs.build-artifacts-container-aarch64.result) }} | |
| runs-on: linux-arm64-cpu8 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Login to NVCR | |
| uses: ./.github/actions/docker-auth | |
| with: | |
| username: ${{ secrets.NVCR_USERNAME }} | |
| token: ${{ secrets.NVCR_TOKEN }} | |
| - name: Pull build container | |
| run: docker pull nvcr.io/0837451325059433/carbide-dev/build-artifacts-container-aarch64:${{ needs.prepare.outputs.build_artifacts_container_aarch64_version }} | |
| - name: Compile bluefield Rust binaries | |
| run: | | |
| docker run --rm \ | |
| -v "${{ github.workspace }}:/workspace" \ | |
| -w /workspace \ | |
| -e CARGO_HOME=/workspace/cargo \ | |
| -e CARGO_INCREMENTAL=0 \ | |
| -e CARGO_BUILD_TARGET=aarch64-unknown-linux-gnu \ | |
| nvcr.io/0837451325059433/carbide-dev/build-artifacts-container-aarch64:${{ needs.prepare.outputs.build_artifacts_container_aarch64_version }} \ | |
| bash -c "git config --global --add safe.directory /workspace && \ | |
| cargo make --cwd bluefield build-dpu-agent-and-dhcp-server-ci && \ | |
| cargo make --cwd bluefield build-fmds-ci && \ | |
| cargo make --cwd bluefield build-dpu-otel-agent-ci" | |
| - name: Stage bluefield binaries for upload | |
| run: | | |
| mkdir -p bluefield-binaries-dir/target/aarch64-unknown-linux-gnu/release | |
| cp target/aarch64-unknown-linux-gnu/release/{forge-dpu-agent,forge-dhcp-server,forge-dpu-otel-agent,carbide-fmds} \ | |
| bluefield-binaries-dir/target/aarch64-unknown-linux-gnu/release/ | |
| - name: Upload bluefield binaries | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bluefield-binaries-${{ github.run_id }} | |
| path: bluefield-binaries-dir/ | |
| build-bluefield-otelcol-contrib: | |
| needs: | |
| - prepare | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: bluefield/containers/otelcol-contrib/Dockerfile | |
| context_path: . | |
| image_name: nvcr.io/0837451325059433/carbide-dev/otelcol-contrib | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| secrets: inherit | |
| build-bluefield-forge-dpu-agent: | |
| needs: | |
| - prepare | |
| - build-bluefield-binaries | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-bluefield-binaries.result == 'success' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: bluefield/containers/forge-dpu-agent/Dockerfile | |
| image_name: nvcr.io/0837451325059433/carbide-dev/forge-dpu-agent | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| download_artifacts: true | |
| secrets: inherit | |
| build-bluefield-forge-dhcp-server: | |
| needs: | |
| - prepare | |
| - build-bluefield-binaries | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-bluefield-binaries.result == 'success' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: bluefield/containers/forge-dhcp-server/Dockerfile | |
| image_name: nvcr.io/0837451325059433/carbide-dev/forge-dhcp-server | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| download_artifacts: true | |
| secrets: inherit | |
| build-bluefield-forge-dpu-otel-agent: | |
| needs: | |
| - prepare | |
| - build-bluefield-binaries | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-bluefield-binaries.result == 'success' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: bluefield/containers/forge-dpu-otel-agent/Dockerfile | |
| image_name: nvcr.io/0837451325059433/carbide-dev/forge-dpu-otel-agent | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| download_artifacts: true | |
| secrets: inherit | |
| build-bluefield-carbide-fmds: | |
| needs: | |
| - prepare | |
| - build-bluefield-binaries | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-bluefield-binaries.result == 'success' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: bluefield/containers/carbide-fmds/Dockerfile | |
| image_name: nvcr.io/0837451325059433/carbide-dev/carbide-fmds | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/arm64 | |
| runner: linux-arm64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| download_artifacts: true | |
| secrets: inherit | |
| # ============================================================================ | |
| # BUILD STAGE - Bluefield Helm Charts | |
| # ============================================================================ | |
| build-validate-bluefield-helm-charts: | |
| needs: | |
| - prepare | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' }} | |
| runs-on: linux-amd64-cpu4 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Validate carbide-otelcol chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-validate@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-otelcol | |
| lint: 'true' | |
| template: 'true' | |
| - name: Validate carbide-dpu-agent chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-validate@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-dpu-agent | |
| lint: 'true' | |
| template: 'true' | |
| - name: Validate carbide-dhcp-server chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-validate@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-dhcp-server | |
| lint: 'true' | |
| template: 'true' | |
| - name: Validate carbide-dpu-otel-agent chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-validate@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-dpu-otel-agent | |
| lint: 'true' | |
| template: 'true' | |
| - name: Validate carbide-fmds chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-validate@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-fmds | |
| lint: 'true' | |
| template: 'true' | |
| build-push-bluefield-helm-charts: | |
| needs: | |
| - prepare | |
| - build-validate-bluefield-helm-charts | |
| if: ${{ !cancelled() && github.event_name != 'schedule' && needs.prepare.result == 'success' && needs.build-validate-bluefield-helm-charts.result == 'success' && !contains(github.ref, 'pull-request/') }} | |
| runs-on: linux-amd64-cpu4 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Package and push carbide-otelcol chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-package-push@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-otelcol | |
| chart-version: ${{ needs.prepare.outputs.helm_version }} | |
| app-version: ${{ needs.prepare.outputs.version }} | |
| lint: 'false' | |
| ngc-key: ${{ secrets.NVCR_TOKEN }} | |
| ngc-path: 0837451325059433/carbide-dev | |
| ngc-duplicate: fail | |
| # helm-package-push expects exactly one .tgz in package/, so we have to clean the previously built chart | |
| - name: Clean helm package directory | |
| run: rm -rf package/ | |
| - name: Package and push carbide-dpu-agent chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-package-push@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-dpu-agent | |
| chart-version: ${{ needs.prepare.outputs.helm_version }} | |
| app-version: ${{ needs.prepare.outputs.version }} | |
| lint: 'false' | |
| ngc-key: ${{ secrets.NVCR_TOKEN }} | |
| ngc-path: 0837451325059433/carbide-dev | |
| ngc-duplicate: fail | |
| # helm-package-push expects exactly one .tgz in package/, so we have to clean the previously built chart | |
| - name: Clean helm package directory | |
| run: rm -rf package/ | |
| - name: Package and push carbide-dhcp-server chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-package-push@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-dhcp-server | |
| chart-version: ${{ needs.prepare.outputs.helm_version }} | |
| app-version: ${{ needs.prepare.outputs.version }} | |
| lint: 'false' | |
| ngc-key: ${{ secrets.NVCR_TOKEN }} | |
| ngc-path: 0837451325059433/carbide-dev | |
| ngc-duplicate: fail | |
| # helm-package-push expects exactly one .tgz in package/, so we have to clean the previously built chart | |
| - name: Clean helm package directory | |
| run: rm -rf package/ | |
| - name: Package and push carbide-dpu-otel-agent chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-package-push@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-dpu-otel-agent | |
| chart-version: ${{ needs.prepare.outputs.helm_version }} | |
| app-version: ${{ needs.prepare.outputs.version }} | |
| lint: 'false' | |
| ngc-key: ${{ secrets.NVCR_TOKEN }} | |
| ngc-path: 0837451325059433/carbide-dev | |
| ngc-duplicate: fail | |
| # helm-package-push expects exactly one .tgz in package/, so we have to clean the previously built chart | |
| - name: Clean helm package directory | |
| run: rm -rf package/ | |
| - name: Package and push carbide-fmds chart | |
| uses: NVIDIA/dsx-github-actions/.github/actions/helm-package-push@94bde998f5d7965576b0c663db7d5d709c918167 | |
| with: | |
| chart-path: bluefield/charts/carbide-fmds | |
| chart-version: ${{ needs.prepare.outputs.helm_version }} | |
| app-version: ${{ needs.prepare.outputs.version }} | |
| lint: 'false' | |
| ngc-key: ${{ secrets.NVCR_TOKEN }} | |
| ngc-path: 0837451325059433/carbide-dev | |
| ngc-duplicate: fail | |
| # ============================================================================ | |
| # BUILD SBOM | |
| # ============================================================================ | |
| build-sbom-container: | |
| needs: | |
| - prepare | |
| if: ${{ needs.prepare.outputs.sbom_container_run == 'true' }} | |
| uses: ./.github/workflows/docker-build.yml | |
| with: | |
| dockerfile_path: dev/docker/sbom-tools/Dockerfile | |
| image_name: nvcr.io/0837451325059433/carbide-dev/sbom-tools | |
| image_tag: ${{ needs.prepare.outputs.version }} | |
| platforms: linux/amd64 | |
| runner: linux-amd64-cpu4 | |
| push: ${{ !contains(github.ref, 'pull-request/') }} | |
| load: false | |
| secrets: inherit | |
| build-summary: | |
| runs-on: linux-amd64-cpu4 | |
| if: ${{ always() && github.event_name != 'schedule' }} | |
| needs: | |
| - build-container-x86_64 | |
| - build-container-aarch64 | |
| - build-runtime-container-x86_64 | |
| - build-runtime-container-aarch64 | |
| - build-artifacts-container-x86_64 | |
| - build-artifacts-container-aarch64 | |
| - build-release-container-x86_64 | |
| - build-release-container-aarch64 | |
| - build-boot-artifacts-x86 | |
| - build-boot-artifacts-bfb | |
| - build-boot-artifacts-ephemeral-image-x86-host | |
| - build-boot-artifacts-ephemeral-image-arm-host | |
| - build-forge-cli-x86_64 | |
| - build-forge-cli-aarch64 | |
| - merge-manifests-forge-cli | |
| - build-release-machine-validation-runner | |
| - build-release-machine-validation-artifacts-x86-host | |
| - build-powerdns-container | |
| - build-validate-helm-chart | |
| - build-push-helm-chart | |
| - build-release-artifacts-x86-host | |
| - build-release-artifacts-arm-host | |
| - build-bluefield-binaries | |
| - build-bluefield-otelcol-contrib | |
| - build-bluefield-forge-dpu-agent | |
| - build-bluefield-forge-dhcp-server | |
| - build-bluefield-forge-dpu-otel-agent | |
| - build-bluefield-carbide-fmds | |
| - build-validate-bluefield-helm-charts | |
| - build-push-bluefield-helm-charts | |
| - lint-police | |
| steps: | |
| - name: Generate summary | |
| run: | | |
| NEEDS='${{ toJson(needs) }}' | |
| echo "## Build Jobs Summary" >> "$GITHUB_STEP_SUMMARY" | |
| echo >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Job | Status |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "|-----|--------|" >> "$GITHUB_STEP_SUMMARY" | |
| echo "$NEEDS" | jq -r ' | |
| to_entries[] | |
| | select(.key | startswith("build-")) | |
| | "| \(.key) | \(if .value.result == "failure" then "**\(.value.result)**" else .value.result end) |" | |
| ' >> "$GITHUB_STEP_SUMMARY" | |
| echo >> "$GITHUB_STEP_SUMMARY" | |
| echo "## Docker Images Built" >> "$GITHUB_STEP_SUMMARY" | |
| echo >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Job | Image |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "|-----|-------|" >> "$GITHUB_STEP_SUMMARY" | |
| # Collect image_ref from docker-build jobs | |
| declare -A IMAGES | |
| IMAGES["build-container-x86_64"]="${{ needs.build-container-x86_64.outputs.image_ref }}" | |
| IMAGES["build-container-aarch64"]="${{ needs.build-container-aarch64.outputs.image_ref }}" | |
| IMAGES["build-runtime-container-x86_64"]="${{ needs.build-runtime-container-x86_64.outputs.image_ref }}" | |
| IMAGES["build-runtime-container-aarch64"]="${{ needs.build-runtime-container-aarch64.outputs.image_ref }}" | |
| IMAGES["build-artifacts-container-x86_64"]="${{ needs.build-artifacts-container-x86_64.outputs.image_ref }}" | |
| IMAGES["build-artifacts-container-aarch64"]="${{ needs.build-artifacts-container-aarch64.outputs.image_ref }}" | |
| IMAGES["build-release-container-x86_64"]="${{ needs.build-release-container-x86_64.outputs.image_ref }}" | |
| IMAGES["build-release-container-aarch64"]="${{ needs.build-release-container-aarch64.outputs.image_ref }}" | |
| IMAGES["build-forge-cli-x86_64"]="${{ needs.build-forge-cli-x86_64.outputs.image_ref }}" | |
| IMAGES["build-forge-cli-aarch64"]="${{ needs.build-forge-cli-aarch64.outputs.image_ref }}" | |
| IMAGES["build-release-machine-validation-runner"]="${{ needs.build-release-machine-validation-runner.outputs.image_ref }}" | |
| IMAGES["build-release-machine-validation-artifacts-x86-host"]="${{ needs.build-release-machine-validation-artifacts-x86-host.outputs.image_ref }}" | |
| IMAGES["build-powerdns-container"]="${{ needs.build-powerdns-container.outputs.image_ref }}" | |
| IMAGES["build-release-artifacts-x86-host"]="${{ needs.build-release-artifacts-x86-host.outputs.image_ref }}" | |
| IMAGES["build-release-artifacts-arm-host"]="${{ needs.build-release-artifacts-arm-host.outputs.image_ref }}" | |
| for job in "${!IMAGES[@]}"; do | |
| image="${IMAGES[$job]}" | |
| if [[ -n "$image" ]]; then | |
| echo "| $job | \`$image\` |" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| done | |
| promote-to-be-scanned-image: | |
| # Skip for pull-request/* branches (main, release/*, and tags are allowed by workflow trigger) | |
| if: ${{ !cancelled() && needs.build-release-container-x86_64.result == 'success' && github.event_name != 'schedule' && !contains(github.ref, 'pull-request/') }} | |
| needs: | |
| - prepare | |
| - build-release-container-x86_64 | |
| uses: NVIDIA/dsx-github-actions/.github/workflows/promote-image.yml@760d2d7964b479fde431cd3e0b980bc6b6a26ccd | |
| with: | |
| source: nvcr.io/0837451325059433/carbide-dev/nvmetal-carbide | |
| source_tag: ${{ needs.prepare.outputs.version }} | |
| destination: nvcr.io/0837451325059433/carbide/nvmetal-carbide | |
| destination_tag: "to-be-scanned" | |
| secrets: | |
| SOURCE_USERNAME: ${{ secrets.NVCR_USERNAME }} | |
| SOURCE_PASSWORD: ${{ secrets.NVCR_TOKEN }} | |
| DEST_USERNAME: ${{ secrets.NVCR_PROD_USERNAME }} | |
| DEST_PASSWORD: ${{ secrets.NVCR_PROD_TOKEN }} | |
| # ============================================================================ | |
| # NOTIFICATION STAGE | |
| # ============================================================================ | |
| notify-build-status: | |
| if: ${{ always() && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && github.event_name != 'schedule' }} | |
| needs: | |
| - prepare | |
| - build-container-x86_64 | |
| - build-container-aarch64 | |
| - build-runtime-container-x86_64 | |
| - build-runtime-container-aarch64 | |
| - build-artifacts-container-x86_64 | |
| - build-artifacts-container-aarch64 | |
| - build-release-container-x86_64 | |
| - build-release-container-aarch64 | |
| - build-boot-artifacts-x86 | |
| - build-boot-artifacts-bfb | |
| - build-boot-artifacts-ephemeral-image-x86-host | |
| - build-boot-artifacts-ephemeral-image-arm-host | |
| - build-forge-cli-x86_64 | |
| - build-forge-cli-aarch64 | |
| - merge-manifests-forge-cli | |
| - build-release-machine-validation-runner | |
| - build-release-machine-validation-artifacts-x86-host | |
| - build-powerdns-container | |
| - build-validate-helm-chart | |
| - build-push-helm-chart | |
| - build-release-artifacts-x86-host | |
| - build-release-artifacts-arm-host | |
| - build-bluefield-binaries | |
| - build-bluefield-otelcol-contrib | |
| - build-bluefield-forge-dpu-agent | |
| - build-bluefield-forge-dhcp-server | |
| - build-bluefield-forge-dpu-otel-agent | |
| - build-bluefield-carbide-fmds | |
| - build-validate-bluefield-helm-charts | |
| - build-push-bluefield-helm-charts | |
| - build-sbom-container | |
| - security-secret-scan | |
| - security-codeql-scan | |
| - promote-to-be-scanned-image | |
| uses: ./.github/workflows/notify-build-status.yml | |
| with: | |
| version: ${{ needs.prepare.outputs.version }} | |
| workflow-name: "Carbide Core CI" | |
| channel-id: C0A0TSKJKSB # #dsx-carbide-feed | |
| needs-context: ${{ toJson(needs) }} | |
| notify-on-success: true | |
| notify-on-partial: true | |
| notify-on-failure: true | |
| secrets: | |
| slack-bot-token: ${{ secrets.CDS_SLACK_BOT_OAUTH_TOKEN }} |