ci(release): per-package ADO release stages + build on Node 22 - #336
Merged
Conversation
B13: eng/ci/release.yml published all three npm packages from a single
`- stage: release`. In Azure DevOps only STAGES are individually selectable at
queue time ("Stages to run") -- jobs are not -- so queuing a release published
core, azuremanaged and durable-functions together. durable-functions pins
"@microsoft/durabletask-js" to an EXACT version, so core must reach the registry
first; a combined publish would put an uninstallable compat package on npm.
Split the single stage into three, one job each, mirroring durabletask-python:
- release_durabletask_js (core; no dependency)
- release_durabletask_js_azuremanaged (dependsOn: release_durabletask_js)
- release_durable_functions (dependsOn: release_durabletask_js)
The two dependents depend on CORE only, not on each other (siblings, not chained).
Because ADO skips a de-selected stage at queue time, core can be released on its own
and a dependent released later. Every EsrpRelease@9 input and each job's
templateContext are preserved byte-for-byte; no environment/condition/input added.
B12: eng/templates/build.yml built the shipped .tgz artifacts on Node 20
(NodeTool@0 versionSpec: 20.x) while all packages declare engines node >=22.0.0 and
GitHub CI only tests 22.x/24.x -- so the runtime that builds the released artifacts
was never covered by the green CI signal and ran a Node the packages call
unsupported. Bump the official build to 22.x, the conservative choice already
exercised by CI. No other change to that file.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d86f5f69-4e1a-4c1d-b017-5e290c85cc05
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the Azure DevOps (1ES Official) pipeline definitions to (1) support per-package releases in this monorepo via individually selectable stages and (2) align the official build’s Node.js version with the packages’ declared engine requirements.
Changes:
- Split the single ADO release stage into three per-package stages with ordering constraints via
dependsOn. - Update the official build template to install Node.js 22.x instead of 20.x.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| eng/ci/release.yml | Refactors the release pipeline into three independently selectable stages and adds stage dependencies to enforce publish ordering. |
| eng/templates/build.yml | Bumps the NodeTool installation from 20.x to 22.x for the official build. |
Comments suppressed due to low confidence (1)
eng/ci/release.yml:106
- Same issue as the other dependent stage: with
dependsOn: release_durabletask_js, this stage will be skipped if the core stage is de-selected at queue time. If the goal is to allow releasing this package independently after core is already published, add aconditionthat permits running when the dependency stage was skipped.
# Publish the core durabletask-js stage before this dependent package: durable-functions
# pins "@microsoft/durabletask-js" to an EXACT version, so core must be on the registry
# first or the published package is uninstallable. This depends on the core stage only,
# not on the azuremanaged stage (they are siblings, mirroring durabletask-python). If the
# core stage is de-selected at queue time, ADO skips it and this stage runs on its own.
dependsOn: release_durabletask_js
jobs:
…cted The Copilot PR reviewer flagged that with `dependsOn: release_durabletask_js` alone, ADO's DEFAULT stage condition requires the core stage to have completed and succeeded, so de-selecting the core stage at queue time (to release only a dependent package) would SKIP the dependent stage too. That contradicts the adjacent comment claiming the stage "runs on its own": the comment copied from durabletask-python is wrong -- verified against Microsoft Learn, ADO does not run a stage whose dependency was Skipped unless an explicit condition allows it. Add an explicit stage-level condition to BOTH dependent stages: condition: in(dependencies.release_durabletask_js.result, 'Succeeded', 'SucceededWithIssues', 'Skipped') This accepts a Skipped core stage (enabling independent release when core is de-selected) while still rejecting Failed and Canceled, so a real core publish FAILURE still blocks the dependent stages. That matters most for durable-functions, whose exact pin "@microsoft/durabletask-js": "0.4.0" would otherwise ship an uninstallable package if core failed. The fix is strictly safe: if de-selection already worked the condition changes nothing; if it did not, it fixes it. The core stage keeps ADO's default (no dependsOn, no condition). Both stage comments are corrected to describe the real behavior. Only eng/ci/release.yml changes; ESRP inputs and templateContext blocks are byte-identical to d00b502. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d86f5f69-4e1a-4c1d-b017-5e290c85cc05
bachuv
approved these changes
Jul 29, 2026
YunchuWang
added a commit
that referenced
this pull request
Jul 29, 2026
doc/release_process.md is the runbook Bill will follow for this release, but it still described the old "all packages share one version, publish manually" model and, followed as written, would produce a wrong release. Update it to match the per-package release tooling (PR #335 prepare-release workflow + PR #336 ADO per-package stages). - Scope: cover all three published packages -- @microsoft/durabletask-js (core), @microsoft/durabletask-js-azuremanaged, and durable-functions (source dir packages/azure-functions-durable) -- in the intro, Overview table, the Step 2 .tgz list, and the Step 4 npm-view list. - Versioning Policy: replace "all packages same version" with per-package independent versioning/changelog/tags; document the one hard ordering constraint (compat exact-pins core, so core must publish first or the published compat package is uninstallable) and that azuremanaged is unordered (peer floor >=0.3.0 already satisfied by published core). - Resolve the self-contradiction: ESRP via eng/ci/release.yml is the sanctioned publish path; a manual npm publish is the alternative. - Prepare Release section: document the required `package` input and that the workflow bumps only the selected package and writes only that package's own changelog file (root CHANGELOG.md for core/azuremanaged, packages/azure-functions-durable/CHANGELOG.md for durable-functions). - Branch/tag naming: prefix-derived (v / azuremanaged-v / durable-functions-v) with concrete examples, in the workflow section, Step 2, Step 5, and the manual steps. - Step 3: three ADO stages (not jobs), individually selectable at queue time, core-before-compat ordering, and the explicit Skipped-accepting condition (rejects Failed/Canceled) added in PR #336. - Manual section: bump only the released package; add the durable-functions exact-pin dependency step. - Dist tags: reconcile the general semver table with the tooling (every prerelease -> preview) and make durable-functions@preview explicit (cross-checked against packages/azure-functions-durable/CHANGELOG.md). - Flag B11 (whether ESRP can set an npm dist-tag) as an explicit open question, not fact. Docs only; no code or behavior change. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d86f5f69-4e1a-4c1d-b017-5e290c85cc05
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.
Summary
Restructures the 1ES Official ADO release pipeline so the three npm packages in this monorepo can be released independently and in the required order, and bumps the official build to the Node version the packages actually require. Two independent fixes, two files.
B13 — per-package release stages (
eng/ci/release.yml)All three ESRP publish jobs previously lived under a single
- stage: release. In Azure DevOps, only stages are individually selectable at queue time (the "Stages to run" picker) — jobs are not. So queuing the release published all three packages at once.That breaks this repo's release, because the packages ship at different versions with a hard ordering constraint:
packages/durabletask-js@microsoft/durabletask-jspackages/durabletask-js-azuremanaged@microsoft/durabletask-js-azuremanagedpackages/azure-functions-durabledurable-functionspackages/azure-functions-durable/package.jsonpins"@microsoft/durabletask-js": "0.4.0"exactly, so core must be on npm before the compat package. Publishing them together (or compat first) puts an uninstallable package on the registry.Fix: split the single stage into three, one job each, mirroring
durabletask-python's already-shipped layout:release_durabletask_js— core; no dependencyrelease_durabletask_js_azuremanaged—dependsOn: release_durabletask_jsrelease_durable_functions—dependsOn: release_durabletask_jsBoth dependents depend on core only, not on each other (siblings, not a serial chain). Because ADO skips a de-selected stage at queue time, the operator can release core alone now and a dependent later — the dependent stage then runs on its own.
This is a pure structural refactor: every
EsrpRelease@9input and each job'stemplateContextis preserved byte-for-byte (the three ESRP input blocks and the threetemplateContextblocks hash-identical toorigin/main). Noenvironment:,condition:, or new ESRP input was added.B12 — official build runs the supported Node (
eng/templates/build.yml)The build that produces the shipped
.tgzartifacts installed Node viaNodeTool@0versionSpec: 20.x, but all packages declare"engines": { "node": ">=22.0.0" }and GitHub CI only tests 22.x/24.x. So the runtime that builds the released artifacts was never covered by the green CI signal and ran a Node the packages call unsupported. Changed20.x→22.x(the version CI already exercises). This is the only Node-version reference ineng/.Out of scope
packages/**changes..github/workflows/prepare-release.yaml(that is a separate PR).