Skip to content

Instantly share code, notes, and snippets.

@dhellmann
Created September 23, 2025 20:46
Show Gist options
  • Save dhellmann/c1f99de188872f4d42a4766f17ae7cc8 to your computer and use it in GitHub Desktop.
Save dhellmann/c1f99de188872f4d42a4766f17ae7cc8 to your computer and use it in GitHub Desktop.

Add BUILD_MODE input to script

Exported on 9/23/2025 at 16:45:57 EDT from Cursor (1.6.42)


User

I want to add a new input BUILD_MODE, similar to BOOTSTRAP_MODE. It should be an enum with 2 options, "parallel" and "serial". The default should be parallel. The input value needs to be saved as a variable on the job and needs to be passed as an environment variable when podman is run.

Then the script pipeline-api/build_wheels.sh needs to be updated to look for the variable. If it is not set, it should assume the mode is parallel. When the mode is parallel the script should call fromager's build-parallel command with the graph file. When the mode is serial, the script should call fromager's build-serial command with the build order file.


Cursor

I'll help you add a new BUILD_MODE input to the CI pipeline and update the build script. Let me first examine the current files to understand the structure and how BOOTSTRAP_MODE is implemented.

Now let me create a todo list to track the changes needed:

Now I'll implement the changes. First, let me add the BUILD_MODE input to the CI configuration:

# This yaml file contains the CI jobs as an API that can be used by other repositories outside builder

spec:
  inputs:
    JOB_STAGE:
      default: build
      description: "Define the job stage that will run the bootstrap and onboard steps of wheel pipeline"
    JOB_PREFIX:
      default: ""
      description: "Define a prefix for the job name"
      type: string
    COLLECTION:
      description: "Define the collection name for which you want to build wheels"
      type: string
    VARIANT:
      description: "Define the variant for which you want to build wheels"
      options: ["cpu-ubi9", "cuda-ubi9", "rocm-ubi9", "spyre-ubi9", "tpu-ubi9"] # , "gaudi-ubi9"]
    ENABLE_REPEATABLE_BUILD_MODE:
      default: false
      description: "Setting which enables repeatable build mode"
      type: boolean
    BOOTSTRAP_MODE:
      description: "Setting for bootstrap mode: 'bootstrap --sdist-only', 'bootstrap --full-build', 'bootstrap-parallel'"
      options: ["sdist-only", "full", "full-parallel"]
      default: "sdist-only"
    BUILD_MODE:
      description: "Setting for build mode: 'parallel' uses build-parallel with graph file, 'serial' uses build-sequence with build order file"
      options: ["parallel", "serial"]
      default: "parallel"
    ARCH:
      default: "x86_64"
      description: "Define the CPU architecture to build wheels for"
      options: ["aarch64", "x86_64", "ppc64le"]
    BUILD_ON_ALL_PUSHES:
      default: false
      description: "Build for every merge, even if the collection has not changed."
      type: boolean
    ENABLE_NIGHTLY_BUILDS:
      default: false
      description: "Setting that enables nightly builds for a given collection"
      type: boolean
    ENABLE_TEST_JOBS:
      default: false
      description: "Setting that enables test build jobs for testing resolution and build of packages"
      type: boolean
---
# ======================================================================== VARIABLES ===============================================================
variables:
  # Set BUILDER_IMAGE_VERSION to some fake value which will be overridden by users when they invoke the API
  BUILDER_IMAGE_VERSION: v0.0
  WHEEL_SERVER_PROJECT_PREFIX: "${CI_PROJECT_NAMESPACE}/indexes"
  # Set PRODUCT_VERSION as a global variable. The default should look like a real value
  COLLECTION_VERSION: $PRODUCT_VERSION
  PRODUCT_VERSION: "0.0"
  # Used in the builder repo to let collections build multiple
  # versions of a package. Disabling constraints output also disables
  # release jobs.
  FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS: false
  # Set PRODUCT_NAME to rhoai. We need PRODUCT_NAME for customer facing package index hosted in PULP
  PRODUCT_NAME: "rhoai"

# =========================================================================== API BASE JOBS ===================================================================

# Base job for release variables
.$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job:
  variables:
    PUBLISH_AUTH_HEADER: "PRIVATE-TOKEN: ${BOT_PAT}"
    RELEASE_TARBALL: "wheels-${RELEASE_VERSION}.tar.gz"
    RELEASE_VERSION_SUFFIX: "+$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]"
    RELEASE_VERSION: "${PRODUCT_VERSION}.${CI_PIPELINE_IID}${RELEASE_VERSION_SUFFIX}"
    GITLAB_PACKAGE_URL: "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/generic/$[[ inputs.COLLECTION ]]-wheels"
    PUBLISH_URL: "${GITLAB_PACKAGE_URL}/${RELEASE_VERSION}"

