Repository navigation
Add release workflow for versioning and publishing - #107
Merged
Merged
Conversation
Replaces the manual versioning steps with a Publish workflow, run from the Actions tab after merging a PR to main. It bumps the version, regenerates the documentation, tags the release, creates the GitHub release and pushes the package to NuGet. Leaving publish-to-nuget unchecked stops it short of NuGet. Documentation generation is a separate workflow so it can be run on its own, and publishing and release creation are reusable so a partially failed run can be resumed a step at a time. Release commits are authored by whoever triggered the run, and the tag records them as tagger; unresolvable actors fall back to the bot rather than failing. publish.sh is kept as a manual fallback, since it prompts for confirmation and cannot run in CI. README now documents the workflow as the primary path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Test failures do not block publication, release tagging follows a mutable branch, and manual version input permits shell injection.
3 open issues
What changed in this PR
Automates .NET SDK releases through GitHub Actions, retaining the manual publishing fallback.
Changes:
- Adds release orchestration and independently runnable publishing workflows.
- Adds version-management and git-attribution actions.
- Documents the automated release process.
| File | Description |
|---|---|
| README.md | Documents automated releases and manual fallback. |
| .github/workflows/publish.yml | Orchestrates versioning, documentation, tagging, and publishing. |
| .github/workflows/publish-nuget.yml | Builds and publishes NuGet packages. |
| .github/workflows/generate-docs.yml | Regenerates, uploads, and optionally commits documentation. |
| .github/workflows/create-github-release.yml | Creates releases with generated notes. |
| .github/actions/set-version/action.yml | Updates and verifies tracked versions. |
| .github/actions/next-version/action.yml | Resolves versions and checks existing tags. |
| .github/actions/git-identity/action.yml | Resolves release attribution with bot fallback. |
Review effort: Balanced
Validate the version in publish-nuget before use. The workflow can be dispatched directly, so the input has not been through the orchestrator's checks; it is now passed as env and required to be semver, so shell metacharacters cannot reach the script. Pin the release to an immutable revision. Each job previously re-resolved the branch, so a merge landing mid-release could enter the tag without having been built or validated. The bump commit's SHA is now threaded through documentation generation to the tag, and pushes use --force-with-lease so a branch that moved underneath stops the release instead of absorbing it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Alexey-Pavlov
previously approved these changes
Oct 22, 2026
Restores publish.yml and generate-docs.yml to their state before 10a8ffc. Checking out the bump commit by SHA left no origin/<branch> tracking ref, so the bare --force-with-lease docs push failed with "stale info" whenever the docs changed, blocking the tag and NuGet publish. Rather than add an explicit lease on top, drop the SHA threading entirely and follow constructorio-ui-plp: check out the branch by name, push plainly, tag the branch tip. A merge landing mid-release can enter the tag; that is accepted, as it is for the UI repos. The publish-nuget input validation from 10a8ffc is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Alexey-Pavlov
approved these changes
Oct 22, 2026
1 task
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.


What
Replaces the manual versioning steps in How to version the .NET repo with a Publish workflow, run from the Actions tab after merging a PR to
main.Structured after the PLP UI repo: small composite actions, reusable workflows, one orchestrator.
workflows/publish.ymlworkflows/generate-docs.ymldocs/; reusable and independently dispatchableworkflows/publish-nuget.ymlworkflows/create-github-release.ymlactions/next-versionconstructor.io.csprojactions/set-versionactions/git-identityInputs:
version-strategy(patch/minor/major/explicit), optional exactversion, a releasetitle, and apublish-to-nugettoggle. Each reusable workflow also keeps a manual trigger so a partially failed run can be resumed a step at a time.Verified before opening this
INPUT = src/constructor.io src/Constructorio_NET.Tests README.md,HTML_OUTPUT = .— all 385 committeddocs/*.htmlcome back byte-identical. That's how the INPUT paths were derived rather than guessed.constructor.io4.4.0 from NuGet and packed locally: samelib/netstandard2.0/{dll,xml}, same.NETStandard2.0nuspec target, sameNewtonsoft.Json 13.0.4dependency. The library targetsnetstandard2.0;dotnet-version: 8.0.xis only the build SDK, needed because the test project targetsnet8.0..slnline.set-versionre-greps every file afterwards; reverting just the.slnmakes it fail, so a silently non-matchingsedcan't ship a half-bumped release.author=<you>, committer=github-actions[bot], and the annotated tag records you as tagger. Unresolvable actors (scheduled run, deleted account, API failure) fall back to the bot with a warning rather than failing the release.Notes for review
publish.shis kept as a manual fallback — it prompts for confirmation, so it can't run in CI. README now documents the workflow as the primary path and warns against bumping by hand, since doing both risks publishing twice.GIT_COMMITTER_*, notGIT_AUTHOR_*— tags have no author field. Hence the deliberate split: the tag uses the triggering user as committer, while commits keep the bot as committer, since the bot is what performed the push.docs/.PROJECT_NUMBERis empty andConstructorIO.Versionis private withEXTRACT_PRIVATE = NO), so the docs step's position is about ordering only, not content.Before the first real release
Two things I couldn't check without repo settings:
NUGET_API_KEYmust exist as a repo secret.main— if direct pushes are blocked,bump_versionandgenerate_docswill both fail and the workflow needs a token with bypass.Suggested first run: Publish: Generate documentation with
commitunchecked. It touches nothing, and exercises the real Linux runner — including the GNUsedpath, which could only be reasoned about locally, not executed.🤖 Generated with Claude Code