Skip to content

Commit 5543296

Browse files
authored
Add release pipeline/doc + fix build pipeline (#103)
* Add release process documentation for npm packages * Enhance release process: update prepare-release workflow, add publishing steps, and create release pipeline for durabletask-js packages * Make release branch and tag creation idempotent in prepare-release workflow
1 parent 5049269 commit 5543296

File tree

4 files changed

+301
-29
lines changed

4 files changed

+301
-29
lines changed

.github/workflows/prepare-release.yaml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,21 +158,21 @@ jobs:
158158
git config user.name "github-actions[bot]"
159159
git config user.email "github-actions[bot]@users.noreply.github.com"
160160
161-
# Create and checkout release branch
162-
git checkout -b "$BRANCH_NAME"
161+
# Create and checkout release branch (idempotent)
162+
git checkout -B "$BRANCH_NAME"
163163
164164
# Stage and commit changes
165165
git add packages/durabletask-js/package.json
166166
git add packages/durabletask-js-azuremanaged/package.json
167167
git add CHANGELOG.md
168168
git commit -m "Release v${NEW_VERSION}"
169169
170-
# Create release tag
171-
git tag "v${NEW_VERSION}"
170+
# Create release tag (idempotent)
171+
git tag -f "v${NEW_VERSION}"
172172
173-
# Push branch and tag
174-
git push origin "$BRANCH_NAME"
175-
git push origin "v${NEW_VERSION}"
173+
# Push branch and tag (force to handle re-runs)
174+
git push -f origin "$BRANCH_NAME"
175+
git push -f origin "v${NEW_VERSION}"
176176
177177
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
178178
echo "Created branch $BRANCH_NAME and tag v${NEW_VERSION}"
@@ -212,8 +212,7 @@ jobs:
212212
--title "Release v${NEW_VERSION}" \
213213
--body-file /tmp/pr_body.md \
214214
--base main \
215-
--head "$BRANCH_NAME" \
216-
--label "release"
215+
--head "$BRANCH_NAME"
217216
218217
- name: Summary
219218
run: |

doc/release_process.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Release Process
2+
3+
This document describes how to cut a new release of the `@microsoft/durabletask-js` and `@microsoft/durabletask-js-azuremanaged` npm packages.
4+
5+
## Overview
6+
7+
| Package | npm |
8+
|---|---|
9+
| `@microsoft/durabletask-js` | [npmjs](https://www.npmjs.com/package/@microsoft/durabletask-js) |
10+
| `@microsoft/durabletask-js-azuremanaged` | [npmjs](https://www.npmjs.com/package/@microsoft/durabletask-js-azuremanaged) |
11+
12+
This is an **npm workspaces** monorepo. There is no automated publish pipeline — the official build (`eng/ci/official-build.yml`) produces signed `.tgz` artifacts which are then published to npm manually.
13+
14+
### Versioning Policy
15+
16+
**All packages are released with the same version number.** This simplifies dependency management and makes it clear which versions are compatible. When cutting a release, both packages are bumped to the same version regardless of whether both have changes.
17+
18+
## Versioning Scheme
19+
20+
We follow [semver](https://semver.org/) with optional pre-release tags:
21+
22+
```
23+
X.Y.Z-alpha.N → X.Y.Z-beta.N → X.Y.Z-rc.N → X.Y.Z (stable)
24+
```
25+
26+
| Version Type | Example | npm Tag |
27+
|---|---|---|
28+
| Alpha | `0.1.0-alpha.1` | `--tag alpha` |
29+
| Beta | `0.1.0-beta.1` | `--tag beta` |
30+
| Release Candidate | `0.1.0-rc.1` | `--tag next` |
31+
| Stable | `0.1.0` | *(no tag, becomes `latest`)* |
32+
33+
## Automated Release Preparation (Recommended)
34+
35+
Use the **Prepare Release** GitHub Action to automate the release preparation process.
36+
37+
### Running the Workflow
38+
39+
1. Go to **Actions****Prepare Release** in GitHub
40+
2. Click **Run workflow**
41+
3. Optionally specify a version (e.g., `0.2.0-beta.1`). Leave empty to auto-increment.
42+
4. Click **Run workflow**
43+
44+
### What the Workflow Does
45+
46+
1. **Determines the next version**: If not specified, auto-increments the current version
47+
2. **Generates changelog**: Uses `git diff` to find changes between `main` and the last release tag
48+
3. **Updates package versions**: Bumps `version` in all `package.json` files to the same version
49+
4. **Updates CHANGELOG.md**: Adds a new version section with the discovered changes
50+
5. **Creates a release branch**: `release/vX.Y.Z`
51+
6. **Creates a release tag**: `vX.Y.Z`
52+
7. **Opens a pull request**: For review before merging to `main`
53+
54+
After the PR is merged, follow the **Publishing** steps below to build and publish.
55+
56+
## Publishing (After Release PR is Merged)
57+
58+
After the release PR is merged to `main`, follow these steps to build, sign, and publish the packages.
59+
60+
### Step 1: Run the Code Mirror Pipeline
61+
62+
Manually trigger the code mirror pipeline to sync the release to the internal ADO repo:
63+
64+
**Pipeline**: [durabletask-js code mirror](https://dev.azure.com/azfunc/internal/_build?definitionId=1004)
65+
66+
Run it on the `main` branch (which now contains the release commit).
67+
68+
### Step 2: Run the Official Build Pipeline
69+
70+
Trigger the official build pipeline on the release tag/commit/branch to produce signed `.tgz` artifacts:
71+
72+
**Pipeline**: [durabletask-js.official](https://dev.azure.com/azfunc/internal/_build?definitionId=1012&_a=summary)
73+
74+
1. Click **Run pipeline**
75+
2. Select the release branch or tag (e.g., `release/vX.Y.Z` or tag `vX.Y.Z`)
76+
3. Wait for it to complete
77+
4. Verify the `drop` artifact contains correctly versioned `.tgz` files:
78+
- `buildoutputs/durabletask-js/microsoft-durabletask-js-X.Y.Z.tgz`
79+
- `buildoutputs/durabletask-js-azuremanaged/microsoft-durabletask-js-azuremanaged-X.Y.Z.tgz`
80+
81+
### Step 3: Run the Release Pipeline
82+
83+
Trigger the release pipeline to publish the signed packages to npm via ESRP. The pipeline has separate release jobs for each package:
84+
85+
**Pipeline**: eng/ci/release.yml (link to update soon)
86+
87+
1. Click **Run pipeline**
88+
2. Select the build from Step 2 as the source pipeline artifact
89+
3. Approve the ESRP release when prompted (one approval per package)
90+
91+
### Step 4: Verify npm Publish
92+
93+
```bash
94+
npm view @microsoft/durabletask-js versions
95+
npm view @microsoft/durabletask-js-azuremanaged versions
96+
```
97+
98+
### Step 5: Create a GitHub Release
99+
100+
Go to [GitHub Releases](https://github.com/microsoft/durabletask-js/releases) and create a new release:
101+
102+
- **Tag**: `vX.Y.Z`
103+
- **Title**: `vX.Y.Z`
104+
- **Description**: Copy the relevant section from `CHANGELOG.md`
105+
- **Pre-release**: Check this box for alpha/beta/rc releases
106+
107+
## Manual Release Process (Alternative)
108+
109+
If you prefer to prepare the release manually, follow these steps.
110+
111+
### 1. Determine the Next Version
112+
113+
Review merged PRs since the last release tag to understand what's shipping. Choose an appropriate version number following semver.
114+
115+
### 2. Update Package Versions
116+
117+
Bump the `"version"` field in **both** package.json files to the **same version**:
118+
119+
```bash
120+
# Edit packages/durabletask-js/package.json → "version": "X.Y.Z"
121+
# Edit packages/durabletask-js-azuremanaged/package.json → "version": "X.Y.Z"
122+
```
123+
124+
Also update the peer dependency in `packages/durabletask-js-azuremanaged/package.json`:
125+
126+
```jsonc
127+
"peerDependencies": {
128+
"@microsoft/durabletask-js": ">=X.Y.Z" // ← same version
129+
}
130+
```
131+
132+
### 3. Update CHANGELOG.md
133+
134+
Move items from the `## Upcoming` section into a new versioned section. Follow the existing format:
135+
136+
```markdown
137+
## Upcoming
138+
139+
### New
140+
<!-- empty or future items -->
141+
142+
## vX.Y.Z
143+
144+
### New
145+
- Feature A ([#NN](https://github.com/microsoft/durabletask-js/pull/NN))
146+
147+
### Fixes
148+
- Fix B ([#NN](https://github.com/microsoft/durabletask-js/pull/NN))
149+
150+
### Breaking Changes
151+
- Breaking change C ([#NN](https://github.com/microsoft/durabletask-js/pull/NN))
152+
```
153+
154+
### 4. Verify Build & Tests Pass Locally
155+
156+
```bash
157+
npm ci
158+
npm run build
159+
npm test
160+
npm run lint
161+
```
162+
163+
### 5. Create a Release PR
164+
165+
Create a branch (e.g., `release/vX.Y.Z`), commit the version bumps and changelog update, and open a PR against `main`. The PR title should follow: `Release vX.Y.Z`.
166+
167+
### 6. Merge and Tag
168+
169+
After the PR is approved and merged to `main`:
170+
171+
```bash
172+
git checkout main
173+
git pull
174+
git tag vX.Y.Z
175+
git push origin vX.Y.Z
176+
```
177+
178+
Then follow the **Publishing** steps above (Steps 1-5).
179+
180+
## Quick Reference: npm Dist Tags
181+
182+
| Tag | When to use |
183+
|---|---|
184+
| `--tag alpha` | For `X.Y.Z-alpha.N` versions |
185+
| `--tag beta` | For `X.Y.Z-beta.N` versions |
186+
| `--tag next` | For release candidates (`X.Y.Z-rc.N`) |
187+
| *(no tag / `latest`)* | For stable GA releases only |
188+
189+
## Rolling Back a Release
190+
191+
If a release has critical issues:
192+
193+
1. **Deprecate on npm**: `npm deprecate @microsoft/durabletask-js@X.Y.Z "Critical bug, use X.Y.Z+1"`
194+
2. **Unpublish** (within 72 hours only): `npm unpublish @microsoft/durabletask-js@X.Y.Z`
195+
3. Cut a new patch release with the fix.

eng/ci/release.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
pr: none
2+
trigger: none
3+
4+
resources:
5+
repositories:
6+
- repository: 1ESPipelineTemplates
7+
type: git
8+
name: 1ESPipelineTemplates/1ESPipelineTemplates
9+
ref: refs/tags/release
10+
pipelines:
11+
- pipeline: DurableTaskJSBuildPipeline
12+
source: durabletask-js.official
13+
branch: main
14+
15+
extends:
16+
template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
17+
parameters:
18+
pool:
19+
name: 1es-pool-azfunc
20+
image: 1es-ubuntu-22.04
21+
os: linux
22+
23+
stages:
24+
- stage: release
25+
jobs:
26+
- job: durabletask_js
27+
displayName: 'Release @microsoft/durabletask-js'
28+
templateContext:
29+
type: releaseJob
30+
isProduction: true
31+
inputs:
32+
- input: pipelineArtifact
33+
pipeline: DurableTaskJSBuildPipeline
34+
artifactName: drop
35+
targetPath: $(System.DefaultWorkingDirectory)/drop
36+
37+
steps:
38+
- task: SFP.release-tasks.custom-build-release-task.EsrpRelease@9
39+
displayName: 'ESRP Release @microsoft/durabletask-js'
40+
inputs:
41+
connectedservicename: 'dtfx-internal-esrp-prod'
42+
usemanagedidentity: true
43+
keyvaultname: 'durable-esrp-akv'
44+
signcertname: 'dts-esrp-cert'
45+
clientid: '0b3ed1a4-0727-4a50-b82a-02c2bd9dec89'
46+
folderlocation: '$(System.DefaultWorkingDirectory)/drop/buildoutputs/durabletask-js'
47+
owners: 'wangbill@microsoft.com'
48+
approvers: 'kaibocai@microsoft.com'
49+
mainpublisher: 'durabletask-js'
50+
51+
- job: durabletask_js_azuremanaged
52+
displayName: 'Release @microsoft/durabletask-js-azuremanaged'
53+
templateContext:
54+
type: releaseJob
55+
isProduction: true
56+
inputs:
57+
- input: pipelineArtifact
58+
pipeline: DurableTaskJSBuildPipeline
59+
artifactName: drop
60+
targetPath: $(System.DefaultWorkingDirectory)/drop
61+
62+
steps:
63+
- task: SFP.release-tasks.custom-build-release-task.EsrpRelease@9
64+
displayName: 'ESRP Release @microsoft/durabletask-js-azuremanaged'
65+
inputs:
66+
connectedservicename: 'dtfx-internal-esrp-prod'
67+
usemanagedidentity: true
68+
keyvaultname: 'durable-esrp-akv'
69+
signcertname: 'dts-esrp-cert'
70+
clientid: '0b3ed1a4-0727-4a50-b82a-02c2bd9dec89'
71+
folderlocation: '$(System.DefaultWorkingDirectory)/drop/buildoutputs/durabletask-js-azuremanaged'
72+
owners: 'wangbill@microsoft.com'
73+
approvers: 'kaibocai@microsoft.com'
74+
mainpublisher: 'durabletask-js'

eng/templates/build.yml

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,44 @@ jobs:
1616
versionSpec: 20.x
1717
displayName: "Install Node.js"
1818

19-
# Build main package
19+
# Install all workspace dependencies
2020
- script: npm ci
2121
displayName: "npm ci"
22-
- script: npm run prebuild
23-
displayName: "npm run prebuild"
22+
23+
# Build all packages (each workspace's build script runs its own prebuild)
2424
- script: npm run build
25-
displayName: "npm run build"
25+
displayName: "npm run build (all packages)"
26+
27+
# Run tests for all packages
28+
- script: npm test
29+
displayName: "npm test (all packages)"
30+
31+
# Prune dev dependencies so that only production dependencies are included in SBOM
2632
- script: npm prune --production
27-
displayName: "npm prune --production" # so that only production dependencies are included in SBOM
28-
- script: npm pack build/
29-
displayName: "pack npm package"
33+
displayName: "npm prune --production"
3034

31-
# Build azure-managed extension package
35+
# Pack @microsoft/durabletask-js
3236
- script: |
33-
cd packages/durabletask-js-azuremanaged
34-
npm ci
35-
npm run build
36-
npm run test
37-
npm prune --production
38-
displayName: "Build azure-managed extension"
37+
cd packages/durabletask-js
38+
npm pack
39+
displayName: "pack @microsoft/durabletask-js"
40+
41+
# Pack @microsoft/durabletask-js-azuremanaged
3942
- script: |
4043
cd packages/durabletask-js-azuremanaged
4144
npm pack
42-
displayName: "pack azure-managed extension"
45+
displayName: "pack @microsoft/durabletask-js-azuremanaged"
4346
47+
# Copy each package to its own staging subfolder
4448
- task: CopyFiles@2
45-
displayName: "Copy package to staging"
49+
displayName: "Copy durabletask-js to staging"
4650
inputs:
47-
SourceFolder: $(System.DefaultWorkingDirectory)
51+
SourceFolder: $(System.DefaultWorkingDirectory)/packages/durabletask-js
4852
Contents: "*.tgz"
49-
TargetFolder: $(Build.ArtifactStagingDirectory)/buildoutputs
53+
TargetFolder: $(Build.ArtifactStagingDirectory)/buildoutputs/durabletask-js
5054
- task: CopyFiles@2
51-
displayName: "Copy azure-managed extension to staging"
55+
displayName: "Copy durabletask-js-azuremanaged to staging"
5256
inputs:
5357
SourceFolder: $(System.DefaultWorkingDirectory)/packages/durabletask-js-azuremanaged
5458
Contents: "*.tgz"
55-
TargetFolder: $(Build.ArtifactStagingDirectory)/buildoutputs
59+
TargetFolder: $(Build.ArtifactStagingDirectory)/buildoutputs/durabletask-js-azuremanaged

0 commit comments

Comments
 (0)