# Base job for the api
.$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job
  image: registry.gitlab.com/redhat/rhel-ai/wheels/builder/podman-stable:v5.5.0
  timeout: 12h
  services:
  # No services section needed for pinp
  interruptible: true
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_PROTECTED == "true"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
    - if: $CI_PIPELINE_SOURCE == "push" && "$[[ inputs.BUILD_ON_ALL_PUSHES ]]" == "true" && $CI_COMMIT_REF_PROTECTED == "true"
    - if: '$CI_PIPELINE_SOURCE == "schedule" && "$[[ inputs.ENABLE_NIGHTLY_BUILDS ]]" == "true"'
  variables:
    FF_SCRIPT_SECTIONS: "true"
    COLLECTION: "$[[ inputs.COLLECTION ]]"
    VARIANT: "$[[ inputs.VARIANT ]]"
    ARCH: "$[[ inputs.ARCH ]]"
    IMAGE_BASE: ${CI_REGISTRY}/redhat/rhel-ai/wheels/builder/builder-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]
    IMAGE: ${IMAGE_BASE}:${BUILDER_IMAGE_VERSION}
    CONTAINERFILE: Containerfile.$[[ inputs.VARIANT ]]
    TOOL_SERVER_URL: "https://gitlab.com/api/v4/projects/61507476/packages/pypi/simple/"
    OUTDIR: /mnt
    JOB_OUTPUT_DIR: /builds/$CI_PROJECT_PATH/mnt
    WHEEL_SERVER_PROJECT_PATH: "${WHEEL_SERVER_PROJECT_PREFIX}/$[[ inputs.COLLECTION ]]-${PRODUCT_VERSION}/$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]"
    SDIST_SERVER_PROJECT_PATH: "redhat/rhel-ai/wheels/prefetch"
    RUN_CLEAN_AND_UPLOAD: "false"
    # These flags are not part of the formal API, but is used to
    # control the jobs in the builder repository.
    BOOTSTRAP_RUN_ONBOARD: "true"
    BUILD_ON_ALL_PUSHES: "$[[ inputs.BUILD_ON_ALL_PUSHES ]]"
    # We need to use non-standard BOOTSTRAP_MODE for some jobs in builder which are not triggered by API
    BOOTSTRAP_MODE: $[[ inputs.BOOTSTRAP_MODE ]]
  before_script:
    # Dump our settings to the log
    - env
    - dnf install -y which ncurses
    # https://docs.gitlab.com/ee/ci/docker/authenticate_registry.html
    - podman login $CI_REGISTRY --username $CI_REGISTRY_USER --password "$CI_REGISTRY_PASSWORD"
    # Install dependencies for downloading secure files
    - dnf install -y which curl bash
    # Share the test script with the container using a directory in /builds, following:
    # https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#known-issues-with-docker-in-docker
    - mkdir -p "${JOB_OUTPUT_DIR}"
    - cp -rv collections "${JOB_OUTPUT_DIR}/"
    # Generate .netrc dynamically and put in inside the container where we want it
    - echo -e "machine gitlab.com\nlogin platform-engineering-bot\npassword ${BOT_PAT}" > ${JOB_OUTPUT_DIR}/.netrc
    # Configure Podman storage
    - mkdir -p /etc/containers
    # create default overlay configuration. Embed storage.conf as HEREDOC.
    # pipelines in other projects cannot access files in builder repo.
    - |
      cat > /etc/containers/storage.conf << EOF
      [storage]
      driver = "overlay"
      runroot = "/var/run/containers/storage"
      graphroot = "/var/lib/containers/storage"
      [storage.options]
      mount_program = ""
      EOF
    - mkdir -p /var/run/containers/storage
    - mkdir -p /var/lib/containers/storage
    # AWS (may) have an existing storage configuration that works with dind but not
    # pinp.  This causes pinp to fail with
    #      "OSError: [Errno 107] Transport endpoint is not connected:
    # errors.  Remove the contents of these directories to re-initialize the overlay
    # storage.
    - rm -rf /var/lib/containers/storage/*
    - rm -rf /var/run/containers/storage/*
  script:
    - >
      podman run \
        -v "$JOB_OUTPUT_DIR:/mnt" \
        -v ".:/collection-repository" \
        -e "NETRC=/mnt/.netrc" \
        -e "OUTDIR=$OUTDIR" \
        -e "FROMAGER_VARIANT=$[[ inputs.VARIANT ]]" \
        -e "COLLECTION=$[[ inputs.COLLECTION ]]" \
        -e "PRODUCT_VERSION=$PRODUCT_VERSION" \
        -e "ENABLE_REPEATABLE_BUILD_MODE=$[[ inputs.ENABLE_REPEATABLE_BUILD_MODE ]]" \
        -e "BOOTSTRAP_MODE=$BOOTSTRAP_MODE" \
        -e "WHEEL_SERVER_PROJECT_PATH=${WHEEL_SERVER_PROJECT_PATH}" \
        -e "SDIST_SERVER_PROJECT_PATH=${SDIST_SERVER_PROJECT_PATH}" \
        -e "PUBLISH_AUTH_HEADER=${PUBLISH_AUTH_HEADER}" \
        -e "RELEASE_VERSION=${RELEASE_VERSION}" \
        -e "RELEASE_VERSION_SUFFIX=${RELEASE_VERSION_SUFFIX}" \
        -e "RELEASE_TARBALL=${RELEASE_TARBALL}" \
        -e "PUBLISH_URL=${PUBLISH_URL}" \
        -e "GITLAB_PACKAGE_URL=${GITLAB_PACKAGE_URL}" \
        -e "RUN_CLEAN_AND_UPLOAD=${RUN_CLEAN_AND_UPLOAD}" \
        -e "BOT_PAT=${BOT_PAT}" \
        -e "BOT_USER=${BOT_USER}" \
        -e "BOOTSTRAP_RUN_ONBOARD=${BOOTSTRAP_RUN_ONBOARD}" \
        -e "REPOSITORY_URL=${CI_REPOSITORY_URL}" \
        -e "FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS=${FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS}" \
        -e "PRODUCT_NAME=$PRODUCT_NAME" \
        ${IMAGE} \
        ${API_SCRIPT}
    # Development command - will be removed eventually when we will have pulp upload script running in builder
    - >
      if [ -f ./bin/upload_to_pulp.sh ] && [[ "$CI_JOB_NAME" == *"build-wheels" ]]; then
        podman run \
          -v "$JOB_OUTPUT_DIR:/mnt" \
          -v ".:/collection-repository" \
          -e "NETRC=/mnt/.netrc" \
          -e "OUTDIR=$OUTDIR" \
          -e "FROMAGER_VARIANT=$[[ inputs.VARIANT ]]" \
          -e "COLLECTION=$[[ inputs.COLLECTION ]]" \
          -e "PRODUCT_VERSION=$PRODUCT_VERSION" \
          -e "ENABLE_REPEATABLE_BUILD_MODE=$[[ inputs.ENABLE_REPEATABLE_BUILD_MODE ]]" \
          -e "BOOTSTRAP_MODE=$BOOTSTRAP_MODE" \
          -e "WHEEL_SERVER_PROJECT_PATH=${WHEEL_SERVER_PROJECT_PATH}" \
          -e "SDIST_SERVER_PROJECT_PATH=${SDIST_SERVER_PROJECT_PATH}" \
          -e "PUBLISH_AUTH_HEADER=${PUBLISH_AUTH_HEADER}" \
          -e "RELEASE_VERSION=${RELEASE_VERSION}" \
          -e "RELEASE_VERSION_SUFFIX=${RELEASE_VERSION_SUFFIX}" \
          -e "RELEASE_TARBALL=${RELEASE_TARBALL}" \
          -e "PUBLISH_URL=${PUBLISH_URL}" \
          -e "GITLAB_PACKAGE_URL=${GITLAB_PACKAGE_URL}" \
          -e "RUN_CLEAN_AND_UPLOAD=${RUN_CLEAN_AND_UPLOAD}" \
          -e "BOT_PAT=${BOT_PAT}" \
          -e "BOT_USER=${BOT_USER}" \
          -e "BOOTSTRAP_RUN_ONBOARD=${BOOTSTRAP_RUN_ONBOARD}" \
          -e "REPOSITORY_URL=${CI_REPOSITORY_URL}" \
          -e "FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS=${FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS}" \
          -e "PULP_CERT_BASE64=${PULP_CERT_BASE64}" \
          -e "PULP_KEY_BASE64=${PULP_KEY_BASE64}" \
          -e "PRODUCT_NAME=$PRODUCT_NAME" \
          ${IMAGE} \
          /collection-repository/bin/upload_to_pulp.sh
      fi
  artifacts:
    paths:
      - $JOB_OUTPUT_DIR/*.log
      - $JOB_OUTPUT_DIR/computed-constraints.txt
      - $JOB_OUTPUT_DIR/computed-requirements.txt
      - $JOB_OUTPUT_DIR/work-dir/*/*.log
      - $JOB_OUTPUT_DIR/work-dir/logs/
      - $JOB_OUTPUT_DIR/work-dir/*.json
      - $JOB_OUTPUT_DIR/work-dir/constraints.txt
      - $JOB_OUTPUT_DIR/work-dir/build-sequence-summary.md
    when: always
  tags:
    - aipcc-large-$[[ inputs.ARCH ]]

# =========================================================== BOOTSTRAP AND ONBOARD API JOB ================================================================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/bootstrap_and_onboard.sh

# =========================================================== TEST BOOTSTRAP AND ONBOARD API JOB ================================================================================

test-$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $ENABLE_TEST_JOBS == "false"
      # Do not run the job if test jobs are turned off.
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/bootstrap_and_onboard.sh
    BOOTSTRAP_RUN_ONBOARD: "false"
    BOOTSTRAP_MODE: "full-parallel"
    ENABLE_TEST_JOBS: "$[[ inputs.ENABLE_TEST_JOBS ]]"

# ==================================== BUILD WHEEL SEQUENCE API JOB ==============================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-build-wheels:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/build_wheels.sh
    RUN_CLEAN_AND_UPLOAD: "true"
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard
      artifacts: true

# ==================================================== RELEASE API JOB ============================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-release-tarball:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/make_release_tarball.sh
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-build-wheels
      artifacts: true

# ============================================ PUBLISH API JOB ====================================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-publish-wheels:
  image: "registry.gitlab.com/gitlab-org/release-cli:latest"
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  interruptible: true
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: '$FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS == "true"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_PROTECTED == "true"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
    - if: '$CI_PIPELINE_SOURCE == "schedule" && "$[[ inputs.ENABLE_NIGHTLY_BUILDS ]]" == "true"'
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-release-tarball
      artifacts: true
  script:
    - echo "running publish job $CI_JOB_NAME for $RELEASE_VERSION and $[[ inputs.ARCH ]] arch"
  release:
    # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties
    tag_name: "$RELEASE_VERSION"
    description: /mnt/work-dir/build-sequence-summary.md
    ref: "$CI_COMMIT_SHA"
    assets:
      links:
        - name: "$RELEASE_TARBALL"
          url: "$PUBLISH_URL/$RELEASE_TARBALL"
  tags:
    - aipcc

Now I'll add the BUILD_MODE as a job variable and mark the next todo as in progress:

# This yaml file contains the CI jobs as an API that can be used by other repositories outside builder

spec:
  inputs:
    JOB_STAGE:
      default: build
      description: "Define the job stage that will run the bootstrap and onboard steps of wheel pipeline"
    JOB_PREFIX:
      default: ""
      description: "Define a prefix for the job name"
      type: string
    COLLECTION:
      description: "Define the collection name for which you want to build wheels"
      type: string
    VARIANT:
      description: "Define the variant for which you want to build wheels"
      options: ["cpu-ubi9", "cuda-ubi9", "rocm-ubi9", "spyre-ubi9", "tpu-ubi9"] # , "gaudi-ubi9"]
    ENABLE_REPEATABLE_BUILD_MODE:
      default: false
      description: "Setting which enables repeatable build mode"
      type: boolean
    BOOTSTRAP_MODE:
      description: "Setting for bootstrap mode: 'bootstrap --sdist-only', 'bootstrap --full-build', 'bootstrap-parallel'"
      options: ["sdist-only", "full", "full-parallel"]
      default: "sdist-only"
    BUILD_MODE:
      description: "Setting for build mode: 'parallel' uses build-parallel with graph file, 'serial' uses build-sequence with build order file"
      options: ["parallel", "serial"]
      default: "parallel"
    ARCH:
      default: "x86_64"
      description: "Define the CPU architecture to build wheels for"
      options: ["aarch64", "x86_64", "ppc64le"]
    BUILD_ON_ALL_PUSHES:
      default: false
      description: "Build for every merge, even if the collection has not changed."
      type: boolean
    ENABLE_NIGHTLY_BUILDS:
      default: false
      description: "Setting that enables nightly builds for a given collection"
      type: boolean
    ENABLE_TEST_JOBS:
      default: false
      description: "Setting that enables test build jobs for testing resolution and build of packages"
      type: boolean
---
# ======================================================================== VARIABLES ===============================================================
variables:
  # Set BUILDER_IMAGE_VERSION to some fake value which will be overridden by users when they invoke the API
  BUILDER_IMAGE_VERSION: v0.0
  WHEEL_SERVER_PROJECT_PREFIX: "${CI_PROJECT_NAMESPACE}/indexes"
  # Set PRODUCT_VERSION as a global variable. The default should look like a real value
  COLLECTION_VERSION: $PRODUCT_VERSION
  PRODUCT_VERSION: "0.0"
  # Used in the builder repo to let collections build multiple
  # versions of a package. Disabling constraints output also disables
  # release jobs.
  FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS: false
  # Set PRODUCT_NAME to rhoai. We need PRODUCT_NAME for customer facing package index hosted in PULP
  PRODUCT_NAME: "rhoai"

# =========================================================================== API BASE JOBS ===================================================================

# Base job for release variables
.$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job:
  variables:
    PUBLISH_AUTH_HEADER: "PRIVATE-TOKEN: ${BOT_PAT}"
    RELEASE_TARBALL: "wheels-${RELEASE_VERSION}.tar.gz"
    RELEASE_VERSION_SUFFIX: "+$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]"
    RELEASE_VERSION: "${PRODUCT_VERSION}.${CI_PIPELINE_IID}${RELEASE_VERSION_SUFFIX}"
    GITLAB_PACKAGE_URL: "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/generic/$[[ inputs.COLLECTION ]]-wheels"
    PUBLISH_URL: "${GITLAB_PACKAGE_URL}/${RELEASE_VERSION}"

# Base job for the api
.$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job
  image: registry.gitlab.com/redhat/rhel-ai/wheels/builder/podman-stable:v5.5.0
  timeout: 12h
  services:
  # No services section needed for pinp
  interruptible: true
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_PROTECTED == "true"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
    - if: $CI_PIPELINE_SOURCE == "push" && "$[[ inputs.BUILD_ON_ALL_PUSHES ]]" == "true" && $CI_COMMIT_REF_PROTECTED == "true"
    - if: '$CI_PIPELINE_SOURCE == "schedule" && "$[[ inputs.ENABLE_NIGHTLY_BUILDS ]]" == "true"'
  variables:
    FF_SCRIPT_SECTIONS: "true"
    COLLECTION: "$[[ inputs.COLLECTION ]]"
    VARIANT: "$[[ inputs.VARIANT ]]"
    ARCH: "$[[ inputs.ARCH ]]"
    IMAGE_BASE: ${CI_REGISTRY}/redhat/rhel-ai/wheels/builder/builder-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]
    IMAGE: ${IMAGE_BASE}:${BUILDER_IMAGE_VERSION}
    CONTAINERFILE: Containerfile.$[[ inputs.VARIANT ]]
    TOOL_SERVER_URL: "https://gitlab.com/api/v4/projects/61507476/packages/pypi/simple/"
    OUTDIR: /mnt
    JOB_OUTPUT_DIR: /builds/$CI_PROJECT_PATH/mnt
    WHEEL_SERVER_PROJECT_PATH: "${WHEEL_SERVER_PROJECT_PREFIX}/$[[ inputs.COLLECTION ]]-${PRODUCT_VERSION}/$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]"
    SDIST_SERVER_PROJECT_PATH: "redhat/rhel-ai/wheels/prefetch"
    RUN_CLEAN_AND_UPLOAD: "false"
    # These flags are not part of the formal API, but is used to
    # control the jobs in the builder repository.
    BOOTSTRAP_RUN_ONBOARD: "true"
    BUILD_ON_ALL_PUSHES: "$[[ inputs.BUILD_ON_ALL_PUSHES ]]"
    # We need to use non-standard BOOTSTRAP_MODE for some jobs in builder which are not triggered by API
    BOOTSTRAP_MODE: $[[ inputs.BOOTSTRAP_MODE ]]
    BUILD_MODE: $[[ inputs.BUILD_MODE ]]
  before_script:
    # Dump our settings to the log
    - env
    - dnf install -y which ncurses
    # https://docs.gitlab.com/ee/ci/docker/authenticate_registry.html
    - podman login $CI_REGISTRY --username $CI_REGISTRY_USER --password "$CI_REGISTRY_PASSWORD"
    # Install dependencies for downloading secure files
    - dnf install -y which curl bash
    # Share the test script with the container using a directory in /builds, following:
    # https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#known-issues-with-docker-in-docker
    - mkdir -p "${JOB_OUTPUT_DIR}"
    - cp -rv collections "${JOB_OUTPUT_DIR}/"
    # Generate .netrc dynamically and put in inside the container where we want it
    - echo -e "machine gitlab.com\nlogin platform-engineering-bot\npassword ${BOT_PAT}" > ${JOB_OUTPUT_DIR}/.netrc
    # Configure Podman storage
    - mkdir -p /etc/containers
    # create default overlay configuration. Embed storage.conf as HEREDOC.
    # pipelines in other projects cannot access files in builder repo.
    - |
      cat > /etc/containers/storage.conf << EOF
      [storage]
      driver = "overlay"
      runroot = "/var/run/containers/storage"
      graphroot = "/var/lib/containers/storage"
      [storage.options]
      mount_program = ""
      EOF
    - mkdir -p /var/run/containers/storage
    - mkdir -p /var/lib/containers/storage
    # AWS (may) have an existing storage configuration that works with dind but not
    # pinp.  This causes pinp to fail with
    #      "OSError: [Errno 107] Transport endpoint is not connected:
    # errors.  Remove the contents of these directories to re-initialize the overlay
    # storage.
    - rm -rf /var/lib/containers/storage/*
    - rm -rf /var/run/containers/storage/*
  script:
    - >
      podman run \
        -v "$JOB_OUTPUT_DIR:/mnt" \
        -v ".:/collection-repository" \
        -e "NETRC=/mnt/.netrc" \
        -e "OUTDIR=$OUTDIR" \
        -e "FROMAGER_VARIANT=$[[ inputs.VARIANT ]]" \
        -e "COLLECTION=$[[ inputs.COLLECTION ]]" \
        -e "PRODUCT_VERSION=$PRODUCT_VERSION" \
        -e "ENABLE_REPEATABLE_BUILD_MODE=$[[ inputs.ENABLE_REPEATABLE_BUILD_MODE ]]" \
        -e "BOOTSTRAP_MODE=$BOOTSTRAP_MODE" \
        -e "WHEEL_SERVER_PROJECT_PATH=${WHEEL_SERVER_PROJECT_PATH}" \
        -e "SDIST_SERVER_PROJECT_PATH=${SDIST_SERVER_PROJECT_PATH}" \
        -e "PUBLISH_AUTH_HEADER=${PUBLISH_AUTH_HEADER}" \
        -e "RELEASE_VERSION=${RELEASE_VERSION}" \
        -e "RELEASE_VERSION_SUFFIX=${RELEASE_VERSION_SUFFIX}" \
        -e "RELEASE_TARBALL=${RELEASE_TARBALL}" \
        -e "PUBLISH_URL=${PUBLISH_URL}" \
        -e "GITLAB_PACKAGE_URL=${GITLAB_PACKAGE_URL}" \
        -e "RUN_CLEAN_AND_UPLOAD=${RUN_CLEAN_AND_UPLOAD}" \
        -e "BOT_PAT=${BOT_PAT}" \
        -e "BOT_USER=${BOT_USER}" \
        -e "BOOTSTRAP_RUN_ONBOARD=${BOOTSTRAP_RUN_ONBOARD}" \
        -e "REPOSITORY_URL=${CI_REPOSITORY_URL}" \
        -e "FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS=${FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS}" \
        -e "PRODUCT_NAME=$PRODUCT_NAME" \
        ${IMAGE} \
        ${API_SCRIPT}
    # Development command - will be removed eventually when we will have pulp upload script running in builder
    - >
      if [ -f ./bin/upload_to_pulp.sh ] && [[ "$CI_JOB_NAME" == *"build-wheels" ]]; then
        podman run \
          -v "$JOB_OUTPUT_DIR:/mnt" \
          -v ".:/collection-repository" \
          -e "NETRC=/mnt/.netrc" \
          -e "OUTDIR=$OUTDIR" \
          -e "FROMAGER_VARIANT=$[[ inputs.VARIANT ]]" \
          -e "COLLECTION=$[[ inputs.COLLECTION ]]" \
          -e "PRODUCT_VERSION=$PRODUCT_VERSION" \
          -e "ENABLE_REPEATABLE_BUILD_MODE=$[[ inputs.ENABLE_REPEATABLE_BUILD_MODE ]]" \
          -e "BOOTSTRAP_MODE=$BOOTSTRAP_MODE" \
          -e "WHEEL_SERVER_PROJECT_PATH=${WHEEL_SERVER_PROJECT_PATH}" \
          -e "SDIST_SERVER_PROJECT_PATH=${SDIST_SERVER_PROJECT_PATH}" \
          -e "PUBLISH_AUTH_HEADER=${PUBLISH_AUTH_HEADER}" \
          -e "RELEASE_VERSION=${RELEASE_VERSION}" \
          -e "RELEASE_VERSION_SUFFIX=${RELEASE_VERSION_SUFFIX}" \
          -e "RELEASE_TARBALL=${RELEASE_TARBALL}" \
          -e "PUBLISH_URL=${PUBLISH_URL}" \
          -e "GITLAB_PACKAGE_URL=${GITLAB_PACKAGE_URL}" \
          -e "RUN_CLEAN_AND_UPLOAD=${RUN_CLEAN_AND_UPLOAD}" \
          -e "BOT_PAT=${BOT_PAT}" \
          -e "BOT_USER=${BOT_USER}" \
          -e "BOOTSTRAP_RUN_ONBOARD=${BOOTSTRAP_RUN_ONBOARD}" \
          -e "REPOSITORY_URL=${CI_REPOSITORY_URL}" \
          -e "FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS=${FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS}" \
          -e "PULP_CERT_BASE64=${PULP_CERT_BASE64}" \
          -e "PULP_KEY_BASE64=${PULP_KEY_BASE64}" \
          -e "PRODUCT_NAME=$PRODUCT_NAME" \
          ${IMAGE} \
          /collection-repository/bin/upload_to_pulp.sh
      fi
  artifacts:
    paths:
      - $JOB_OUTPUT_DIR/*.log
      - $JOB_OUTPUT_DIR/computed-constraints.txt
      - $JOB_OUTPUT_DIR/computed-requirements.txt
      - $JOB_OUTPUT_DIR/work-dir/*/*.log
      - $JOB_OUTPUT_DIR/work-dir/logs/
      - $JOB_OUTPUT_DIR/work-dir/*.json
      - $JOB_OUTPUT_DIR/work-dir/constraints.txt
      - $JOB_OUTPUT_DIR/work-dir/build-sequence-summary.md
    when: always
  tags:
    - aipcc-large-$[[ inputs.ARCH ]]

# =========================================================== BOOTSTRAP AND ONBOARD API JOB ================================================================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/bootstrap_and_onboard.sh

# =========================================================== TEST BOOTSTRAP AND ONBOARD API JOB ================================================================================

test-$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $ENABLE_TEST_JOBS == "false"
      # Do not run the job if test jobs are turned off.
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/bootstrap_and_onboard.sh
    BOOTSTRAP_RUN_ONBOARD: "false"
    BOOTSTRAP_MODE: "full-parallel"
    ENABLE_TEST_JOBS: "$[[ inputs.ENABLE_TEST_JOBS ]]"

# ==================================== BUILD WHEEL SEQUENCE API JOB ==============================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-build-wheels:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/build_wheels.sh
    RUN_CLEAN_AND_UPLOAD: "true"
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard
      artifacts: true

# ==================================================== RELEASE API JOB ============================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-release-tarball:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/make_release_tarball.sh
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-build-wheels
      artifacts: true

# ============================================ PUBLISH API JOB ====================================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-publish-wheels:
  image: "registry.gitlab.com/gitlab-org/release-cli:latest"
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  interruptible: true
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: '$FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS == "true"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_PROTECTED == "true"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
    - if: '$CI_PIPELINE_SOURCE == "schedule" && "$[[ inputs.ENABLE_NIGHTLY_BUILDS ]]" == "true"'
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-release-tarball
      artifacts: true
  script:
    - echo "running publish job $CI_JOB_NAME for $RELEASE_VERSION and $[[ inputs.ARCH ]] arch"
  release:
    # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties
    tag_name: "$RELEASE_VERSION"
    description: /mnt/work-dir/build-sequence-summary.md
    ref: "$CI_COMMIT_SHA"
    assets:
      links:
        - name: "$RELEASE_TARBALL"
          url: "$PUBLISH_URL/$RELEASE_TARBALL"
  tags:
    - aipcc

Now I need to add BUILD_MODE as an environment variable in both podman run commands. Let me add it to both places:

# This yaml file contains the CI jobs as an API that can be used by other repositories outside builder

spec:
  inputs:
    JOB_STAGE:
      default: build
      description: "Define the job stage that will run the bootstrap and onboard steps of wheel pipeline"
    JOB_PREFIX:
      default: ""
      description: "Define a prefix for the job name"
      type: string
    COLLECTION:
      description: "Define the collection name for which you want to build wheels"
      type: string
    VARIANT:
      description: "Define the variant for which you want to build wheels"
      options: ["cpu-ubi9", "cuda-ubi9", "rocm-ubi9", "spyre-ubi9", "tpu-ubi9"] # , "gaudi-ubi9"]
    ENABLE_REPEATABLE_BUILD_MODE:
      default: false
      description: "Setting which enables repeatable build mode"
      type: boolean
    BOOTSTRAP_MODE:
      description: "Setting for bootstrap mode: 'bootstrap --sdist-only', 'bootstrap --full-build', 'bootstrap-parallel'"
      options: ["sdist-only", "full", "full-parallel"]
      default: "sdist-only"
    BUILD_MODE:
      description: "Setting for build mode: 'parallel' uses build-parallel with graph file, 'serial' uses build-sequence with build order file"
      options: ["parallel", "serial"]
      default: "parallel"
    ARCH:
      default: "x86_64"
      description: "Define the CPU architecture to build wheels for"
      options: ["aarch64", "x86_64", "ppc64le"]
    BUILD_ON_ALL_PUSHES:
      default: false
      description: "Build for every merge, even if the collection has not changed."
      type: boolean
    ENABLE_NIGHTLY_BUILDS:
      default: false
      description: "Setting that enables nightly builds for a given collection"
      type: boolean
    ENABLE_TEST_JOBS:
      default: false
      description: "Setting that enables test build jobs for testing resolution and build of packages"
      type: boolean
---
# ======================================================================== VARIABLES ===============================================================
variables:
  # Set BUILDER_IMAGE_VERSION to some fake value which will be overridden by users when they invoke the API
  BUILDER_IMAGE_VERSION: v0.0
  WHEEL_SERVER_PROJECT_PREFIX: "${CI_PROJECT_NAMESPACE}/indexes"
  # Set PRODUCT_VERSION as a global variable. The default should look like a real value
  COLLECTION_VERSION: $PRODUCT_VERSION
  PRODUCT_VERSION: "0.0"
  # Used in the builder repo to let collections build multiple
  # versions of a package. Disabling constraints output also disables
  # release jobs.
  FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS: false
  # Set PRODUCT_NAME to rhoai. We need PRODUCT_NAME for customer facing package index hosted in PULP
  PRODUCT_NAME: "rhoai"

# =========================================================================== API BASE JOBS ===================================================================

# Base job for release variables
.$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job:
  variables:
    PUBLISH_AUTH_HEADER: "PRIVATE-TOKEN: ${BOT_PAT}"
    RELEASE_TARBALL: "wheels-${RELEASE_VERSION}.tar.gz"
    RELEASE_VERSION_SUFFIX: "+$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]"
    RELEASE_VERSION: "${PRODUCT_VERSION}.${CI_PIPELINE_IID}${RELEASE_VERSION_SUFFIX}"
    GITLAB_PACKAGE_URL: "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/generic/$[[ inputs.COLLECTION ]]-wheels"
    PUBLISH_URL: "${GITLAB_PACKAGE_URL}/${RELEASE_VERSION}"

# Base job for the api
.$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job
  image: registry.gitlab.com/redhat/rhel-ai/wheels/builder/podman-stable:v5.5.0
  timeout: 12h
  services:
  # No services section needed for pinp
  interruptible: true
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_PROTECTED == "true"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
    - if: $CI_PIPELINE_SOURCE == "push" && "$[[ inputs.BUILD_ON_ALL_PUSHES ]]" == "true" && $CI_COMMIT_REF_PROTECTED == "true"
    - if: '$CI_PIPELINE_SOURCE == "schedule" && "$[[ inputs.ENABLE_NIGHTLY_BUILDS ]]" == "true"'
  variables:
    FF_SCRIPT_SECTIONS: "true"
    COLLECTION: "$[[ inputs.COLLECTION ]]"
    VARIANT: "$[[ inputs.VARIANT ]]"
    ARCH: "$[[ inputs.ARCH ]]"
    IMAGE_BASE: ${CI_REGISTRY}/redhat/rhel-ai/wheels/builder/builder-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]
    IMAGE: ${IMAGE_BASE}:${BUILDER_IMAGE_VERSION}
    CONTAINERFILE: Containerfile.$[[ inputs.VARIANT ]]
    TOOL_SERVER_URL: "https://gitlab.com/api/v4/projects/61507476/packages/pypi/simple/"
    OUTDIR: /mnt
    JOB_OUTPUT_DIR: /builds/$CI_PROJECT_PATH/mnt
    WHEEL_SERVER_PROJECT_PATH: "${WHEEL_SERVER_PROJECT_PREFIX}/$[[ inputs.COLLECTION ]]-${PRODUCT_VERSION}/$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]"
    SDIST_SERVER_PROJECT_PATH: "redhat/rhel-ai/wheels/prefetch"
    RUN_CLEAN_AND_UPLOAD: "false"
    # These flags are not part of the formal API, but is used to
    # control the jobs in the builder repository.
    BOOTSTRAP_RUN_ONBOARD: "true"
    BUILD_ON_ALL_PUSHES: "$[[ inputs.BUILD_ON_ALL_PUSHES ]]"
    # We need to use non-standard BOOTSTRAP_MODE for some jobs in builder which are not triggered by API
    BOOTSTRAP_MODE: $[[ inputs.BOOTSTRAP_MODE ]]
    BUILD_MODE: $[[ inputs.BUILD_MODE ]]
  before_script:
    # Dump our settings to the log
    - env
    - dnf install -y which ncurses
    # https://docs.gitlab.com/ee/ci/docker/authenticate_registry.html
    - podman login $CI_REGISTRY --username $CI_REGISTRY_USER --password "$CI_REGISTRY_PASSWORD"
    # Install dependencies for downloading secure files
    - dnf install -y which curl bash
    # Share the test script with the container using a directory in /builds, following:
    # https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#known-issues-with-docker-in-docker
    - mkdir -p "${JOB_OUTPUT_DIR}"
    - cp -rv collections "${JOB_OUTPUT_DIR}/"
    # Generate .netrc dynamically and put in inside the container where we want it
    - echo -e "machine gitlab.com\nlogin platform-engineering-bot\npassword ${BOT_PAT}" > ${JOB_OUTPUT_DIR}/.netrc
    # Configure Podman storage
    - mkdir -p /etc/containers
    # create default overlay configuration. Embed storage.conf as HEREDOC.
    # pipelines in other projects cannot access files in builder repo.
    - |
      cat > /etc/containers/storage.conf << EOF
      [storage]
      driver = "overlay"
      runroot = "/var/run/containers/storage"
      graphroot = "/var/lib/containers/storage"
      [storage.options]
      mount_program = ""
      EOF
    - mkdir -p /var/run/containers/storage
    - mkdir -p /var/lib/containers/storage
    # AWS (may) have an existing storage configuration that works with dind but not
    # pinp.  This causes pinp to fail with
    #      "OSError: [Errno 107] Transport endpoint is not connected:
    # errors.  Remove the contents of these directories to re-initialize the overlay
    # storage.
    - rm -rf /var/lib/containers/storage/*
    - rm -rf /var/run/containers/storage/*
  script:
    - >
      podman run \
        -v "$JOB_OUTPUT_DIR:/mnt" \
        -v ".:/collection-repository" \
        -e "NETRC=/mnt/.netrc" \
        -e "OUTDIR=$OUTDIR" \
        -e "FROMAGER_VARIANT=$[[ inputs.VARIANT ]]" \
        -e "COLLECTION=$[[ inputs.COLLECTION ]]" \
        -e "PRODUCT_VERSION=$PRODUCT_VERSION" \
        -e "ENABLE_REPEATABLE_BUILD_MODE=$[[ inputs.ENABLE_REPEATABLE_BUILD_MODE ]]" \
        -e "BOOTSTRAP_MODE=$BOOTSTRAP_MODE" \
        -e "BUILD_MODE=$BUILD_MODE" \
        -e "WHEEL_SERVER_PROJECT_PATH=${WHEEL_SERVER_PROJECT_PATH}" \
        -e "SDIST_SERVER_PROJECT_PATH=${SDIST_SERVER_PROJECT_PATH}" \
        -e "PUBLISH_AUTH_HEADER=${PUBLISH_AUTH_HEADER}" \
        -e "RELEASE_VERSION=${RELEASE_VERSION}" \
        -e "RELEASE_VERSION_SUFFIX=${RELEASE_VERSION_SUFFIX}" \
        -e "RELEASE_TARBALL=${RELEASE_TARBALL}" \
        -e "PUBLISH_URL=${PUBLISH_URL}" \
        -e "GITLAB_PACKAGE_URL=${GITLAB_PACKAGE_URL}" \
        -e "RUN_CLEAN_AND_UPLOAD=${RUN_CLEAN_AND_UPLOAD}" \
        -e "BOT_PAT=${BOT_PAT}" \
        -e "BOT_USER=${BOT_USER}" \
        -e "BOOTSTRAP_RUN_ONBOARD=${BOOTSTRAP_RUN_ONBOARD}" \
        -e "REPOSITORY_URL=${CI_REPOSITORY_URL}" \
        -e "FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS=${FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS}" \
        -e "PRODUCT_NAME=$PRODUCT_NAME" \
        ${IMAGE} \
        ${API_SCRIPT}
    # Development command - will be removed eventually when we will have pulp upload script running in builder
    - >
      if [ -f ./bin/upload_to_pulp.sh ] && [[ "$CI_JOB_NAME" == *"build-wheels" ]]; then
        podman run \
          -v "$JOB_OUTPUT_DIR:/mnt" \
          -v ".:/collection-repository" \
          -e "NETRC=/mnt/.netrc" \
          -e "OUTDIR=$OUTDIR" \
          -e "FROMAGER_VARIANT=$[[ inputs.VARIANT ]]" \
          -e "COLLECTION=$[[ inputs.COLLECTION ]]" \
          -e "PRODUCT_VERSION=$PRODUCT_VERSION" \
          -e "ENABLE_REPEATABLE_BUILD_MODE=$[[ inputs.ENABLE_REPEATABLE_BUILD_MODE ]]" \
          -e "BOOTSTRAP_MODE=$BOOTSTRAP_MODE" \
          -e "WHEEL_SERVER_PROJECT_PATH=${WHEEL_SERVER_PROJECT_PATH}" \
          -e "SDIST_SERVER_PROJECT_PATH=${SDIST_SERVER_PROJECT_PATH}" \
          -e "PUBLISH_AUTH_HEADER=${PUBLISH_AUTH_HEADER}" \
          -e "RELEASE_VERSION=${RELEASE_VERSION}" \
          -e "RELEASE_VERSION_SUFFIX=${RELEASE_VERSION_SUFFIX}" \
          -e "RELEASE_TARBALL=${RELEASE_TARBALL}" \
          -e "PUBLISH_URL=${PUBLISH_URL}" \
          -e "GITLAB_PACKAGE_URL=${GITLAB_PACKAGE_URL}" \
          -e "RUN_CLEAN_AND_UPLOAD=${RUN_CLEAN_AND_UPLOAD}" \
          -e "BOT_PAT=${BOT_PAT}" \
          -e "BOT_USER=${BOT_USER}" \
          -e "BOOTSTRAP_RUN_ONBOARD=${BOOTSTRAP_RUN_ONBOARD}" \
          -e "REPOSITORY_URL=${CI_REPOSITORY_URL}" \
          -e "FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS=${FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS}" \
          -e "PULP_CERT_BASE64=${PULP_CERT_BASE64}" \
          -e "PULP_KEY_BASE64=${PULP_KEY_BASE64}" \
          -e "PRODUCT_NAME=$PRODUCT_NAME" \
          ${IMAGE} \
          /collection-repository/bin/upload_to_pulp.sh
      fi
  artifacts:
    paths:
      - $JOB_OUTPUT_DIR/*.log
      - $JOB_OUTPUT_DIR/computed-constraints.txt
      - $JOB_OUTPUT_DIR/computed-requirements.txt
      - $JOB_OUTPUT_DIR/work-dir/*/*.log
      - $JOB_OUTPUT_DIR/work-dir/logs/
      - $JOB_OUTPUT_DIR/work-dir/*.json
      - $JOB_OUTPUT_DIR/work-dir/constraints.txt
      - $JOB_OUTPUT_DIR/work-dir/build-sequence-summary.md
    when: always
  tags:
    - aipcc-large-$[[ inputs.ARCH ]]

# =========================================================== BOOTSTRAP AND ONBOARD API JOB ================================================================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/bootstrap_and_onboard.sh

# =========================================================== TEST BOOTSTRAP AND ONBOARD API JOB ================================================================================

test-$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $ENABLE_TEST_JOBS == "false"
      # Do not run the job if test jobs are turned off.
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/bootstrap_and_onboard.sh
    BOOTSTRAP_RUN_ONBOARD: "false"
    BOOTSTRAP_MODE: "full-parallel"
    ENABLE_TEST_JOBS: "$[[ inputs.ENABLE_TEST_JOBS ]]"

# ==================================== BUILD WHEEL SEQUENCE API JOB ==============================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-build-wheels:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/build_wheels.sh
    RUN_CLEAN_AND_UPLOAD: "true"
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard
      artifacts: true

# ==================================================== RELEASE API JOB ============================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-release-tarball:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/make_release_tarball.sh
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-build-wheels
      artifacts: true

# ============================================ PUBLISH API JOB ====================================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-publish-wheels:
  image: "registry.gitlab.com/gitlab-org/release-cli:latest"
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  interruptible: true
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: '$FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS == "true"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_PROTECTED == "true"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
    - if: '$CI_PIPELINE_SOURCE == "schedule" && "$[[ inputs.ENABLE_NIGHTLY_BUILDS ]]" == "true"'
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-release-tarball
      artifacts: true
  script:
    - echo "running publish job $CI_JOB_NAME for $RELEASE_VERSION and $[[ inputs.ARCH ]] arch"
  release:
    # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties
    tag_name: "$RELEASE_VERSION"
    description: /mnt/work-dir/build-sequence-summary.md
    ref: "$CI_COMMIT_SHA"
    assets:
      links:
        - name: "$RELEASE_TARBALL"
          url: "$PUBLISH_URL/$RELEASE_TARBALL"
  tags:
    - aipcc

Now I need to add it to the second podman run command as well:

# This yaml file contains the CI jobs as an API that can be used by other repositories outside builder

spec:
  inputs:
    JOB_STAGE:
      default: build
      description: "Define the job stage that will run the bootstrap and onboard steps of wheel pipeline"
    JOB_PREFIX:
      default: ""
      description: "Define a prefix for the job name"
      type: string
    COLLECTION:
      description: "Define the collection name for which you want to build wheels"
      type: string
    VARIANT:
      description: "Define the variant for which you want to build wheels"
      options: ["cpu-ubi9", "cuda-ubi9", "rocm-ubi9", "spyre-ubi9", "tpu-ubi9"] # , "gaudi-ubi9"]
    ENABLE_REPEATABLE_BUILD_MODE:
      default: false
      description: "Setting which enables repeatable build mode"
      type: boolean
    BOOTSTRAP_MODE:
      description: "Setting for bootstrap mode: 'bootstrap --sdist-only', 'bootstrap --full-build', 'bootstrap-parallel'"
      options: ["sdist-only", "full", "full-parallel"]
      default: "sdist-only"
    BUILD_MODE:
      description: "Setting for build mode: 'parallel' uses build-parallel with graph file, 'serial' uses build-sequence with build order file"
      options: ["parallel", "serial"]
      default: "parallel"
    ARCH:
      default: "x86_64"
      description: "Define the CPU architecture to build wheels for"
      options: ["aarch64", "x86_64", "ppc64le"]
    BUILD_ON_ALL_PUSHES:
      default: false
      description: "Build for every merge, even if the collection has not changed."
      type: boolean
    ENABLE_NIGHTLY_BUILDS:
      default: false
      description: "Setting that enables nightly builds for a given collection"
      type: boolean
    ENABLE_TEST_JOBS:
      default: false
      description: "Setting that enables test build jobs for testing resolution and build of packages"
      type: boolean
---
# ======================================================================== VARIABLES ===============================================================
variables:
  # Set BUILDER_IMAGE_VERSION to some fake value which will be overridden by users when they invoke the API
  BUILDER_IMAGE_VERSION: v0.0
  WHEEL_SERVER_PROJECT_PREFIX: "${CI_PROJECT_NAMESPACE}/indexes"
  # Set PRODUCT_VERSION as a global variable. The default should look like a real value
  COLLECTION_VERSION: $PRODUCT_VERSION
  PRODUCT_VERSION: "0.0"
  # Used in the builder repo to let collections build multiple
  # versions of a package. Disabling constraints output also disables
  # release jobs.
  FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS: false
  # Set PRODUCT_NAME to rhoai. We need PRODUCT_NAME for customer facing package index hosted in PULP
  PRODUCT_NAME: "rhoai"

# =========================================================================== API BASE JOBS ===================================================================

# Base job for release variables
.$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job:
  variables:
    PUBLISH_AUTH_HEADER: "PRIVATE-TOKEN: ${BOT_PAT}"
    RELEASE_TARBALL: "wheels-${RELEASE_VERSION}.tar.gz"
    RELEASE_VERSION_SUFFIX: "+$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]"
    RELEASE_VERSION: "${PRODUCT_VERSION}.${CI_PIPELINE_IID}${RELEASE_VERSION_SUFFIX}"
    GITLAB_PACKAGE_URL: "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/generic/$[[ inputs.COLLECTION ]]-wheels"
    PUBLISH_URL: "${GITLAB_PACKAGE_URL}/${RELEASE_VERSION}"

# Base job for the api
.$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job
  image: registry.gitlab.com/redhat/rhel-ai/wheels/builder/podman-stable:v5.5.0
  timeout: 12h
  services:
  # No services section needed for pinp
  interruptible: true
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_PROTECTED == "true"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
    - if: $CI_PIPELINE_SOURCE == "push" && "$[[ inputs.BUILD_ON_ALL_PUSHES ]]" == "true" && $CI_COMMIT_REF_PROTECTED == "true"
    - if: '$CI_PIPELINE_SOURCE == "schedule" && "$[[ inputs.ENABLE_NIGHTLY_BUILDS ]]" == "true"'
  variables:
    FF_SCRIPT_SECTIONS: "true"
    COLLECTION: "$[[ inputs.COLLECTION ]]"
    VARIANT: "$[[ inputs.VARIANT ]]"
    ARCH: "$[[ inputs.ARCH ]]"
    IMAGE_BASE: ${CI_REGISTRY}/redhat/rhel-ai/wheels/builder/builder-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]
    IMAGE: ${IMAGE_BASE}:${BUILDER_IMAGE_VERSION}
    CONTAINERFILE: Containerfile.$[[ inputs.VARIANT ]]
    TOOL_SERVER_URL: "https://gitlab.com/api/v4/projects/61507476/packages/pypi/simple/"
    OUTDIR: /mnt
    JOB_OUTPUT_DIR: /builds/$CI_PROJECT_PATH/mnt
    WHEEL_SERVER_PROJECT_PATH: "${WHEEL_SERVER_PROJECT_PREFIX}/$[[ inputs.COLLECTION ]]-${PRODUCT_VERSION}/$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]"
    SDIST_SERVER_PROJECT_PATH: "redhat/rhel-ai/wheels/prefetch"
    RUN_CLEAN_AND_UPLOAD: "false"
    # These flags are not part of the formal API, but is used to
    # control the jobs in the builder repository.
    BOOTSTRAP_RUN_ONBOARD: "true"
    BUILD_ON_ALL_PUSHES: "$[[ inputs.BUILD_ON_ALL_PUSHES ]]"
    # We need to use non-standard BOOTSTRAP_MODE for some jobs in builder which are not triggered by API
    BOOTSTRAP_MODE: $[[ inputs.BOOTSTRAP_MODE ]]
    BUILD_MODE: $[[ inputs.BUILD_MODE ]]
  before_script:
    # Dump our settings to the log
    - env
    - dnf install -y which ncurses
    # https://docs.gitlab.com/ee/ci/docker/authenticate_registry.html
    - podman login $CI_REGISTRY --username $CI_REGISTRY_USER --password "$CI_REGISTRY_PASSWORD"
    # Install dependencies for downloading secure files
    - dnf install -y which curl bash
    # Share the test script with the container using a directory in /builds, following:
    # https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#known-issues-with-docker-in-docker
    - mkdir -p "${JOB_OUTPUT_DIR}"
    - cp -rv collections "${JOB_OUTPUT_DIR}/"
    # Generate .netrc dynamically and put in inside the container where we want it
    - echo -e "machine gitlab.com\nlogin platform-engineering-bot\npassword ${BOT_PAT}" > ${JOB_OUTPUT_DIR}/.netrc
    # Configure Podman storage
    - mkdir -p /etc/containers
    # create default overlay configuration. Embed storage.conf as HEREDOC.
    # pipelines in other projects cannot access files in builder repo.
    - |
      cat > /etc/containers/storage.conf << EOF
      [storage]
      driver = "overlay"
      runroot = "/var/run/containers/storage"
      graphroot = "/var/lib/containers/storage"
      [storage.options]
      mount_program = ""
      EOF
    - mkdir -p /var/run/containers/storage
    - mkdir -p /var/lib/containers/storage
    # AWS (may) have an existing storage configuration that works with dind but not
    # pinp.  This causes pinp to fail with
    #      "OSError: [Errno 107] Transport endpoint is not connected:
    # errors.  Remove the contents of these directories to re-initialize the overlay
    # storage.
    - rm -rf /var/lib/containers/storage/*
    - rm -rf /var/run/containers/storage/*
  script:
    - >
      podman run \
        -v "$JOB_OUTPUT_DIR:/mnt" \
        -v ".:/collection-repository" \
        -e "NETRC=/mnt/.netrc" \
        -e "OUTDIR=$OUTDIR" \
        -e "FROMAGER_VARIANT=$[[ inputs.VARIANT ]]" \
        -e "COLLECTION=$[[ inputs.COLLECTION ]]" \
        -e "PRODUCT_VERSION=$PRODUCT_VERSION" \
        -e "ENABLE_REPEATABLE_BUILD_MODE=$[[ inputs.ENABLE_REPEATABLE_BUILD_MODE ]]" \
        -e "BOOTSTRAP_MODE=$BOOTSTRAP_MODE" \
        -e "BUILD_MODE=$BUILD_MODE" \
        -e "WHEEL_SERVER_PROJECT_PATH=${WHEEL_SERVER_PROJECT_PATH}" \
        -e "SDIST_SERVER_PROJECT_PATH=${SDIST_SERVER_PROJECT_PATH}" \
        -e "PUBLISH_AUTH_HEADER=${PUBLISH_AUTH_HEADER}" \
        -e "RELEASE_VERSION=${RELEASE_VERSION}" \
        -e "RELEASE_VERSION_SUFFIX=${RELEASE_VERSION_SUFFIX}" \
        -e "RELEASE_TARBALL=${RELEASE_TARBALL}" \
        -e "PUBLISH_URL=${PUBLISH_URL}" \
        -e "GITLAB_PACKAGE_URL=${GITLAB_PACKAGE_URL}" \
        -e "RUN_CLEAN_AND_UPLOAD=${RUN_CLEAN_AND_UPLOAD}" \
        -e "BOT_PAT=${BOT_PAT}" \
        -e "BOT_USER=${BOT_USER}" \
        -e "BOOTSTRAP_RUN_ONBOARD=${BOOTSTRAP_RUN_ONBOARD}" \
        -e "REPOSITORY_URL=${CI_REPOSITORY_URL}" \
        -e "FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS=${FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS}" \
        -e "PRODUCT_NAME=$PRODUCT_NAME" \
        ${IMAGE} \
        ${API_SCRIPT}
    # Development command - will be removed eventually when we will have pulp upload script running in builder
    - >
      if [ -f ./bin/upload_to_pulp.sh ] && [[ "$CI_JOB_NAME" == *"build-wheels" ]]; then
        podman run \
          -v "$JOB_OUTPUT_DIR:/mnt" \
          -v ".:/collection-repository" \
          -e "NETRC=/mnt/.netrc" \
          -e "OUTDIR=$OUTDIR" \
          -e "FROMAGER_VARIANT=$[[ inputs.VARIANT ]]" \
          -e "COLLECTION=$[[ inputs.COLLECTION ]]" \
          -e "PRODUCT_VERSION=$PRODUCT_VERSION" \
          -e "ENABLE_REPEATABLE_BUILD_MODE=$[[ inputs.ENABLE_REPEATABLE_BUILD_MODE ]]" \
          -e "BOOTSTRAP_MODE=$BOOTSTRAP_MODE" \
          -e "BUILD_MODE=$BUILD_MODE" \
          -e "WHEEL_SERVER_PROJECT_PATH=${WHEEL_SERVER_PROJECT_PATH}" \
          -e "SDIST_SERVER_PROJECT_PATH=${SDIST_SERVER_PROJECT_PATH}" \
          -e "PUBLISH_AUTH_HEADER=${PUBLISH_AUTH_HEADER}" \
          -e "RELEASE_VERSION=${RELEASE_VERSION}" \
          -e "RELEASE_VERSION_SUFFIX=${RELEASE_VERSION_SUFFIX}" \
          -e "RELEASE_TARBALL=${RELEASE_TARBALL}" \
          -e "PUBLISH_URL=${PUBLISH_URL}" \
          -e "GITLAB_PACKAGE_URL=${GITLAB_PACKAGE_URL}" \
          -e "RUN_CLEAN_AND_UPLOAD=${RUN_CLEAN_AND_UPLOAD}" \
          -e "BOT_PAT=${BOT_PAT}" \
          -e "BOT_USER=${BOT_USER}" \
          -e "BOOTSTRAP_RUN_ONBOARD=${BOOTSTRAP_RUN_ONBOARD}" \
          -e "REPOSITORY_URL=${CI_REPOSITORY_URL}" \
          -e "FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS=${FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS}" \
          -e "PULP_CERT_BASE64=${PULP_CERT_BASE64}" \
          -e "PULP_KEY_BASE64=${PULP_KEY_BASE64}" \
          -e "PRODUCT_NAME=$PRODUCT_NAME" \
          ${IMAGE} \
          /collection-repository/bin/upload_to_pulp.sh
      fi
  artifacts:
    paths:
      - $JOB_OUTPUT_DIR/*.log
      - $JOB_OUTPUT_DIR/computed-constraints.txt
      - $JOB_OUTPUT_DIR/computed-requirements.txt
      - $JOB_OUTPUT_DIR/work-dir/*/*.log
      - $JOB_OUTPUT_DIR/work-dir/logs/
      - $JOB_OUTPUT_DIR/work-dir/*.json
      - $JOB_OUTPUT_DIR/work-dir/constraints.txt
      - $JOB_OUTPUT_DIR/work-dir/build-sequence-summary.md
    when: always
  tags:
    - aipcc-large-$[[ inputs.ARCH ]]

# =========================================================== BOOTSTRAP AND ONBOARD API JOB ================================================================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/bootstrap_and_onboard.sh

# =========================================================== TEST BOOTSTRAP AND ONBOARD API JOB ================================================================================

test-$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $ENABLE_TEST_JOBS == "false"
      # Do not run the job if test jobs are turned off.
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/bootstrap_and_onboard.sh
    BOOTSTRAP_RUN_ONBOARD: "false"
    BOOTSTRAP_MODE: "full-parallel"
    ENABLE_TEST_JOBS: "$[[ inputs.ENABLE_TEST_JOBS ]]"

# ==================================== BUILD WHEEL SEQUENCE API JOB ==============================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-build-wheels:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/build_wheels.sh
    RUN_CLEAN_AND_UPLOAD: "true"
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-bootstrap-and-onboard
      artifacts: true

# ==================================================== RELEASE API JOB ============================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-release-tarball:
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-api-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  variables:
    API_SCRIPT: /mirror-builder/pipeline-api/make_release_tarball.sh
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-build-wheels
      artifacts: true

# ============================================ PUBLISH API JOB ====================================================

$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-publish-wheels:
  image: "registry.gitlab.com/gitlab-org/release-cli:latest"
  extends:
    - .$[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-wheel-pipeline-release-variables-base-job
  stage: $[[ inputs.JOB_STAGE ]]
  interruptible: true
  rules:
    - if: '$CI_PROJECT_ROOT_NAMESPACE != "redhat"'
      when: never
    - if: '$FROMAGER_BOOTSTRAP_SKIP_CONSTRAINTS == "true"'
      when: never
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_PROTECTED == "true"
      changes:
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/requirements.txt
        - collections/$[[ inputs.COLLECTION ]]/$[[ inputs.VARIANT ]]/constraints.txt
        - builder-image-version.yml
    - if: '$CI_PIPELINE_SOURCE == "schedule" && "$[[ inputs.ENABLE_NIGHTLY_BUILDS ]]" == "true"'
  needs:
    - job: $[[ inputs.JOB_PREFIX ]]$[[ inputs.COLLECTION ]]-$[[ inputs.VARIANT ]]-$[[ inputs.ARCH ]]-release-tarball
      artifacts: true
  script:
    - echo "running publish job $CI_JOB_NAME for $RELEASE_VERSION and $[[ inputs.ARCH ]] arch"
  release:
    # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties
    tag_name: "$RELEASE_VERSION"
    description: /mnt/work-dir/build-sequence-summary.md
    ref: "$CI_COMMIT_SHA"
    assets:
      links:
        - name: "$RELEASE_TARBALL"
          url: "$PUBLISH_URL/$RELEASE_TARBALL"
  tags:
    - aipcc

Now I need to update the build_wheels.sh script to handle the BUILD_MODE variable. Looking at the current script, I can see it has commented-out lines for both build-parallel and build-sequence. I need to modify it to use BUILD_MODE to decide which command to run:

#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# API script for running build-sequence in a pipeline

# Dump our settings to the log
env

if [ -z "$WHEEL_SERVER_PROJECT_PATH" ]; then
    echo "wheel server project path is not set"
    exit 1
fi

set -x
set -e
set -o pipefail
set -u

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck disable=SC1091
source "$SCRIPTDIR/prepare_constraints.sh"

if [ -z "$FROMAGER_VARIANT" ]; then
    echo "fromager variant is not set"
    exit 1
fi

if [ -z "$COLLECTION" ]; then
    echo "collection is not set"
    exit 1
fi

OUTDIR=${OUTDIR:-.}

# Use provided constraints file if set, otherwise compute constraints
if [ -z "${CONSTRAINTS:-}" ]; then
    CONSTRAINTS="$OUTDIR/computed-constraints.txt"
    prepare_constraints "$FROMAGER_VARIANT" "$COLLECTION" "$CONSTRAINTS"
else
    echo "Using provided constraints file: $CONSTRAINTS"
fi

GRAPH_FILE="$OUTDIR/work-dir/graph.json"
BUILD_ORDER_FILE="$OUTDIR/work-dir/build-order.json"

# Set default build mode if not provided
BUILD_MODE=${BUILD_MODE:-parallel}

# Compute wheel server url from wheel server project path using wheel project id
WHEEL_PROJECT_ID=$(get-project-id "$WHEEL_SERVER_PROJECT_PATH" | tail -1)
export WHEEL_PROJECT_ID
export PYPI_URL_BASE="https://gitlab.com/api/v4/projects/${WHEEL_PROJECT_ID}/packages/pypi/"
export WHEEL_SERVER_URL="${PYPI_URL_BASE}/simple/"

# Write a pypirc file for the uploader plugin to use with twine.
export TWINE_CONFIG_FILE=/tmp/.pypirc
if [ -n "${RUN_CLEAN_AND_UPLOAD:-}" ]; then
    INDEX_NAME=gitlab-${FROMAGER_VARIANT}-wheels
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
index-servers = ${INDEX_NAME}
[${INDEX_NAME}]
repository = ${PYPI_URL_BASE}
username = ${BOT_USER}
password = ${BOT_PAT}
EOF
else
    # Create empty pypirc file when not uploading
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
EOF
fi

# Set up nginx web server using the reusable functions
# shellcheck disable=SC1091
source "$SCRIPTDIR/nginx_server.sh"
start_nginx_server "$OUTDIR"

fromager \
  --constraints-file "$CONSTRAINTS" \
  --error-log-file="$OUTDIR/errors.log" \
  --log-file="$OUTDIR/build-sequence.log" \
  --sdists-repo="$OUTDIR/sdists-repo" \
  --wheels-repo="$OUTDIR/wheels-repo" \
  --work-dir="$OUTDIR/work-dir" \
  --build-wheel-server-url="http://localhost:8080/simple/" \
  build-sequence --cache-wheel-server-url="$WHEEL_SERVER_URL" "$BUILD_ORDER_FILE"

# build-parallel --cache-wheel-server-url="$WHEEL_SERVER_URL" "$GRAPH_FILE"

Now I need to replace the current fromager command with conditional logic based on BUILD_MODE:

#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# API script for running build-sequence in a pipeline

# Dump our settings to the log
env

if [ -z "$WHEEL_SERVER_PROJECT_PATH" ]; then
    echo "wheel server project path is not set"
    exit 1
fi

set -x
set -e
set -o pipefail
set -u

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck disable=SC1091
source "$SCRIPTDIR/prepare_constraints.sh"

if [ -z "$FROMAGER_VARIANT" ]; then
    echo "fromager variant is not set"
    exit 1
fi

if [ -z "$COLLECTION" ]; then
    echo "collection is not set"
    exit 1
fi

OUTDIR=${OUTDIR:-.}

# Use provided constraints file if set, otherwise compute constraints
if [ -z "${CONSTRAINTS:-}" ]; then
    CONSTRAINTS="$OUTDIR/computed-constraints.txt"
    prepare_constraints "$FROMAGER_VARIANT" "$COLLECTION" "$CONSTRAINTS"
else
    echo "Using provided constraints file: $CONSTRAINTS"
fi

GRAPH_FILE="$OUTDIR/work-dir/graph.json"
BUILD_ORDER_FILE="$OUTDIR/work-dir/build-order.json"

# Set default build mode if not provided
BUILD_MODE=${BUILD_MODE:-parallel}

# Compute wheel server url from wheel server project path using wheel project id
WHEEL_PROJECT_ID=$(get-project-id "$WHEEL_SERVER_PROJECT_PATH" | tail -1)
export WHEEL_PROJECT_ID
export PYPI_URL_BASE="https://gitlab.com/api/v4/projects/${WHEEL_PROJECT_ID}/packages/pypi/"
export WHEEL_SERVER_URL="${PYPI_URL_BASE}/simple/"

# Write a pypirc file for the uploader plugin to use with twine.
export TWINE_CONFIG_FILE=/tmp/.pypirc
if [ -n "${RUN_CLEAN_AND_UPLOAD:-}" ]; then
    INDEX_NAME=gitlab-${FROMAGER_VARIANT}-wheels
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
index-servers = ${INDEX_NAME}
[${INDEX_NAME}]
repository = ${PYPI_URL_BASE}
username = ${BOT_USER}
password = ${BOT_PAT}
EOF
else
    # Create empty pypirc file when not uploading
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
EOF
fi

# Set up nginx web server using the reusable functions
# shellcheck disable=SC1091
source "$SCRIPTDIR/nginx_server.sh"
start_nginx_server "$OUTDIR"

# Run fromager command based on build mode
if [ "$BUILD_MODE" = "serial" ]; then
  echo "Running fromager in serial mode using build-sequence command"
  fromager \
    --constraints-file "$CONSTRAINTS" \
    --error-log-file="$OUTDIR/errors.log" \
    --log-file="$OUTDIR/build-sequence.log" \
    --sdists-repo="$OUTDIR/sdists-repo" \
    --wheels-repo="$OUTDIR/wheels-repo" \
    --work-dir="$OUTDIR/work-dir" \
    --build-wheel-server-url="http://localhost:8080/simple/" \
    build-sequence --cache-wheel-server-url="$WHEEL_SERVER_URL" "$BUILD_ORDER_FILE"
else
  echo "Running fromager in parallel mode using build-parallel command"
  fromager \
    --constraints-file "$CONSTRAINTS" \
    --error-log-file="$OUTDIR/errors.log" \
    --log-file="$OUTDIR/build-parallel.log" \
    --sdists-repo="$OUTDIR/sdists-repo" \
    --wheels-repo="$OUTDIR/wheels-repo" \
    --work-dir="$OUTDIR/work-dir" \
    --build-wheel-server-url="http://localhost:8080/simple/" \
    build-parallel --cache-wheel-server-url="$WHEEL_SERVER_URL" "$GRAPH_FILE"
fi

Now let me check for any linting issues in the files I modified:

Perfect! Let me also run a quick test to make sure the build script logic works correctly:


User

The only difference in the fromager commands for the mode are the use of build-sequence vs. build-parallel and the final argument providing the input file. Move the conditional with the mode check to a point before fromager is called, set some variables for the values that vary, and reform the fromager command using those variables.


Cursor

You're absolutely right! That's a much cleaner approach. Let me refactor the script to set variables for the differing parts and use a single fromager command.

#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# API script for running build-sequence in a pipeline

# Dump our settings to the log
env

if [ -z "$WHEEL_SERVER_PROJECT_PATH" ]; then
    echo "wheel server project path is not set"
    exit 1
fi

set -x
set -e
set -o pipefail
set -u

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck disable=SC1091
source "$SCRIPTDIR/prepare_constraints.sh"

if [ -z "$FROMAGER_VARIANT" ]; then
    echo "fromager variant is not set"
    exit 1
fi

if [ -z "$COLLECTION" ]; then
    echo "collection is not set"
    exit 1
fi

OUTDIR=${OUTDIR:-.}

# Use provided constraints file if set, otherwise compute constraints
if [ -z "${CONSTRAINTS:-}" ]; then
    CONSTRAINTS="$OUTDIR/computed-constraints.txt"
    prepare_constraints "$FROMAGER_VARIANT" "$COLLECTION" "$CONSTRAINTS"
else
    echo "Using provided constraints file: $CONSTRAINTS"
fi

GRAPH_FILE="$OUTDIR/work-dir/graph.json"
BUILD_ORDER_FILE="$OUTDIR/work-dir/build-order.json"

# Set default build mode if not provided
BUILD_MODE=${BUILD_MODE:-parallel}

# Compute wheel server url from wheel server project path using wheel project id
WHEEL_PROJECT_ID=$(get-project-id "$WHEEL_SERVER_PROJECT_PATH" | tail -1)
export WHEEL_PROJECT_ID
export PYPI_URL_BASE="https://gitlab.com/api/v4/projects/${WHEEL_PROJECT_ID}/packages/pypi/"
export WHEEL_SERVER_URL="${PYPI_URL_BASE}/simple/"

# Write a pypirc file for the uploader plugin to use with twine.
export TWINE_CONFIG_FILE=/tmp/.pypirc
if [ -n "${RUN_CLEAN_AND_UPLOAD:-}" ]; then
    INDEX_NAME=gitlab-${FROMAGER_VARIANT}-wheels
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
index-servers = ${INDEX_NAME}
[${INDEX_NAME}]
repository = ${PYPI_URL_BASE}
username = ${BOT_USER}
password = ${BOT_PAT}
EOF
else
    # Create empty pypirc file when not uploading
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
EOF
fi

# Set up nginx web server using the reusable functions
# shellcheck disable=SC1091
source "$SCRIPTDIR/nginx_server.sh"
start_nginx_server "$OUTDIR"

# Set fromager command variables based on build mode
if [ "$BUILD_MODE" = "serial" ]; then
  echo "Running fromager in serial mode using build-sequence command"
  FROMAGER_COMMAND="build-sequence"
  LOG_FILE="$OUTDIR/build-sequence.log"
  INPUT_FILE="$BUILD_ORDER_FILE"
else
  echo "Running fromager in parallel mode using build-parallel command"
  FROMAGER_COMMAND="build-parallel"
  LOG_FILE="$OUTDIR/build-parallel.log"
  INPUT_FILE="$GRAPH_FILE"
fi

fromager \
  --constraints-file "$CONSTRAINTS" \
  --error-log-file="$OUTDIR/errors.log" \
  --log-file="$LOG_FILE" \
  --sdists-repo="$OUTDIR/sdists-repo" \
  --wheels-repo="$OUTDIR/wheels-repo" \
  --work-dir="$OUTDIR/work-dir" \
  --build-wheel-server-url="http://localhost:8080/simple/" \
  "$FROMAGER_COMMAND" --cache-wheel-server-url="$WHEEL_SERVER_URL" "$INPUT_FILE"

Perfect! Now the script is much cleaner and more maintainable. The changes I've implemented are:

Summary of Changes

  1. Added BUILD_MODE input to ci-wheelhouse.yml:

    • New enum input with options "parallel" and "serial"
    • Default value set to "parallel"
  2. Added BUILD_MODE as a job variable in the base job configuration

  3. Added BUILD_MODE as an environment variable in both podman run commands so it gets passed to the container

  4. Updated build_wheels.sh script to:

    • Set a default value of "parallel" if BUILD_MODE is not provided
    • Use conditional logic to set three variables based on the build mode:
      • FROMAGER_COMMAND: either "build-sequence" or "build-parallel"
      • LOG_FILE: either "build-sequence.log" or "build-parallel.log"
      • INPUT_FILE: either "$BUILD_ORDER_FILE" or "$GRAPH_FILE"
    • Use a single fromager command that references these variables

The implementation follows the same pattern as the existing BOOTSTRAP_MODE input and provides a clean way to switch between serial and parallel build modes. When BUILD_MODE is "serial", it uses the build-sequence command with the build order file. When BUILD_MODE is "parallel" (the default), it uses the build-parallel command with the graph file.


User

Update the log file so it is always just $OUTDIR/build.log


Cursor

#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# API script for running build-sequence in a pipeline

# Dump our settings to the log
env

if [ -z "$WHEEL_SERVER_PROJECT_PATH" ]; then
    echo "wheel server project path is not set"
    exit 1
fi

set -x
set -e
set -o pipefail
set -u

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck disable=SC1091
source "$SCRIPTDIR/prepare_constraints.sh"

if [ -z "$FROMAGER_VARIANT" ]; then
    echo "fromager variant is not set"
    exit 1
fi

if [ -z "$COLLECTION" ]; then
    echo "collection is not set"
    exit 1
fi

OUTDIR=${OUTDIR:-.}

# Use provided constraints file if set, otherwise compute constraints
if [ -z "${CONSTRAINTS:-}" ]; then
    CONSTRAINTS="$OUTDIR/computed-constraints.txt"
    prepare_constraints "$FROMAGER_VARIANT" "$COLLECTION" "$CONSTRAINTS"
else
    echo "Using provided constraints file: $CONSTRAINTS"
fi

GRAPH_FILE="$OUTDIR/work-dir/graph.json"
BUILD_ORDER_FILE="$OUTDIR/work-dir/build-order.json"

# Set default build mode if not provided
BUILD_MODE=${BUILD_MODE:-parallel}

# Compute wheel server url from wheel server project path using wheel project id
WHEEL_PROJECT_ID=$(get-project-id "$WHEEL_SERVER_PROJECT_PATH" | tail -1)
export WHEEL_PROJECT_ID
export PYPI_URL_BASE="https://gitlab.com/api/v4/projects/${WHEEL_PROJECT_ID}/packages/pypi/"
export WHEEL_SERVER_URL="${PYPI_URL_BASE}/simple/"

# Write a pypirc file for the uploader plugin to use with twine.
export TWINE_CONFIG_FILE=/tmp/.pypirc
if [ -n "${RUN_CLEAN_AND_UPLOAD:-}" ]; then
    INDEX_NAME=gitlab-${FROMAGER_VARIANT}-wheels
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
index-servers = ${INDEX_NAME}
[${INDEX_NAME}]
repository = ${PYPI_URL_BASE}
username = ${BOT_USER}
password = ${BOT_PAT}
EOF
else
    # Create empty pypirc file when not uploading
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
EOF
fi

# Set up nginx web server using the reusable functions
# shellcheck disable=SC1091
source "$SCRIPTDIR/nginx_server.sh"
start_nginx_server "$OUTDIR"

# Set fromager command variables based on build mode
if [ "$BUILD_MODE" = "serial" ]; then
  echo "Running fromager in serial mode using build-sequence command"
  FROMAGER_COMMAND="build-sequence"
  INPUT_FILE="$BUILD_ORDER_FILE"
else
  echo "Running fromager in parallel mode using build-parallel command"
  FROMAGER_COMMAND="build-parallel"
  INPUT_FILE="$GRAPH_FILE"
fi

LOG_FILE="$OUTDIR/build.log"

fromager \
  --constraints-file "$CONSTRAINTS" \
  --error-log-file="$OUTDIR/errors.log" \
  --log-file="$LOG_FILE" \
  --sdists-repo="$OUTDIR/sdists-repo" \
  --wheels-repo="$OUTDIR/wheels-repo" \
  --work-dir="$OUTDIR/work-dir" \
  --build-wheel-server-url="http://localhost:8080/simple/" \
  "$FROMAGER_COMMAND" --cache-wheel-server-url="$WHEEL_SERVER_URL" "$INPUT_FILE"

Perfect! I've updated the script so that the log file is always $OUTDIR/build.log regardless of the build mode. This simplifies the logic and provides a consistent log file name for both serial and parallel builds.


User

There is no need to set separate variables for the graph and build order file at the top of the script, move those definitions to the new variable for the input file.


Cursor

You're absolutely right! Since we're only using one of those files at a time based on the build mode, we can define them directly in the conditional logic. Let me make that change:

#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# API script for running build-sequence in a pipeline

# Dump our settings to the log
env

if [ -z "$WHEEL_SERVER_PROJECT_PATH" ]; then
    echo "wheel server project path is not set"
    exit 1
fi

set -x
set -e
set -o pipefail
set -u

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck disable=SC1091
source "$SCRIPTDIR/prepare_constraints.sh"

if [ -z "$FROMAGER_VARIANT" ]; then
    echo "fromager variant is not set"
    exit 1
fi

if [ -z "$COLLECTION" ]; then
    echo "collection is not set"
    exit 1
fi

OUTDIR=${OUTDIR:-.}

# Use provided constraints file if set, otherwise compute constraints
if [ -z "${CONSTRAINTS:-}" ]; then
    CONSTRAINTS="$OUTDIR/computed-constraints.txt"
    prepare_constraints "$FROMAGER_VARIANT" "$COLLECTION" "$CONSTRAINTS"
else
    echo "Using provided constraints file: $CONSTRAINTS"
fi

# Set default build mode if not provided
BUILD_MODE=${BUILD_MODE:-parallel}

# Compute wheel server url from wheel server project path using wheel project id
WHEEL_PROJECT_ID=$(get-project-id "$WHEEL_SERVER_PROJECT_PATH" | tail -1)
export WHEEL_PROJECT_ID
export PYPI_URL_BASE="https://gitlab.com/api/v4/projects/${WHEEL_PROJECT_ID}/packages/pypi/"
export WHEEL_SERVER_URL="${PYPI_URL_BASE}/simple/"

# Write a pypirc file for the uploader plugin to use with twine.
export TWINE_CONFIG_FILE=/tmp/.pypirc
if [ -n "${RUN_CLEAN_AND_UPLOAD:-}" ]; then
    INDEX_NAME=gitlab-${FROMAGER_VARIANT}-wheels
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
index-servers = ${INDEX_NAME}
[${INDEX_NAME}]
repository = ${PYPI_URL_BASE}
username = ${BOT_USER}
password = ${BOT_PAT}
EOF
else
    # Create empty pypirc file when not uploading
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
EOF
fi

# Set up nginx web server using the reusable functions
# shellcheck disable=SC1091
source "$SCRIPTDIR/nginx_server.sh"
start_nginx_server "$OUTDIR"

# Set fromager command variables based on build mode
if [ "$BUILD_MODE" = "serial" ]; then
  echo "Running fromager in serial mode using build-sequence command"
  FROMAGER_COMMAND="build-sequence"
  INPUT_FILE="$BUILD_ORDER_FILE"
else
  echo "Running fromager in parallel mode using build-parallel command"
  FROMAGER_COMMAND="build-parallel"
  INPUT_FILE="$GRAPH_FILE"
fi

LOG_FILE="$OUTDIR/build.log"

fromager \
  --constraints-file "$CONSTRAINTS" \
  --error-log-file="$OUTDIR/errors.log" \
  --log-file="$LOG_FILE" \
  --sdists-repo="$OUTDIR/sdists-repo" \
  --wheels-repo="$OUTDIR/wheels-repo" \
  --work-dir="$OUTDIR/work-dir" \
  --build-wheel-server-url="http://localhost:8080/simple/" \
  "$FROMAGER_COMMAND" --cache-wheel-server-url="$WHEEL_SERVER_URL" "$INPUT_FILE"

#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# API script for running build-sequence in a pipeline

# Dump our settings to the log
env

if [ -z "$WHEEL_SERVER_PROJECT_PATH" ]; then
    echo "wheel server project path is not set"
    exit 1
fi

set -x
set -e
set -o pipefail
set -u

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck disable=SC1091
source "$SCRIPTDIR/prepare_constraints.sh"

if [ -z "$FROMAGER_VARIANT" ]; then
    echo "fromager variant is not set"
    exit 1
fi

if [ -z "$COLLECTION" ]; then
    echo "collection is not set"
    exit 1
fi

OUTDIR=${OUTDIR:-.}

# Use provided constraints file if set, otherwise compute constraints
if [ -z "${CONSTRAINTS:-}" ]; then
    CONSTRAINTS="$OUTDIR/computed-constraints.txt"
    prepare_constraints "$FROMAGER_VARIANT" "$COLLECTION" "$CONSTRAINTS"
else
    echo "Using provided constraints file: $CONSTRAINTS"
fi

# Set default build mode if not provided
BUILD_MODE=${BUILD_MODE:-parallel}

# Compute wheel server url from wheel server project path using wheel project id
WHEEL_PROJECT_ID=$(get-project-id "$WHEEL_SERVER_PROJECT_PATH" | tail -1)
export WHEEL_PROJECT_ID
export PYPI_URL_BASE="https://gitlab.com/api/v4/projects/${WHEEL_PROJECT_ID}/packages/pypi/"
export WHEEL_SERVER_URL="${PYPI_URL_BASE}/simple/"

# Write a pypirc file for the uploader plugin to use with twine.
export TWINE_CONFIG_FILE=/tmp/.pypirc
if [ -n "${RUN_CLEAN_AND_UPLOAD:-}" ]; then
    INDEX_NAME=gitlab-${FROMAGER_VARIANT}-wheels
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
index-servers = ${INDEX_NAME}
[${INDEX_NAME}]
repository = ${PYPI_URL_BASE}
username = ${BOT_USER}
password = ${BOT_PAT}
EOF
else
    # Create empty pypirc file when not uploading
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
EOF
fi

# Set up nginx web server using the reusable functions
# shellcheck disable=SC1091
source "$SCRIPTDIR/nginx_server.sh"
start_nginx_server "$OUTDIR"

# Set fromager command variables based on build mode
if [ "$BUILD_MODE" = "serial" ]; then
  echo "Running fromager in serial mode using build-sequence command"
  FROMAGER_COMMAND="build-sequence"
  INPUT_FILE="$OUTDIR/work-dir/build-order.json"
else
  echo "Running fromager in parallel mode using build-parallel command"
  FROMAGER_COMMAND="build-parallel"
  INPUT_FILE="$OUTDIR/work-dir/graph.json"
fi

LOG_FILE="$OUTDIR/build.log"

fromager \
  --constraints-file "$CONSTRAINTS" \
  --error-log-file="$OUTDIR/errors.log" \
  --log-file="$LOG_FILE" \
  --sdists-repo="$OUTDIR/sdists-repo" \
  --wheels-repo="$OUTDIR/wheels-repo" \
  --work-dir="$OUTDIR/work-dir" \
  --build-wheel-server-url="http://localhost:8080/simple/" \
  "$FROMAGER_COMMAND" --cache-wheel-server-url="$WHEEL_SERVER_URL" "$INPUT_FILE"

Perfect! I've cleaned up the script by:

  1. Removing the separate GRAPH_FILE and BUILD_ORDER_FILE variable definitions at the top
  2. Moving those file path definitions directly into the conditional logic where INPUT_FILE is set

This makes the code more concise and clearer, as the file paths are only defined when they're actually needed based on the build mode.


User

Use a case statement to examine the build mode. If the mode is unknown report an error and exit


Cursor

Great suggestion! Using a case statement will make the code more robust and handle unknown build modes properly. Let me update the conditional logic:

#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# API script for running build-sequence in a pipeline

# Dump our settings to the log
env

if [ -z "$WHEEL_SERVER_PROJECT_PATH" ]; then
    echo "wheel server project path is not set"
    exit 1
fi

set -x
set -e
set -o pipefail
set -u

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck disable=SC1091
source "$SCRIPTDIR/prepare_constraints.sh"

if [ -z "$FROMAGER_VARIANT" ]; then
    echo "fromager variant is not set"
    exit 1
fi

if [ -z "$COLLECTION" ]; then
    echo "collection is not set"
    exit 1
fi

OUTDIR=${OUTDIR:-.}

# Use provided constraints file if set, otherwise compute constraints
if [ -z "${CONSTRAINTS:-}" ]; then
    CONSTRAINTS="$OUTDIR/computed-constraints.txt"
    prepare_constraints "$FROMAGER_VARIANT" "$COLLECTION" "$CONSTRAINTS"
else
    echo "Using provided constraints file: $CONSTRAINTS"
fi

# Set default build mode if not provided
BUILD_MODE=${BUILD_MODE:-parallel}

# Compute wheel server url from wheel server project path using wheel project id
WHEEL_PROJECT_ID=$(get-project-id "$WHEEL_SERVER_PROJECT_PATH" | tail -1)
export WHEEL_PROJECT_ID
export PYPI_URL_BASE="https://gitlab.com/api/v4/projects/${WHEEL_PROJECT_ID}/packages/pypi/"
export WHEEL_SERVER_URL="${PYPI_URL_BASE}/simple/"

# Write a pypirc file for the uploader plugin to use with twine.
export TWINE_CONFIG_FILE=/tmp/.pypirc
if [ -n "${RUN_CLEAN_AND_UPLOAD:-}" ]; then
    INDEX_NAME=gitlab-${FROMAGER_VARIANT}-wheels
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
index-servers = ${INDEX_NAME}
[${INDEX_NAME}]
repository = ${PYPI_URL_BASE}
username = ${BOT_USER}
password = ${BOT_PAT}
EOF
else
    # Create empty pypirc file when not uploading
    cat > $TWINE_CONFIG_FILE <<EOF
[distutils]
EOF
fi

# Set up nginx web server using the reusable functions
# shellcheck disable=SC1091
source "$SCRIPTDIR/nginx_server.sh"
start_nginx_server "$OUTDIR"

# Set fromager command variables based on build mode
case "$BUILD_MODE" in
  serial)
    echo "Running fromager in serial mode using build-sequence command"
    FROMAGER_COMMAND="build-sequence"
    INPUT_FILE="$OUTDIR/work-dir/build-order.json"
    ;;
  parallel)
    echo "Running fromager in parallel mode using build-parallel command"
    FROMAGER_COMMAND="build-parallel"
    INPUT_FILE="$OUTDIR/work-dir/graph.json"
    ;;
  *)
    echo "Error: Unknown build mode '$BUILD_MODE'. Valid options are 'serial' or 'parallel'."
    exit 1
    ;;
esac

LOG_FILE="$OUTDIR/build.log"

fromager \
  --constraints-file "$CONSTRAINTS" \
  --error-log-file="$OUTDIR/errors.log" \
  --log-file="$LOG_FILE" \
  --sdists-repo="$OUTDIR/sdists-repo" \
  --wheels-repo="$OUTDIR/wheels-repo" \
  --work-dir="$OUTDIR/work-dir" \
  --build-wheel-server-url="http://localhost:8080/simple/" \
  "$FROMAGER_COMMAND" --cache-wheel-server-url="$WHEEL_SERVER_URL" "$INPUT_FILE"

Perfect! I've updated the script to use a case statement that:

  1. Handles "serial" mode: Sets up build-sequence command with build-order.json
  2. Handles "parallel" mode: Sets up build-parallel command with graph.json
  3. Handles unknown modes: Reports a clear error message and exits with status 1

This makes the code more robust by explicitly handling invalid build mode values and providing clear feedback to users about what went wrong and what the valid options are.


User

You are a Commit Message Assistant. Your job is to generate high-quality, well-formatted Git commit messages based on user-provided descriptions of code changes.

Write a commit message describing the changes.

Output the results as literal markdown so the user can copy them.

Objectives

  • Help the user craft commit messages that follow best practices
  • Use Conventional Commit format unless otherwise specified
  • Clarify unclear or incomplete input with targeted questions
  • Ensure messages are concise, informative, and use imperative mood

Style Guidelines

  • Use the format: <type>(<scope>): <short summary> for the subject line
  • Keep the subject line ≤ 72 characters
  • Use a blank line before the body
  • The body explains what and why (not how)
  • Use a footer for metadata (e.g., Closes: #123, BREAKING CHANGE:)
  • Add attribution for yourself, including identifying the model and any tools used.

Types include:

  • feat: a new feature
  • fix: a bug fix
  • docs: documentation only changes
  • style: formatting, missing semi colons, etc
  • refactor: code change that neither fixes a bug nor adds a feature
  • perf: performance improvements
  • test: adding missing tests
  • chore: changes to the build process or auxiliary tools

Cursor

Based on the changes we made to add BUILD_MODE functionality to the CI pipeline, here's a commit message following the project's required format:

AIPCC-XXX: Add BUILD_MODE input for parallel/serial wheel building

This commit adds a new BUILD_MODE input parameter to the CI pipeline
that allows users to choose between parallel and serial wheel building
modes. The default mode is parallel for optimal performance.

Changes include:
- Add BUILD_MODE enum input with 'parallel' and 'serial' options
- Pass BUILD_MODE as environment variable to container builds
- Update build_wheels.sh to use build-parallel or build-sequence
  commands based on the specified mode
- Use case statement for robust mode validation with error handling
- Standardize log file naming to build.log for both modes

The parallel mode uses fromager's build-parallel command with the
dependency graph file, while serial mode uses build-sequence with
the build order file.

Signed-off-by: [Your Name] <[[email protected]]>

Note: You'll need to:

  1. Replace XXX with your actual JIRA ticket number
  2. Fill in your name and email in the Signed-off-by line
  3. Optionally add Fixes AIPCC-XXX if this closes the ticket

Generated by Claude (Anthropic) via Cursor IDE

AIPCC-XXX: Add BUILD_MODE input for parallel/serial wheel building

This commit adds a new BUILD_MODE input parameter to the CI pipeline
that allows users to choose between parallel and serial wheel building
modes. The default mode is parallel for optimal performance.

Changes include:
- Add BUILD_MODE enum input with 'parallel' and 'serial' options
- Pass BUILD_MODE as environment variable to container builds
- Update build_wheels.sh to use build-parallel or build-sequence
  commands based on the specified mode
- Use case statement for robust mode validation with error handling
- Standardize log file naming to build.log for both modes

The parallel mode uses fromager's build-parallel command with the
dependency graph file, while serial mode uses build-sequence with
the build order file.

Signed-off-by: [Your Name] <[[email protected]]>

User

Add attribution for yourself as a co-author to that commit message. Use the jira ticket AIPCC-5450 as the prefix of the title.


Cursor

Here's the updated commit message with the JIRA ticket number and co-author attribution:

AIPCC-5450: Add BUILD_MODE input for parallel/serial wheel building

This commit adds a new BUILD_MODE input parameter to the CI pipeline
that allows users to choose between parallel and serial wheel building
modes. The default mode is parallel for optimal performance.

Changes include:
- Add BUILD_MODE enum input with 'parallel' and 'serial' options
- Pass BUILD_MODE as environment variable to container builds
- Update build_wheels.sh to use build-parallel or build-sequence
  commands based on the specified mode
- Use case statement for robust mode validation with error handling
- Standardize log file naming to build.log for both modes

The parallel mode uses fromager's build-parallel command with the
dependency graph file, while serial mode uses build-sequence with
the build order file.

Co-authored-by: Claude (Anthropic) <[email protected]>
Signed-off-by: [Your Name] <[[email protected]]>

Note: You'll need to fill in your name and email in the Signed-off-by line. Optionally add Fixes AIPCC-5450 if this closes the ticket.

AIPCC-5450: Add BUILD_MODE input for parallel/serial wheel building

This commit adds a new BUILD_MODE input parameter to the CI pipeline
that allows users to choose between parallel and serial wheel building
modes. The default mode is parallel for optimal performance.

Changes include:
- Add BUILD_MODE enum input with 'parallel' and 'serial' options
- Pass BUILD_MODE as environment variable to container builds
- Update build_wheels.sh to use build-parallel or build-sequence
  commands based on the specified mode
- Use case statement for robust mode validation with error handling
- Standardize log file naming to build.log for both modes

The parallel mode uses fromager's build-parallel command with the
dependency graph file, while serial mode uses build-sequence with
the build order file.

Co-authored-by: Claude (Anthropic) <[email protected]>
Signed-off-by: [Your Name] <[[email protected]]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment