From ded668be79fac6935325e14a4341f22346f9078b Mon Sep 17 00:00:00 2001 From: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com> Date: Wed, 15 Oct 2025 09:41:57 -0700 Subject: [PATCH] Sync eng/common directory with azure-sdk-tools for PR 12483 (#6787) * Mark TypeSpec upgrade PR as draft when generation fails Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> * Add condition to run Create_PR job even when Generate fails Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> * Include emitter name in PR title Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> * Use emitterIdentifier variable for PR title instead of recalculating Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> * Include scope in emitterIdentifier for branch and PR names Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> * Read emitter name from package.json instead of extracting from path Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> * Resolve emitterPackagePath to absolute path before reading Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> * Append package.json to emitterPackagePath directory Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> * Add log statement for fallback to package path Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- .../templates/archetype-typespec-emitter.yml | 50 ++++++++++++++++--- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/eng/common/pipelines/templates/archetype-typespec-emitter.yml b/eng/common/pipelines/templates/archetype-typespec-emitter.yml index dab06ccb1..443ac86a9 100644 --- a/eng/common/pipelines/templates/archetype-typespec-emitter.yml +++ b/eng/common/pipelines/templates/archetype-typespec-emitter.yml @@ -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" } @@ -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 @@ -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)' @@ -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)
" if ($sourceBranch -match "^refs/heads/(.+)$") { @@ -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') { @@ -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) {