# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

name: Build Framework Image Matrix

on:
  workflow_call:
    inputs:
      framework:
        description: 'Framework name (vllm, sglang, trtllm)'
        required: true
        type: string
      target:
        description: 'Target stage for Docker rendering'
        required: true
        type: string
      platforms:
        description: 'Platforms to build (JSON array, e.g., ["amd64", "arm64"])'
        required: true
        type: string
      cuda_versions:
        description: 'CUDA versions to build (JSON array, e.g., ["12.9", "13.0"])'
        required: true
        type: string
      builder_name:
        description: 'Buildkit builder name'
        required: true
        type: string
      build_timeout_minutes:
        description: 'Timeout in minutes for the build step'
        required: false
        type: number
        default: 60
      push_image:
        description: 'Push image to registry'
        required: false
        type: boolean
        default: false
      extra_tags:
        description: 'Additional tags (newline-separated, -$platform suffix auto-appended)'
        required: false
        type: string
        default: ''
      make_efa:
        description: 'Enable AWS EFA support in the build'
        required: false
        type: boolean
        default: false
      no_cache:
        description: 'Disable Docker build cache'
        required: false
        type: boolean
        default: false
      sanitized_ref_name:
        description: 'Sanitized git ref name for branch-tagged images'
        required: false
        type: string
        default: ''
      build_only:
        description: 'Build and push only — enables branch-tagged images'
        required: false
        type: boolean
        default: false
      run_compliance_scan:
        description: 'Run compliance scan after build'
        required: false
        type: boolean
        default: false
      copy_to_acr:
        description: 'Copy the built image from ECR to ACR using skopeo after the build'
        required: false
        type: boolean
        default: false
      copy_timeout_minutes:
        description: 'Timeout in minutes for the copy to ACR step'
        required: false
        type: number
        default: 10
    secrets:
      AWS_DEFAULT_REGION:
        required: true
      AWS_ACCOUNT_ID:
        required: true
      AZURE_ACR_HOSTNAME:
        required: true
      AZURE_ACR_USER:
        required: true
      AZURE_ACR_PASSWORD:
        required: true
      SCCACHE_S3_BUCKET:
        required: false
      AWS_ACCESS_KEY_ID:
        required: false
      AWS_SECRET_ACCESS_KEY:
        required: false
      HF_TOKEN:
        required: false

jobs:
  build:
    name: Build cuda${{ matrix.cuda_version }}-${{ matrix.platform }}
    runs-on: prod-builder-v3
    timeout-minutes: ${{ inputs.build_timeout_minutes }}
    strategy:
      fail-fast: false
      matrix:
        platform: ${{ fromJson(inputs.platforms) }}
        cuda_version: ${{ fromJson(inputs.cuda_versions) }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955  # v4.3.0
        with:
          lfs: true
      - name: Build
        id: build
        uses: ./.github/actions/build-flavor
        with:
          framework: ${{ inputs.framework }}
          target: ${{ inputs.target }}
          platform: ${{ matrix.platform }}
          cuda_version: ${{ matrix.cuda_version }}
          builder_name: ${{ inputs.builder_name }}
          aws_default_region: ${{ secrets.AWS_DEFAULT_REGION }}
          aws_account_id: ${{ secrets.AWS_ACCOUNT_ID }}
          azure_acr_hostname: ${{ secrets.AZURE_ACR_HOSTNAME }}
          azure_acr_user: ${{ secrets.AZURE_ACR_USER }}
          azure_acr_password: ${{ secrets.AZURE_ACR_PASSWORD }}
          sccache_s3_bucket: ${{ secrets.SCCACHE_S3_BUCKET }}
          aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          hf_token: ${{ secrets.HF_TOKEN }}
          build_timeout_minutes: ${{ inputs.build_timeout_minutes }}
          push_image: ${{ inputs.push_image }}
          no_cache: ${{ inputs.no_cache }}
          make_efa: ${{ inputs.make_efa }}
          extra_tags: ${{ inputs.extra_tags }}
          sanitized_ref_name: ${{ inputs.sanitized_ref_name }}
          build_only: ${{ inputs.build_only }}
          show_summary: ${{ inputs.push_image }}
      - name: Refresh BuildKit builder
        if: ${{ inputs.target != 'dev' }}
        uses: ./.github/actions/builder-refresher
        with:
          builder_name: ${{ inputs.builder_name }}
          flavor: ${{ inputs.framework }}
          arch: ${{ matrix.platform }}
          cuda_version: ${{ matrix.cuda_version }}
      - name: Copy image to ACR
        if: inputs.copy_to_acr
        timeout-minutes: ${{ inputs.copy_timeout_minutes }}
        uses: ./.github/actions/skopeo-copy
        with:
          source_registry: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_DEFAULT_REGION }}.amazonaws.com
          source_image: ai-dynamo/dynamo
          source_tag: ${{ steps.build.outputs.target_tag_plain }}-cuda${{ steps.build.outputs.cuda_version_plain }}-${{ matrix.platform }}
          target_registry: ${{ secrets.AZURE_ACR_HOSTNAME }}
          target_image: ai-dynamo/dynamo
          target_tag: ${{ steps.build.outputs.target_tag_plain }}-cuda${{ steps.build.outputs.cuda_version_plain }}-${{ matrix.platform }}
          source_aws_default_region: ${{ secrets.AWS_DEFAULT_REGION }}
          source_aws_account_id: ${{ secrets.AWS_ACCOUNT_ID }}
          target_azure_acr_hostname: ${{ secrets.AZURE_ACR_HOSTNAME }}
          target_azure_acr_user: ${{ secrets.AZURE_ACR_USER }}
          target_azure_acr_password: ${{ secrets.AZURE_ACR_PASSWORD }}
      - name: Calculate compliance image URI
        id: compliance-image
        if: inputs.run_compliance_scan
        shell: bash
        run: |
          CUDA_MAJOR="${{ matrix.cuda_version }}"
          CUDA_MAJOR="${CUDA_MAJOR%%.*}"
          EFA_SUFFIX=""
          if [ "${{ inputs.make_efa }}" == "true" ]; then
            EFA_SUFFIX="-efa"
          fi
          TARGET_TAG="${{ github.sha }}-${{ inputs.framework }}-${{ inputs.target }}${EFA_SUFFIX}"
          IMAGE="${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_DEFAULT_REGION }}.amazonaws.com/ai-dynamo/dynamo:${TARGET_TAG}-cuda${CUDA_MAJOR}-${{ matrix.platform }}"
          echo "runtime_image=${IMAGE}" >> $GITHUB_OUTPUT
          echo "cuda_major=${CUDA_MAJOR}" >> $GITHUB_OUTPUT
      - name: Compliance scan
        if: inputs.run_compliance_scan
        uses: ./.github/actions/compliance-scan
        with:
          image: ${{ steps.compliance-image.outputs.runtime_image }}
          artifact_name: compliance-${{ inputs.framework }}-${{ inputs.target }}${{ inputs.make_efa && '-efa' || '' }}-cuda${{ steps.compliance-image.outputs.cuda_major }}-${{ matrix.platform }}
          arch: ${{ matrix.platform }}
          framework: ${{ inputs.framework }}
          cuda_version: ${{ matrix.cuda_version }}