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
72 changes: 72 additions & 0 deletions eng/common/pipelines/templates/jobs/apireview-hub-job-base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Base job wrapper for API Review Hub artifact creation. Language-specific job
# templates provide setup steps and the request handler provides orchestration steps.
parameters:
- name: jobName
type: string
default: CreateApiReviewArtifacts
- name: displayName
type: string
default: 'Create API review artifacts'
- name: poolName
type: string
default: 'azsdk-pool'
- name: imageOverride
type: string
default: 'ubuntu-24.04'
- name: variables
type: object
default: []
- name: sourceRepositoryFullName
type: string
default: ''
- name: sourceCheckoutDir
type: string
default: ''
- name: toolingDir
type: string
default: '$(Pipeline.Workspace)/apireview/tooling'
- name: setupSteps
type: stepList
default: []
- name: steps
type: stepList
default: []

jobs:
- job: ${{ parameters.jobName }}
displayName: ${{ parameters.displayName }}

pool:
name: ${{ parameters.poolName }}
demands: ImageOverride -equals ${{ parameters.imageOverride }}

variables:
- template: /eng/pipelines/templates/variables/globals.yml
- name: ApiReviewRepositoryFullName
value: ${{ parameters.sourceRepositoryFullName }}
- name: ApiReviewSourceDir
value: ${{ parameters.sourceCheckoutDir }}
- name: ApiReviewToolingDir
value: ${{ parameters.toolingDir }}
- ${{ each variable in parameters.variables }}:
- ${{ variable }}

steps:
- ${{ if ne(parameters.sourceCheckoutDir, '') }}:
- bash: |
set -Eeuo pipefail

source_repo="${{ parameters.sourceCheckoutDir }}"
repository_full_name="${{ parameters.sourceRepositoryFullName }}"

rm -rf "$source_repo"
mkdir -p "$(dirname "$source_repo")"

echo "Cloning $repository_full_name into $source_repo"
git clone --filter=blob:none --no-checkout "https://github.com/$repository_full_name.git" "$source_repo"
displayName: 'Clone API review source repository'

- ${{ parameters.setupSteps }}

# These steps are assembled by the generic API Review Hub request pipeline.
- ${{ parameters.steps }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Base artifact step for API Review Hub. Language-specific templates provide the
# generation steps and this template enforces the shared artifact contract.
parameters:
- name: requestMode
type: string
- name: operationId
type: string
- name: packageName
type: string
- name: ref
type: string
- name: kind
type: string
- name: outputDir
type: string
- name: workingDir
type: string
- name: sourceDir
type: string
- name: language
type: string
- name: repositoryFullName
type: string
- name: generationSteps
type: stepList
default: []

steps:
- pwsh: |
$ErrorActionPreference = 'Stop'

New-Item -ItemType Directory -Force -Path '${{ parameters.outputDir }}' | Out-Null
New-Item -ItemType Directory -Force -Path '${{ parameters.workingDir }}' | Out-Null
New-Item -ItemType Directory -Force -Path '${{ parameters.workingDir }}/state' | Out-Null
displayName: 'Prepare ${{ parameters.kind }} API review bundle directories'

- bash: |
set -Eeuo pipefail

source_repo="${{ parameters.sourceDir }}"
ref="${{ parameters.ref }}"

if [ ! -d "$source_repo/.git" ]; then
echo "Expected API review source repository was not cloned at $source_repo" >&2
exit 1
fi

# API Review Hub must provide a fully-qualified Git ref (for example refs/heads/* or refs/tags/*).
# Keeping this explicit avoids ambiguous fetch behavior across remote refspec configurations.
if [[ -z "$ref" || "$ref" != refs/* ]]; then
echo "Expected a fully-qualified git ref (refs/*), but received: '$ref'" >&2
exit 1
fi

echo "Checking out ${{ parameters.kind }} API review source ref $ref in $source_repo"
git -C "$source_repo" fetch --depth=1 origin "$ref"
git -C "$source_repo" checkout --force FETCH_HEAD
git -C "$source_repo" clean -ffd
displayName: 'Checkout ${{ parameters.kind }} API review source'

- ${{ parameters.generationSteps }}

- pwsh: |
$ErrorActionPreference = 'Stop'

$outputDir = '${{ parameters.outputDir }}'
$stateDir = '${{ parameters.workingDir }}/state'
$apiMdPath = Join-Path $outputDir 'api.md'
$apiMetadataPath = Join-Path $outputDir 'api.metadata.yml'
$packageRelativePathPath = Join-Path $stateDir 'package-relative-path.txt'
$versionPath = Join-Path $stateDir 'version.txt'
if (!(Test-Path -Path $apiMdPath -PathType Leaf)) {
Write-Error "Expected api.md was not produced at $apiMdPath."
}
if (!(Test-Path -Path $apiMetadataPath -PathType Leaf)) {
Write-Error "Expected api.metadata.yml was not produced at $apiMetadataPath."
}
if (!(Test-Path -Path $packageRelativePathPath -PathType Leaf)) {
Write-Error "Expected package-relative-path.txt was not produced at $packageRelativePathPath."
}
if (!(Test-Path -Path $versionPath -PathType Leaf)) {
Write-Error "Expected version.txt was not produced at $versionPath."
}

$packageRelativePath = Get-Content -Raw -Path $packageRelativePathPath
$version = Get-Content -Raw -Path $versionPath

$metadata = [ordered]@{
operationId = '${{ parameters.operationId }}'
mode = '${{ parameters.requestMode }}'
language = '${{ parameters.language }}'
repositoryFullName = '${{ parameters.repositoryFullName }}'
packageName = '${{ parameters.packageName }}'
packageRelativePath = $packageRelativePath.Trim()
ref = '${{ parameters.ref }}'
version = $version.Trim()
kind = '${{ parameters.kind }}'
}
$metadata | ConvertTo-Json -Depth 10 | Set-Content -Path (Join-Path $outputDir 'artifact-metadata.json') -Encoding utf8
Get-Content -Path (Join-Path $outputDir 'artifact-metadata.json')
displayName: 'Validate and write ${{ parameters.kind }} API review bundle metadata'
Loading