From c4a639f8ef675b4cc8aebb031cb4629a8c77d6f4 Mon Sep 17 00:00:00 2001 From: Zhipeng Wang Date: Thu, 14 May 2026 14:11:21 +0800 Subject: [PATCH] ci: migrate GitHub release pipeline from OneBranch to 1ES template Switch modelkit-release-github.yml to extend v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates, running on the ProjectReunionESPool-2022 pool with MMS2022-1ES-GPT. Split the original single-job pipeline into Prepare (downloads official build, stages wheels + parquets) and CreateGitHubRelease (releaseJob consuming the staged artifact), since 1ES Official only permits GitHubRelease@1 inside templateContext.type: releaseJob and that job type cannot run DownloadPipelineArtifact@2. Version is now derived from the wheel filename instead of pyproject.toml so the release job needs no source checkout. --- .pipelines/modelkit-release-github.yml | 196 ++++++++++++------------- 1 file changed, 97 insertions(+), 99 deletions(-) diff --git a/.pipelines/modelkit-release-github.yml b/.pipelines/modelkit-release-github.yml index 96b7ec7c6..b27e71937 100644 --- a/.pipelines/modelkit-release-github.yml +++ b/.pipelines/modelkit-release-github.yml @@ -1,129 +1,127 @@ -################################################################################# -# OneBranch Pipelines # -# This pipeline was created by EasyStart from a sample located at: # -# https://aka.ms/obpipelines/easystart/samples # -# Documentation: https://aka.ms/obpipelines # -# Yaml Schema: https://aka.ms/obpipelines/yaml/schema # -# Retail Tasks: https://aka.ms/obpipelines/tasks # -# Support: https://aka.ms/onebranchsup # -################################################################################# +name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr) -trigger: none # https://aka.ms/obpipelines/triggers +trigger: none -parameters: # parameters are shown up in ADO UI in a build queue time -- name: 'debug' - displayName: 'Enable debug output' - type: boolean - default: false +parameters: - name: OFFICIAL_BUILD_ID - displayName: 'Specify which run to use (the pipeline build ID)' + displayName: 'Specify which official build run to use (pipeline build ID)' type: string -variables: - CDP_DEFINITION_BUILD_COUNT: $[counter('', 0)] # needed for onebranch.pipeline.version task https://aka.ms/obpipelines/versioning - DEBIAN_FRONTEND: noninteractive - LinuxContainerImage: 'mcr.microsoft.com/onebranch/azurelinux/build:3.0' # https://eng.ms/docs/products/onebranch/infrastructureandimages/containerimages/linuximages/marinerazurelinux/azurelinux - WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' # https://aka.ms/obpipelines/containers - resources: repositories: - - repository: templates - type: git - name: OneBranch.Pipelines/GovernedTemplates - ref: refs/heads/main + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release extends: - template: v2/OneBranch.Official.CrossPlat.yml@templates # https://aka.ms/obpipelines/templates + template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates parameters: - git: - fetchDepth: -1 - featureFlags: - EnableCDPxPAT: false - WindowsHostVersion: '1ESWindows2022' - globalSdl: - tsa: - enabled: false - + pool: + isCustom: true + name: 'ProjectReunionESPool-2022' + # Need a clone of MMS2022 with artifact windows-1es-pt-prerequisites-v2 installed to satisfy 1ESPT. + # https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/onboardingesteams/create-agent-image + demands: ImageOverride -equals MMS2022-1ES-GPT stages: - stage: Release displayName: 'Release to GitHub' condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/release/') jobs: - - job: CreateGitHubRelease - displayName: 'Create GitHub Release' - pool: - type: windows - - variables: - ob_outputDirectory: '$(Build.SourcesDirectory)\out' + - job: Prepare + displayName: 'Prepare GitHub Release Assets' + templateContext: + outputs: + - output: pipelineArtifact + displayName: 'Publish staged release assets' + targetPath: $(Build.SourcesDirectory)/release_assets + artifactName: GitHubReleaseAssets steps: - - task: DownloadPipelineArtifact@2 - displayName: 'Download build artifacts' - inputs: - buildType: 'specific' - project: '320d2220-0d58-42de-ae76-6f774e8e5eef' - definition: '191314' - buildVersionToDownload: 'specific' - pipelineId: ${{ parameters.OFFICIAL_BUILD_ID }} - targetPath: '$(Pipeline.Workspace)' - - - powershell: | - $content = Get-Content "$(Build.SourcesDirectory)\pyproject.toml" -Raw - if ($content -match 'version\s*=\s*"([^"]+)"') { - $version = $matches[1] - $tag = "v$version" - Write-Host "Version: $version" - Write-Host "Tag: $tag" - Write-Host "##vso[task.setvariable variable=ReleaseVersion]$version" - Write-Host "##vso[task.setvariable variable=ReleaseTag]$tag" - } else { - Write-Error "Could not parse version from pyproject.toml" - exit 1 - } - displayName: 'Extract version from pyproject.toml' - - - powershell: | - $artifactDir = "$(Pipeline.Workspace)" - $outDir = "$(ob_outputDirectory)" - $rulesZipPath = Join-Path $outDir "rules.zip" - - New-Item -ItemType Directory -Path $outDir -Force | Out-Null - - $wheels = Get-ChildItem "$artifactDir" -Filter "*.whl" -Recurse + - task: DownloadPipelineArtifact@2 + displayName: 'Download official build artifacts' + inputs: + buildType: 'specific' + project: '320d2220-0d58-42de-ae76-6f774e8e5eef' + definition: '191314' + buildVersionToDownload: 'specific' + pipelineId: ${{ parameters.OFFICIAL_BUILD_ID }} + targetPath: '$(Build.SourcesDirectory)/official_build' + + - task: PowerShell@2 + displayName: 'Stage wheels + rules.zip' + inputs: + targetType: 'inline' + script: | + $src = "$(Build.SourcesDirectory)/official_build" + $dst = "$(Build.SourcesDirectory)/release_assets" + New-Item -ItemType Directory -Path $dst -Force | Out-Null + + $wheels = Get-ChildItem $src -Filter "*.whl" -Recurse if (-not $wheels) { - throw "No wheel files found under $artifactDir" + throw "No wheel files found under $src" } - $wheels | Copy-Item -Destination $outDir -Force + $wheels | Copy-Item -Destination $dst -Force - $rulesZipCandidates = Get-ChildItem "$artifactDir" -Filter "rules.zip" -Recurse + $rulesZipCandidates = Get-ChildItem $src -Filter "rules.zip" -Recurse if (-not $rulesZipCandidates) { - throw "No rules.zip found under $artifactDir. Release requires the official build to publish rules.zip." + throw "No rules.zip found under $src. Release requires the official build to publish rules.zip." } - if ($rulesZipCandidates.Count -gt 1) { Write-Warning "Found $($rulesZipCandidates.Count) rules.zip files; using the first one" } $selectedRulesZip = $rulesZipCandidates | Select-Object -First 1 - Copy-Item $selectedRulesZip.FullName -Destination $rulesZipPath -Force + Copy-Item $selectedRulesZip.FullName -Destination (Join-Path $dst "rules.zip") -Force Write-Host "Found $($wheels.Count) wheel(s)" Write-Host "Using build-produced rules.zip from $($selectedRulesZip.FullName)" - displayName: 'Stage release assets' + Write-Host "Staged GitHub release assets:" + Get-ChildItem $dst | ForEach-Object { Write-Host (" - {0} ({1:N0} bytes)" -f $_.Name, $_.Length) } + + - job: CreateGitHubRelease + displayName: 'Create GitHub Release' + dependsOn: Prepare + templateContext: + type: releaseJob # Required, this indicates this job is a release job + isProduction: true # Required, must be 'true' or 'false' + inputs: + - input: pipelineArtifact + artifactName: GitHubReleaseAssets + targetPath: $(Build.SourcesDirectory)/release_assets - - task: GitHubRelease@1 - displayName: 'Create GitHub Release' - inputs: - gitHubConnection: 'ModelKit' - repositoryName: 'microsoft/WinML-ModelKit' - action: create - target: '$(Build.SourceVersion)' - tagSource: userSpecifiedTag - tag: '$(ReleaseTag)' - title: 'ModelKit $(ReleaseTag)' - assets: | - $(ob_outputDirectory)\*.whl - $(ob_outputDirectory)\rules.zip - isDraft: false - isPreRelease: true - addChangeLog: false + steps: + - task: PowerShell@2 + displayName: 'Extract version from wheel filename' + inputs: + targetType: 'inline' + script: | + $wheel = Get-ChildItem "$(Build.SourcesDirectory)/release_assets/*.whl" | Select-Object -First 1 + if (-not $wheel) { throw "no wheel found in staged assets" } + # Wheel filename is ----.whl + # PEP 503 normalizes "winml-modelkit" -> "winml_modelkit" in filenames. + if ($wheel.Name -notmatch '^winml_modelkit-([^-]+)-') { + throw "wheel filename '$($wheel.Name)' does not match expected pattern 'winml_modelkit--...'" + } + $version = $matches[1] + $tag = "v$version" + Write-Host "Version: $version" + Write-Host "Tag: $tag" + Write-Host "##vso[task.setvariable variable=ReleaseVersion]$version" + Write-Host "##vso[task.setvariable variable=ReleaseTag]$tag" + + - task: GitHubRelease@1 + displayName: 'Create GitHub Release' + inputs: + gitHubConnection: 'ModelKit' + repositoryName: 'microsoft/WinML-ModelKit' + action: create + target: '$(Build.SourceVersion)' + tagSource: userSpecifiedTag + tag: '$(ReleaseTag)' + title: 'ModelKit $(ReleaseTag)' + assets: | + $(Build.SourcesDirectory)/release_assets/*.whl + $(Build.SourcesDirectory)/release_assets/rules.zip + isDraft: false + isPreRelease: true + addChangeLog: false