Skip to content

fix: repair release workflow, cumulative changelog, and supply chain hardening#194

Merged
elantiguamsft merged 2 commits intomainfrom
fix/release-workflow-and-changelog
Apr 7, 2026
Merged

fix: repair release workflow, cumulative changelog, and supply chain hardening#194
elantiguamsft merged 2 commits intomainfrom
fix/release-workflow-and-changelog

Conversation

@JeromySt
Copy link
Copy Markdown
Member

@JeromySt JeromySt commented Apr 7, 2026

Summary

The automated release pipeline has been broken since at least v1.7.2 — every push-to-main workflow run fails at the Increment pre-release tag step, meaning all recent releases (v1.7.2 through v1.7.6) were created manually. This PR fixes the root cause, hardens the supply chain by eliminating all third-party GitHub Actions, and ensures the changelog is cumulative across releases.

Problems Fixed

1. Broken tag discovery (root cause of all release failures)

The workflow used git tag | sort --version-sort | tail -n1 to find the latest tag. GNU sort --version-sort incorrectly sorted the malformed tag v.1.5.5 (note the extra dot) as the highest version, ahead of legitimate tags like v1.7.6. The tag regex ^v([0-9]+\.[0-9]+\.[0-9]+)(-pre([0-9]+))?$ then failed to match, causing every run to exit with Invalid tag format.

Fix: Added a grep -E filter to select only well-formed vX.Y.Z(-preN) tags before sorting, so malformed tags like v.1.5.5 and 1.6.2 are excluded.

2. Third-party action supply chain risk

The workflow depended on three third-party actions from individual maintainers:

  • tj-actions/github-changelog-generator@v1.19
  • softprops/action-gh-release@v2
  • svenstaro/upload-release-action@v2

Each of these is a potential supply chain vector — a compromised release of any one could exfiltrate secrets or tamper with build artifacts.

Fix: Replaced all three with the gh CLI, which is pre-installed on every GitHub-hosted runner and maintained by GitHub:

Before (third-party) After (official)
tj-actions/github-changelog-generator@v1.19 gh api repos/.../releases/generate-notes + gh release list/view
softprops/action-gh-release@v2 gh release create
svenstaro/upload-release-action@v2 gh release upload

3. Deprecated APIs and actions

  • ::set-output (deprecated since Oct 2022, scheduled for removal) was used in 3 places → replaced with \
  • actions/create-release@v1 (archived, no longer maintained) → replaced with gh release create

4. Outdated action versions

Action Before After
actions/checkout v3 / v4 v6
actions/setup-dotnet v3 v5
actions/upload-artifact v4 v4 (already latest)
actions/download-artifact v4 v4 (already latest)

5. Cumulative changelog

Previously, the changelog was generated by a third-party action and committed to the repo. Since the org-level branch protection ruleset blocks direct pushes to main (even from GITHUB_TOKEN), this approach was already broken — PR #189 moved it to an artifact, but each release body only contained the delta.

New approach: The changelog is now built entirely from the GitHub API:

  1. gh api repos/.../releases/generate-notes generates the "What's Changed" delta for the new release
  2. gh release list + gh release view fetches the body text of all previous releases
  3. Both are combined into a single cumulative CHANGELOG.md artifact
  4. gh release create --notes-file uses it as the release body

Each release body now contains the full project history, not just the latest delta.

6. Stale CHANGELOG.md removed

The 797-line committed CHANGELOG.md was stale (last updated at v1.7.2) and no longer the source of truth. Replaced with a 5-line pointer to the Releases page.

What's NOT changed

  • Build matrix, test configuration, publish steps, and NuGet packaging are untouched
  • The semantic versioning logic (pre-release incrementing, tag collision retry) is preserved
  • The release_assets job structure and zip creation are unchanged

Testing

The workflow changes can only be fully validated by a push-to-main event. The PR itself will trigger the build job (unchanged) and the create_changelog job (which no-ops on PRs by design).

Jstatia and others added 2 commits April 7, 2026 14:19
Eliminate all third-party GitHub Actions to contain the supply chain.
Only official actions/* and the pre-installed gh CLI are used now.

Supply chain cleanup:
- Remove tj-actions/github-changelog-generator — replaced with gh API
  (repos/generate-notes) plus gh release list/view for cumulative history
- Remove softprops/action-gh-release — replaced with gh release create
- Remove svenstaro/upload-release-action — replaced with gh release upload

Action version upgrades:
- actions/checkout: v3/v4 -> v6
- actions/setup-dotnet: v3 -> v5
- actions/upload-artifact and download-artifact remain at v4 (latest)

Bug fixes:
- Filter tags with grep to only match well-formed vX.Y.Z(-preN) format,
  fixing the sort that returned malformed tag 'v.1.5.5' instead of v1.7.6
- Replace all deprecated '::set-output' with GITHUB_OUTPUT
- Remove unused upload_url output

Changelog is now cumulative: each release body includes the delta for the
current release (via GitHub generate-notes API) plus the full body text
of all previous releases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The changelog is now generated at release time via the GitHub API and
stored in each release body. The committed file is no longer needed as
the source of truth — point readers to the Releases page instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@elantiguamsft elantiguamsft merged commit 9a8f8b8 into main Apr 7, 2026
12 checks passed
@elantiguamsft elantiguamsft deleted the fix/release-workflow-and-changelog branch April 7, 2026 22:30
JeromySt pushed a commit that referenced this pull request Apr 8, 2026
Apply the same supply chain fixes from PR #194 to all remaining workflows:
- dotnet-v1.yml, dotnet-v2.yml: replace tj-actions, softprops, svenstaro
  with gh CLI equivalents; cumulative changelog via GitHub API
- codeql.yml, dependency-review.yml, rerelease.yml: bump action versions
- All workflows now use only official actions/* and gh CLI
- checkout@v6, setup-dotnet@v5 across the board

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants