Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions .github/workflows/ado/package-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
# .github/workflows/ado/templates/package-build-stages.yml
#
# Authenticates via Workload Identity Federation (OIDC) and calls the Control
# Tower APIs to run the v1 post-merge delta build:
# Tower APIs to run the v1 post-merge delta build against each configured
# deployment:
# 1. Resolve the (target, source) commit range for this push from the
# previous CI build (ADO Builds API).
# 2. Submit official package builds for the components that changed across
# that range, via Workload Identity Federation (OIDC) to Control Tower.
# that range, via deployment-specific Workload Identity Federation (OIDC)
# service connections to Control Tower. Deployment jobs run independently
# in parallel.
#
# The setup + change-detection + validation steps are composed from the shared
# templates/steps/* step templates via templates/steps/get-changes-info.yml.
Expand All @@ -23,28 +26,30 @@
# - scripts/ci/components/ - (cross-pipeline azldev helpers shared with the GH Actions PR gates).
#
# Prerequisites (ADO / Azure Portal):
# 1. Entra ID App Registration with audience URI
# 1. Entra ID App Registrations with audience URIs
# "api://<ControlTower-ClientId>" (see variable group below).
# 2. Federated identity credential on the app registration for the ADO
# service connection (issuer: https://vstoken.dev.azure.com/<org-id>,
# 2. Federated identity credentials on the app registrations for the ADO
# service connections (issuer: https://vstoken.dev.azure.com/<org-id>,
# subject: sc://<org>/<project>/<service-connection-name>).
# 3. ARM service connection in ADO project settings using Workload Identity
# Federation (manual).
# 3. DEV and PROD ARM service connections in ADO project settings using
# Workload Identity Federation (manual).
# 4. CI trigger configured (in ADO pipeline settings) to fire on pushes to
# the target branch.
#
# Variable Group (ADO Pipelines > Library):
# Name: "ControlTower-PRCheck"
# Required variables:
# - ApiAudienceDev : DEV Entra ID audience URI
# - ApiBaseAFDUrlDev : DEV Azure Front Door endpoint base URL
# - ApiAudienceDev : DEV Entra ID audience URI
# - ApiAudienceProd : PROD Entra ID audience URI
# - ApiBaseAFDUrlDev : DEV Azure Front Door endpoint base URL
# - ApiBaseAFDUrlProd : PROD Azure Front Door endpoint base URL

# Trigger controlled by ADO branch policy — not YAML triggers.
trigger: none

pr: none

# Variables extracted from this group: ApiAudienceDev, ApiBaseAFDUrlDev.
# Variables extracted from this group: deployment audiences and endpoint URLs.
variables:
- group: ControlTower-PRCheck

Expand Down Expand Up @@ -78,15 +83,21 @@ extends:
stages:
- template: /.github/workflows/ado/templates/package-build-stages.yml@self
parameters:
apiAudience: $(ApiAudienceDev)
apiBaseAFDUrl: $(ApiBaseAFDUrlDev)
artifactBaseName: packagebuild
containerImage: mcr.microsoft.com/onebranch/azurelinux/build:3.0
deployments:
DEV:
apiAudience: $(ApiAudienceDev)
apiBaseAFDUrl: $(ApiBaseAFDUrlDev)
serviceConnection: CT-Endpoints-Access-ServiceConnection-DEV
PROD:
apiAudience: $(ApiAudienceProd)
apiBaseAFDUrl: $(ApiBaseAFDUrlProd)
serviceConnection: CT-Endpoints-Access-ServiceConnection-PROD
outputDirectory: $(Build.ArtifactStagingDirectory)/output
# Distro-config RPM build-environment for the 4.0 branch.
packageEnvironment: "4.0"
poolType: linux
serviceConnection: CT-Endpoints-Access-ServiceConnection-DEV
# Must exceed the script's --poll-timeout-seconds (default 600s = 10m)
# with enough headroom for setup steps and the final API call.
timeoutInMinutes: 25
132 changes: 67 additions & 65 deletions .github/workflows/ado/templates/package-build-stages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
# OneBranch-coupled knobs as parameters. The wrapper at
# .github/workflows/ado/package-build.yml supplies concrete values.
#
# Per push: gather the change-set info (get-changes-info, mode=postmerge: full
# history, deps, commit range, lock + render verification, changed-component
# set), then submit an official Control Tower build for the changed components.
# Per push and deployment: gather the change-set info (get-changes-info,
# mode=postmerge: full history, deps, commit range, lock + render verification,
# changed-component set), then submit an official Control Tower build for the
# changed components. Each deployment runs in a separate parallel job.

parameters:
- name: apiAudience
type: string
- name: apiBaseAFDUrl
type: string
- name: artifactBaseName
type: string
- name: containerImage
type: string
# Named map of deployment identifier to apiAudience, apiBaseAFDUrl, and
# serviceConnection. Identifiers must be valid Azure Pipelines job-name
# suffixes.
- name: deployments
type: object
- name: outputDirectory
type: string
# Distro-config RPM build-environment used by Control Tower.
Expand All @@ -27,70 +29,70 @@ parameters:
- name: poolType
type: string
default: linux
- name: serviceConnection
type: string
- name: timeoutInMinutes
type: number

stages:
- stage: PackageBuild
jobs:
- job: PackageBuild
# Post-merge build: code has already merged, so there is no PR or merge
# queue to gate. Fails loud -- any failing step turns the run red so
# submission/validation breakage is visible rather than masked. The
# build runs asynchronously in Control Tower/Koji; this pipeline only
# submits it and confirms acceptance (see run_official_package_build.py).
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
pool:
type: ${{ parameters.poolType }}
variables:
- name: LinuxContainerImage
value: ${{ parameters.containerImage }}
- name: ob_artifactBaseName
value: ${{ parameters.artifactBaseName }}
- name: ob_outputDirectory
value: ${{ parameters.outputDirectory }}
- name: packageEnvironment
value: ${{ parameters.packageEnvironment }}
steps:
# Sets job variables:
# - changedComponentsFile
- template: steps/get-changes-info.yml
parameters:
mode: postmerge
- ${{ each deployment in parameters.deployments }}:
- job: PackageBuild_${{ deployment.key }}
displayName: "Package build (${{ deployment.key }})"
# Post-merge build: code has already merged, so there is no PR or
# merge queue to gate. Fails loud -- any failing deployment turns
# the run red so submission/validation breakage is visible rather
# than masked. Deployment jobs run independently in parallel. The
# build runs asynchronously in Control Tower/Koji; this pipeline
# only submits it and confirms acceptance (see
# run_official_package_build.py).
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
pool:
type: ${{ parameters.poolType }}
variables:
- name: LinuxContainerImage
value: ${{ parameters.containerImage }}
- name: ob_artifactBaseName
value: ${{ parameters.artifactBaseName }}-${{ deployment.key }}
- name: ob_outputDirectory
value: ${{ parameters.outputDirectory }}/${{ deployment.key }}
- name: packageEnvironment
value: ${{ parameters.packageEnvironment }}
steps:
# Sets job variables:
# - changedComponentsFile
- template: steps/get-changes-info.yml
Comment thread
dmcilvaney marked this conversation as resolved.
parameters:
mode: postmerge

- template: steps/install-deps.yml
parameters:
installControlTowerClient: true
- template: steps/install-deps.yml
parameters:
installControlTowerClient: true

- task: AzureCLI@2
displayName: "Submit official package build to Control Tower"
inputs:
azureSubscription: ${{ parameters.serviceConnection }}
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
set -euo pipefail
- task: AzureCLI@2
displayName: "Submit official package build to Control Tower (${{ deployment.key }})"
inputs:
azureSubscription: ${{ deployment.value.serviceConnection }}
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
set -euo pipefail

python3 scripts/ci/control-tower/run_official_package_build.py \
--api-audience "$API_AUDIENCE" \
--api-base-url "$API_BASE_URL" \
--build-reason "$BUILD_REASON" \
--changed-components-file "$CHANGED_COMPONENTS_FILE" \
--environment "$PACKAGE_ENVIRONMENT"
env:
# apiAudience / apiBaseAFDUrl come from the parameters directly
# (not surfaced as same-named job variables): the wrapper passes
# $(ApiAudience) / $(ApiBaseAFDUrl) from the variable group, and a
# job variable of the same (case-insensitive) name would
# self-reference -> "cyclical reference" and never resolve.
API_AUDIENCE: ${{ parameters.apiAudience }}
API_BASE_URL: ${{ parameters.apiBaseAFDUrl }}
CHANGED_COMPONENTS_FILE: $(changedComponentsFile)
PACKAGE_ENVIRONMENT: $(packageEnvironment)
# Secret predefined variables are not auto-exposed.
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
# Build.Reason is predefined and auto-exposed as $BUILD_REASON;
# reference it directly and do not map it here (env: overrides
# of reserved variables are silently ignored by the agent).
python3 scripts/ci/control-tower/run_official_package_build.py \
--api-audience "$API_AUDIENCE" \
--api-base-url "$API_BASE_URL" \
--build-reason "$BUILD_REASON" \
--changed-components-file "$CHANGED_COMPONENTS_FILE" \
--environment "$PACKAGE_ENVIRONMENT"
env:
# Values come directly from parameters rather than same-named
# job variables, which would create cyclical references.
API_AUDIENCE: ${{ deployment.value.apiAudience }}
API_BASE_URL: ${{ deployment.value.apiBaseAFDUrl }}
CHANGED_COMPONENTS_FILE: $(changedComponentsFile)
PACKAGE_ENVIRONMENT: $(packageEnvironment)
# Secret predefined variables are not auto-exposed.
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
# Build.Reason is predefined and auto-exposed as
# $BUILD_REASON; reference it directly and do not map it here
# (env: overrides of reserved variables are silently ignored
# by the agent).
Loading