Make prepare-release workflow per-package - #335
Conversation
The prepare-release workflow hardcoded two package paths and a single version namespace, so it could not release the new durable-functions compat package without destructively bumping unrelated packages to the wrong version and namespace. Running it with 4.0.0-beta.1 would catapult @microsoft/durabletask-js from 0.4.x to 4.0.0-beta.1, bump azuremanaged to 4.0.0-beta.1, leave azure-functions-durable untouched, and tag a mislabeled v4.0.0-beta.1. An npm name+version pair can never be reused (even after unpublish), so reaching npm that way is irreversible. Rework the workflow to release exactly one selected package at a time: - Add a required `package` choice input (durabletask-js, durabletask-js-azuremanaged, azure-functions-durable) and an early "Resolve package metadata" step mapping it to pkg_dir, npm_name, tag_prefix (v / azuremanaged-v / functions-v) and changelog_path. - Thread those outputs through every step: read the selected package's version, scope the latest-tag glob to the package's tag prefix, bump only the selected package.json, write the package's changelog, and create release/<tag_prefix><version> plus a <tag_prefix><version> tag. - Delete the azuremanaged peerDependencies['@microsoft/durabletask-js'] rewrite: packages now release independently, so bumping a >=0.3.0 floor on every core release no longer makes sense. - Before releasing azure-functions-durable, verify its pinned @microsoft/durabletask-js dependency actually exists on the public npm registry, failing the run otherwise (core is 0.4.0 in-repo but npm's latest is 0.3.0, which would ship an uninstallable hard dependency). - Print the exact publish command in the run summary, deriving the dist-tag from the version: `npm publish --tag preview` for prereleases so they do not move `latest`, plain `npm publish` otherwise. scripts/update-changelog.js gains an optional 4th positional argument for the target changelog path (default CHANGELOG.md), so the compat package's packages/azure-functions-durable/CHANGELOG.md can be updated without changing existing 3-argument behavior or the `## Upcoming` logic. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d86f5f69-4e1a-4c1d-b017-5e290c85cc05
There was a problem hiding this comment.
Pull request overview
This PR reworks the prepare-release GitHub Actions workflow to make release preparation package-scoped (core, azuremanaged, or azure-functions-durable) to prevent accidental cross-package version/tag churn, and updates the changelog update script to support writing to a non-default changelog path.
Changes:
- Adds a required
packageinput and resolves package-specific metadata (directory, npm name, tag prefix, changelog path) to scope every step to the selected package. - Updates tagging/branching conventions to use per-package tag prefixes and
release/<tag_prefix><version>branches, and improves the summary with package-scoped publish guidance. - Extends
scripts/update-changelog.jswith an optional target changelog path argument.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
scripts/update-changelog.js |
Adds support for updating a specified changelog file instead of always CHANGELOG.md. |
.github/workflows/prepare-release.yaml |
Implements per-package release preparation flow (version bump, changelog generation, tagging/branching, and publish guidance). |
| const changelogContent = fs.readFileSync(changelogFile, 'utf8').trim(); | ||
| let content = fs.readFileSync('CHANGELOG.md', 'utf8'); | ||
| let content = fs.readFileSync(targetChangelog, 'utf8'); | ||
|
|
| echo "Manually create a PR from **${BRANCH_NAME}** → **main** with title: **Release v${NEW_VERSION}**" >> $GITHUB_STEP_SUMMARY | ||
| echo "Manually create a PR from **${BRANCH_NAME}** → **main** with title: **Release ${NPM_NAME}@${NEW_VERSION}**" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "[Create PR](https://github.com/microsoft/durabletask-js/compare/main...${BRANCH_NAME}?expand=1&title=Release+${NPM_NAME}@${NEW_VERSION})" >> $GITHUB_STEP_SUMMARY |
Add `publishConfig.registry = https://registry.npmjs.org/` to all three publishable packages (@microsoft/durabletask-js, @microsoft/durabletask-js-azuremanaged, durable-functions). The repo has no committed .npmrc; root package.json's `preinstall` hook (scripts/preinstallNpmrc.js) generates a gitignored .npmrc pointing at the azfunc Azure DevOps feed for @microsoft.com users and azfunc CI, so `npm publish` from a Microsoft machine would otherwise target that feed instead of public npm. publishConfig travels with the package and pins the registry regardless of the publishing machine's .npmrc. prepare-release.yaml: - Correct the false comment in the "Verify pinned core dependency" step: the repo does not commit an .npmrc; the preinstall hook generates a gitignored one. Keep the explicit --registry flag (still needed). - Print the publish command with an explicit --registry https://registry.npmjs.org/ (belt-and-braces so a copied command is safe even if publishConfig is ever dropped). durabletask-js: add `prepublishOnly: npm run build && npm run test` (the only publishable package without a build/test publish guard), matching the string used by the other two packages verbatim. Core's test suite is backend-independent (67 suites / 1176 tests pass with no sidecar). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d86f5f69-4e1a-4c1d-b017-5e290c85cc05
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
.github/workflows/prepare-release.yaml:132
grep -v "^${TAG_PREFIX}${NEW_VERSION}$"treats.(and other regex chars) in NEW_VERSION as regex metacharacters, so it can exclude the wrong tag(s) (and not just the exact tag being created). Use fixed-string matching instead for reliable re-runs.
LATEST_TAG=$(git tag -l "${TAG_PREFIX}*" --sort=-v:refname | \
grep -v "^${TAG_PREFIX}${NEW_VERSION}$" | head -n 1)
scripts/update-changelog.js:20
- This script isn't idempotent: re-running for the same version inserts a second
## v<version>section. Also, if the target changelog begins with a top-level header (e.g.# Changelogin packages/azure-functions-durable/CHANGELOG.md), the current prepend path moves that header below the new sections. Consider preserving a leading H1 and replacing any existing version section before inserting.
const changelogContent = fs.readFileSync(changelogFile, 'utf8').trim();
let content = fs.readFileSync(targetChangelog, 'utf8');
const newSection = `## v${version} (${releaseDate})
packages/durabletask-js/package.json:20
- The PR description says this change is "workflow + changelog script only", but this PR also modifies package manifests (e.g. adds
prepublishOnlyandpublishConfig.registry). Either update the PR description/scope to explicitly include these package.json changes, or revert them if they’re unintended.
"test:unit": "jest test --runInBand --detectOpenHandles",
"prepublishOnly": "npm run build && npm run test"
},
…correct WhenAll/#317/publishConfig update-changelog.js: a release now PROMOTES the curated `## Upcoming` body into the new `## v<version>` section instead of discarding it (fixes silent data loss where curated notes were overwritten by the generated commit list). Empty scaffold subsections (`### New` / `### Fixes` with no body) are dropped, so cutting a release with an untouched Upcoming section is byte-for-byte identical to before. The no-Upcoming fallback, the final Upcoming reset, the 4th-arg target path, and `## v` boundary detection are unchanged. Verified with scratch runs across four cases (empty scaffold diff-identical to the pre-change script; curated Breaking-changes block promoted; no-Upcoming fallback; 3-arg default target). CHANGELOG.md: fill `## Upcoming` with a `### Breaking changes` section for the two core 0.4.0 changes -- whenAll no longer fails fast (throws an AggregateError only after every child is terminal; fixes #301) and default sub-orchestration instance IDs derive from the parent execution ID (with a legacy fallback when executionId is empty). New/Fixes left as empty scaffold for the workflow to append. publishConfig: add `access: public` to the two scoped packages (@microsoft/durabletask-js, @microsoft/durabletask-js-azuremanaged) so a first publish cannot fail `restricted`; omitted for the unscoped durable-functions where access is meaningless. Docs: - azure-functions-durable/README.md: the v3 df.lock / isLocked surface is not supported and not planned (#317 is closed not_planned; the doc PR was closed unmerged) -- drop the dead tracking-issue pointer. Add a Requirements section documenting the Functions extension-bundle floor (GA [4.36.0, 5.0.0) or Preview [4.29.0, 5.0.0)); earlier GA v4 bundles lack the durable gRPC endpoint and cause a silent ~60s starter hang. - copilot-instructions.md: correct the WhenAll description in the task hierarchy tree and the renamed "WhenAll Wait-All Behavior" section -- it completes only when every child is terminal and aggregates failures into an AggregateError, not fail-fast. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d86f5f69-4e1a-4c1d-b017-5e290c85cc05
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (5)
scripts/update-changelog.js:18
- prepare-release now points azure-functions-durable at packages/azure-functions-durable/CHANGELOG.md, which currently starts with a top-level “# Changelog” header and a “## TBD” placeholder (no “## Upcoming”). With the current logic, the script will prepend its own “## Upcoming/## v…” sections above that header and leave the placeholder content behind, producing a malformed/duplicated changelog.
const changelogContent = fs.readFileSync(changelogFile, 'utf8').trim();
let content = fs.readFileSync(targetChangelog, 'utf8');
scripts/update-changelog.js:56
- The script now supports promoting “### Breaking changes” from Upcoming, and the repo’s root CHANGELOG.md has added that scaffold. However, the Upcoming reset template drops the Breaking changes heading, so after the next release it will disappear from the file format.
// Reset the Upcoming section to empty
content = content.replace(/## Upcoming[\s\S]*?(?=\n## v)/, '## Upcoming\n\n### New\n\n### Fixes\n\n');
CHANGELOG.md:7
- The PR description says “No CHANGELOG content” is in scope, but this change adds substantive release notes under Upcoming (e.g., the new “### Breaking changes” entries). Either update the PR description/scope to include these changelog edits, or revert these content changes to keep the PR limited to workflow + script updates.
### Breaking changes
- **`whenAll` no longer fails fast.** A `whenAll` task — and therefore the Durable Functions compat
`context.df.Task.all()`, which forwards straight to it — now completes only after **every** child
is terminal, instead of the moment the first child fails. Two user-visible effects: (1) **timing** —
packages/durabletask-js/package.json:20
- The PR description frames the change as “workflow + changelog script only / no package.json changes”, but this diff adds a prepublishOnly hook (build+test) and publishConfig. If intentional, the PR description should be updated to reflect that package publish behavior is also being changed; otherwise these edits should be moved to a separate PR.
"test:unit": "jest test --runInBand --detectOpenHandles",
"prepublishOnly": "npm run build && npm run test"
},
.github/workflows/prepare-release.yaml:132
- The tag-exclusion filter uses regex grep with an unescaped version string. Versions contain '.' and '-' which are regex metacharacters, so this can exclude unintended tags and select the wrong baseline. Use fixed-string whole-line matching instead.
LATEST_TAG=$(git tag -l "${TAG_PREFIX}*" --sort=-v:refname | \
grep -v "^${TAG_PREFIX}${NEW_VERSION}$" | head -n 1)
… seed compat changelog 5A: The "Generate changelog diff" step in prepare-release.yaml ran `git log "$LATEST_TAG"..HEAD` with no path filter, so a release listed commits from every package. For a package with no release tag yet (compat, azuremanaged) LATEST_TAG falls back to the repo's initial commit, so the list became the entire repo history (193 commits for compat). Add a `-- "$PKG_DIR"` path filter (after the `--` separator) so a release only lists commits that touched that package. Effect: compat 193->5, azuremanaged 193->20, core (v0.3.0..HEAD) 93->66. The existing `--no-merges`, the `(#N)`->markdown-link sed, the `- ` prefix, and the empty-line grep are unchanged. 5B: update-changelog.js promotion (added in the prior release-hygiene commit) skipped any lead-in body text written directly under `## Upcoming` before the first `### ` subsection, silently dropping it. Promote that lead-in too, placed ahead of the promoted subsections; whitespace-only lead-in still promotes nothing, so the empty-scaffold case stays byte-identical to the pre-promotion script. 5C: Replace the compat package's placeholder CHANGELOG body with a curated `## Upcoming` section for 4.0.0-beta.1 (a preview lead-in + install fence, then Why-this-is-a-new-major-version / Requirements / Underlying packages / Breaking changes / Added / Known limitations). The release workflow promotes this and appends the scoped commit list as `### Changes`; it does not yet carry a `## v` heading. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d86f5f69-4e1a-4c1d-b017-5e290c85cc05
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
packages/azure-functions-durable/README.md:46
- This README says there is “no tracking issue” for the removed v3 entity-lock API, but issue #317 exists (closed as not planned). The statement is factually incorrect and should either link to #317 (not planned) or remove the claim about tracking.
`context.entities.isInCriticalSection()`. The v3 `df.lock` / `isLocked` surface is **not supported
and not planned** — there is no tracking issue.
.github/workflows/prepare-release.yaml:132
- The tag-exclusion filter uses a regex pattern with unescaped version text (e.g., dots are wildcards). This can accidentally exclude unrelated tags and pick the wrong baseline for changelog generation. Use fixed-string matching instead.
LATEST_TAG=$(git tag -l "${TAG_PREFIX}*" --sort=-v:refname | \
grep -v "^${TAG_PREFIX}${NEW_VERSION}$" | head -n 1)
…release sort 7A: Rename the azure-functions-durable release tag prefix from `functions-v` to `durable-functions-v`. A git tag should name the package a reader can look up on the registry; our npm package is `durable-functions` (`azure-functions-durable` is only the directory name, which drove the original choice). This mirrors how `azuremanaged-v` matches the npm-name suffix of `@microsoft/durabletask-js-azuremanaged`; core `v` and azuremanaged `azuremanaged-v` already match durabletask-python, only compat diverged. The resulting tag is `durable-functions-v4.0.0-beta.1` and branch `release/durable-functions-v4.0.0-beta.1` (valid ref). No `functions-v*` tag has ever existed, so nothing to retag. 7B: Add `-c versionsort.suffix=-` to the latest-tag lookup so git orders a prerelease (X-beta.1) below its own GA (X). With git's default config, `--sort=-v:refname` ranks X-beta.1 ABOVE X, so the first post-GA release (e.g. X.0.1) would resolve LATEST_TAG to the prerelease baseline and re-list every commit already shipped in GA. This is a pre-existing flaw independent of 7A. The flag is scoped to that single tag-listing command only; not set globally. Only .github/workflows/prepare-release.yaml changes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d86f5f69-4e1a-4c1d-b017-5e290c85cc05
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (5)
scripts/update-changelog.js:62
- The Upcoming-section reset scaffold drops the new "### Breaking changes" heading that now exists in CHANGELOG.md. After the next release cut, the script will overwrite Upcoming with only New/Fixes, forcing maintainers to re-add Breaking changes manually each time.
// Reset the Upcoming section to empty
content = content.replace(/## Upcoming[\s\S]*?(?=\n## v)/, '## Upcoming\n\n### New\n\n### Fixes\n\n');
.github/workflows/prepare-release.yaml:8
- The workflow header comment lists the tag prefix for durable-functions as "durable-functions-v", but the PR description specifies "functions-v". This inconsistency makes it easy for operators to create tags in an unexpected namespace.
# 3. Updates the package's changelog file and creates a release branch + package-scoped tag
# Packages are versioned and tagged independently (tag prefixes: v, azuremanaged-v, durable-functions-v).
# After the workflow completes, manually open a PR from the release branch to main, then publish
.github/workflows/prepare-release.yaml:67
- For the azure-functions-durable package, TAG_PREFIX is set to "durable-functions-v", but the PR description (and its tag-glob backward-compat notes) describe the namespace as "functions-v". If the intended prefix is "functions-v", this needs to be corrected here or the PR description updated to match.
azure-functions-durable)
PKG_DIR="packages/azure-functions-durable"
NPM_NAME="durable-functions"
TAG_PREFIX="durable-functions-v"
CHANGELOG_PATH="packages/azure-functions-durable/CHANGELOG.md"
CHANGELOG.md:15
- The PR description says CHANGELOG content is out of scope ("No CHANGELOG content"), but this change adds new breaking-change entries under the Upcoming section. Either the PR description should be updated to reflect this expanded scope, or the CHANGELOG edits should be moved to a separate PR.
### Breaking changes
- **`whenAll` no longer fails fast.** A `whenAll` task — and therefore the Durable Functions compat
`context.df.Task.all()`, which forwards straight to it — now completes only after **every** child
is terminal, instead of the moment the first child fails. Two user-visible effects: (1) **timing** —
the orchestrator resumes past the `whenAll` only once all siblings finish, not at the first failure;
(2) **error type** — on failure it throws a JS-native `AggregateError` (`.errors` populated, message
of the form `"<N> of <M> tasks in the whenAll failed: <child messages joined by '; '>"`) instead of
re-throwing the first child's own exception. This fixes a lost-failure bug where a later failing
sibling was dropped against an already-terminal `whenAll`
([#301](https://github.com/microsoft/durabletask-js/issues/301)). Fan-out/fan-in is the canonical
Durable Functions pattern, so review any `Task.all()` error handling that relied on early completion
or on catching a single child error.
.github/workflows/prepare-release.yaml:136
- The tag-exclusion filter uses grep with a regex pattern built from ${TAG_PREFIX}${NEW_VERSION}. Since grep treats '.' and other characters as regex metacharacters, versions like 0.2.0-beta.1 can match unintended tag names. Use fixed-string matching instead.
LATEST_TAG=$(git -c versionsort.suffix=- tag -l "${TAG_PREFIX}*" --sort=-v:refname | \
grep -v "^${TAG_PREFIX}${NEW_VERSION}$" | head -n 1)
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
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
packages/azure-functions-durable/README.md:46
- The README says there is no tracking issue for restoring the v3
df.lock/isLockedsurface, but issue #317 exists (it’s closed asnot_planned). This should either reference #317 or remove the “no tracking issue” claim to avoid misleading readers.
`context.entities.isInCriticalSection()`. The v3 `df.lock` / `isLocked` surface is **not supported
and not planned** — there is no tracking issue.
.github/workflows/prepare-release.yaml:67
- PR description specifies the compat package tag prefix as
functions-v, but this workflow sets it todurable-functions-v. Please align the tag namespace across the PR description, workflow, and release documentation (and the explanatory comments about prefixes).
azure-functions-durable)
PKG_DIR="packages/azure-functions-durable"
NPM_NAME="durable-functions"
TAG_PREFIX="durable-functions-v"
CHANGELOG_PATH="packages/azure-functions-durable/CHANGELOG.md"
.github/workflows/prepare-release.yaml:249
git tag -f+git push -f origin <tag>will move an existing release tag if it already exists, which can rewrite release history. Safer behavior is to only create the tag if it doesn’t exist, or allow it only when it already points to the same commit; otherwise fail with a clear error.
git tag -f "$TAG_NAME"
# Push branch and tag (force to handle re-runs)
git push -f origin "$BRANCH_NAME"
git push -f origin "$TAG_NAME"
|
This PR is being split into four smaller, independently reviewable PRs, each branched off current File → carrier PR
Provenance: for #337 / #338 / #339 the content is byte-identical to this branch at Leaving this PR open so you can confirm nothing was dropped, then close it at your discretion. |
Why this is not cosmetic — the current workflow is a destructive trap
.github/workflows/prepare-release.yamlonmaincannot express a per-packagerelease, and running it as-is against the new
durable-functionscompat packageis destructive and irreversible.
Its "Update package versions" step hardcodes exactly two paths and assigns the
single
$NEW_VERSIONto both. If an operator runs the workflow with, say,4.0.0-beta.1intending to release the compat package:packages/durabletask-js0.4.0→4.0.0-beta.1(core catapulted from 0.4.x to 4.x)packages/durabletask-js-azuremanaged0.3.0→4.0.0-beta.1packages/azure-functions-durable→ untouched (the package actually being released)v4.0.0-beta.1(wrong namespace)If any of that ever reaches npm it is irreversible — npm never lets a
name+version pair be reused, even after
unpublish.What this PR changes (workflow + changelog script only)
Reworks the workflow to release one selected package at a time:
New required
packagechoice input (durabletask-js,durabletask-js-azuremanaged,azure-functions-durable) plus an early"Resolve package metadata" step mapping the selection to
pkg_dir,npm_name,tag_prefix,changelog_path:vazuremanaged-vfunctions-vThreads those outputs through every step: reads the selected package's
current version, scopes the latest-tag glob to the package's
tag_prefix(excluding the tag being created), bumps only the selected
package.json,writes the selected changelog, and creates
release/<tag_prefix><version>+ a<tag_prefix><version>tag.Deletes the azuremanaged
peerDependencies['@microsoft/durabletask-js']>=$NEW_VERSIONrewrite — packages now version independently, so bumping a>=0.3.0floor on every core release no longer makes sense.New guard (azure-functions-durable only): before creating the branch,
verifies the package's pinned
@microsoft/durabletask-jsdependency isactually published on the public npm registry, failing the run otherwise.
Core is
0.4.0in-repo but npm'slatestis still0.3.0, so publishingdurable-functionstoday would ship a package whose hard dependency cannot beinstalled (a failure mode already predicted on Add
durable-functions@4.0.0— Azure Functions Durable provider on the gRPC core (+ core host helpers, E2E CI, and release pipeline) #282).Summary prints the exact publish command, deriving the dist-tag from the
version:
npm publish --tag previewfor prereleases (so they do not movelatest, with a warning), plainnpm publishotherwise.scripts/update-changelog.jsgains an optional 4th positional argument forthe target changelog path (default
CHANGELOG.md), sopackages/azure-functions-durable/CHANGELOG.mdcan be updated without changingexisting 3-argument behavior or the
## Upcominginsertion/reset logic.Out of scope (deliberately)
No
package.jsonversion bumps, no CHANGELOG content, and no npm publishstep (publishing needs a separate decision on
NPM_TOKENvs OIDC trustedpublishing). Only the workflow and the changelog script change.
Notes on the tag-glob (backward compatibility)
With
tag_prefix=v,git tag -l "v*"still matches the legacy core tags(
v0.1.0-alpha.1…v0.3.0) — intended and backward compatible — and nevermatches the new
azuremanaged-v*/functions-v*namespaces (they start witha/f, notv).