ci: make release publish jobs idempotent on re-run#7895
Merged
Conversation
Re-triggering the release pipeline for a tag that was already (partially) published previously failed hard: GitHubRelease@1 returns 422 on an existing tag, NuGet push returns 409 on a duplicate version, npm/ESRP re-publish and vsce publish fail on an existing version. This blocked recovering from a partial release (e.g. when only the npm ESRP step failed) without manual surgery. Each publish job now checks whether its artifact version is already published and skips the publish step if so, otherwise publishes as before: - github_release: anonymous GitHub API lookup of the release by tag sets releaseExists; both GitHubRelease@1 tasks are gated to skip when it exists. - deploy_kiota / deploy_builder: query the nuget.org flat container for the version parsed from the .nupkg filename; 1ES.PublishNuget@1 is gated on the result. - deploy_npm: add UseNode@1 and run 'npm view @microsoft/kiota@<version>' (version parsed from the microsoft-kiota-<version>.tgz filename); EsrpRelease@12 is gated on the result. - vs_marketplace: capture vsce publish output and treat a non-zero exit whose output contains 'already exists' as an idempotent skip. PushDockerImage is already idempotent (tag overwrite) and is unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Code Coverage OverviewLanguages: C# C# / code-coverage/dotnetThe overall coverage in the branch is 72%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
Code Coverage is in Public Preview. Learn more and provide us with your feedback. |
adrian05-ms
approved these changes
Jul 3, 2026
This was referenced Jul 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Re-triggering the release pipeline for a tag that was already (partially) published previously failed hard, making it impossible to recover from a partial release without manual surgery:
GitHubRelease@1returns 422 when the tag/release already exists1ES.PublishNuget@1returns 409 on a duplicate NuGet versionEsrpRelease@12(npm) andvsce publishfail on an already-published versionThis blocked recovery scenarios such as a run where every stage succeeded except the npm ESRP publish — a plain "Rerun failed jobs" still re-hit the 422/409 walls on the other publish steps.
What
Each publish job now checks whether its artifact version is already published and skips that publish step if so, otherwise publishes exactly as before:
github_releasereleaseExistsGitHubRelease@1tasks gatedne(releaseExists,'true')deploy_kiota/deploy_builder.nupkgfilename →nugetAlreadyPublished1ES.PublishNuget@1gated on itdeploy_npmUseNode@1;npm view @microsoft/kiota@<version>(version frommicrosoft-kiota-<version>.tgz) →npmAlreadyPublishedEsrpRelease@12gated on itvs_marketplacevsce publishoutput; non-zero exit whose output containsalready existsPushDockerImageis already idempotent (tag overwrite) and is unchanged.Notes
vs_marketplacerelies on vsce's own duplicate detection rather than a tag-version compare: a re-run of the same build republishes an identical vsix version (skipped), while a new build produces a new version (published).Validation
yaml.safe_load).Microsoft.OpenApi.Kiota/.Builderboth already at 1.32.5 → would skip; npm@microsoft/kiotais only at 1.32.4 (1.32.5 returns 404) → would publish. This matches the real partial-release state.