Skip to content
50 changes: 42 additions & 8 deletions eng/common/pipelines/templates/archetype-typespec-emitter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,34 @@ extends:
# Create emitter identifier from package path for disambiguation
$emitterIdentifier = ""
if (-not [string]::IsNullOrWhiteSpace($emitterPackagePath)) {
# Extract filename without extension and make it safe for branch names
$emitterIdentifier = [System.IO.Path]::GetFileNameWithoutExtension($emitterPackagePath)
# Replace any characters that aren't alphanumeric, hyphens, or underscores
$emitterIdentifier = $emitterIdentifier -replace '[^a-zA-Z0-9\-_]', '-'
# Remove any leading/trailing hyphens and convert to lowercase
# Resolve emitterPackagePath to absolute path (it's relative to repo root)
# EmitterPackagePath is a directory, so append package.json
$absoluteEmitterPackagePath = Join-Path '$(Build.SourcesDirectory)' $emitterPackagePath
$packageJsonPath = Join-Path $absoluteEmitterPackagePath 'package.json'

# Read the package name from package.json
if (Test-Path $packageJsonPath) {
try {
$packageJson = Get-Content $packageJsonPath -Raw | ConvertFrom-Json
if ($packageJson.name) {
$emitterIdentifier = $packageJson.name
}
} catch {
Write-Host "Warning: Could not read package name from $packageJsonPath"
}
}

# If we still don't have an identifier, fall back to filename
if ([string]::IsNullOrWhiteSpace($emitterIdentifier)) {
Write-Host "Warning: Could not read emitter name from package.json, falling back to package path"
$emitterIdentifier = [System.IO.Path]::GetFileNameWithoutExtension($emitterPackagePath)
}

# Clean up the identifier: remove @ prefix, replace invalid chars
$emitterIdentifier = $emitterIdentifier -replace '^@', ''
$emitterIdentifier = $emitterIdentifier -replace '[^a-zA-Z0-9\-_/]', '-'
$emitterIdentifier = $emitterIdentifier.Trim('-').ToLower()

if (-not [string]::IsNullOrWhiteSpace($emitterIdentifier)) {
$emitterIdentifier = "-$emitterIdentifier"
}
Expand All @@ -163,6 +185,8 @@ extends:

Write-Host "Setting variable 'branchName' to '$branchName'"
Write-Host "##vso[task.setvariable variable=branchName;isOutput=true]$branchName"
Write-Host "Setting variable 'emitterIdentifier' to '$emitterIdentifier'"
Write-Host "##vso[task.setvariable variable=emitterIdentifier;isOutput=true]$emitterIdentifier"
displayName: Set branch name
name: set_branch_name

Expand Down Expand Up @@ -383,15 +407,18 @@ extends:
displayName: Create PR
dependsOn:
- Generate
condition: succeededOrFailed()
variables:
generateJobResult: $[dependencies.Generate.result]
emitterVersion: $[stageDependencies.Build.Build.outputs['initialize.emitterVersion']]
emitterIdentifier: $[stageDependencies.Build.Build.outputs['set_branch_name.emitterIdentifier']]
steps:
- template: /eng/common/pipelines/templates/steps/sparse-checkout.yml

- pwsh: |
$generateJobResult = '$(generateJobResult)'
$emitterVersion = '$(emitterVersion)'
$emitterIdentifier = '$(emitterIdentifier)'
$collectionUri = '$(System.CollectionUri)'
$project = '$(System.TeamProject)'
$definitionName = '$(Build.DefinitionName)'
Expand All @@ -403,6 +430,12 @@ extends:
$buildNumber = '$(Build.BuildNumber)'
$preRelease = '${{ parameters.BuildPrereleaseVersion }}' -eq 'true'

# Use emitterIdentifier for PR title (remove leading dash if present)
$emitterName = "TypeSpec emitter"
if (-not [string]::IsNullOrWhiteSpace($emitterIdentifier)) {
$emitterName = $emitterIdentifier.TrimStart('-')
}

$prBody = "Generated by $definitionName build [$buildNumber]($collectionUri/$project/_build/results?buildId=$buildId)<br/>"

if ($sourceBranch -match "^refs/heads/(.+)$") {
Expand All @@ -419,9 +452,9 @@ extends:
$prTitle = "Scheduled code regeneration test"
} else {
if ($preRelease) {
$prTitle = "Update TypeSpec emitter version to prerelease $emitterVersion"
$prTitle = "Update $emitterName version to prerelease $emitterVersion"
} else {
$prTitle = "Update TypeSpec emitter version to $emitterVersion"
$prTitle = "Update $emitterName version to $emitterVersion"
}

if ($generateJobResult -ne 'Succeeded') {
Expand All @@ -446,7 +479,8 @@ extends:
Write-Error "Build.Repository.Name not in the expected {Owner}/{Name} format"
}

$openAsDraft = -not ($reason -eq 'IndividualCI' -and $sourceBranch -eq 'refs/heads/main')
# Open PR as draft if generation failed, or if it's not an IndividualCI build from main
$openAsDraft = ($generateJobResult -ne 'Succeeded') -or (-not ($reason -eq 'IndividualCI' -and $sourceBranch -eq 'refs/heads/main'))
Write-Host "Setting OpenAsDraftBool = $openAsDraft"
Write-Host "##vso[task.setvariable variable=OpenAsDraft]$openAsDraft"
if ($openAsDraft) {
Expand Down