dotnet / Nerdbank.GitVersioning

Stamp your assemblies, packages and more with a unique version generated from a single, simple version.json file and include git commit IDs for non-official builds.
https://www.nuget.org/packages/Nerdbank.GitVersioning
MIT License
1.36k stars 166 forks source link

Versioning flow #1023

Closed johnwc closed 8 months ago

johnwc commented 8 months ago

A lot of teams have the master/main branch locked so that only edits can come into it via a PR. In this scenario, can you describe the typical process of a release? Below are our typical steps for developing, can you add where this tool would be used to version each? Keep in mind that master/main branch is locked.

@AArnott I've always loathed dealing with coming up with a version strategy for development project, so this tool is much appreciated!

Let's say that current master/main branch is currently at version 1.0.1.

AArnott commented 8 months ago

Hi @johnwc. To start off, have you read these docs? That gives an outline of the process.

When you say "this tool" are you talking about the nuget package or the nbgv CLI tool? I'll assume the latter, since it's the most 'tool like', and relates to the actual process of branching for versions which seems to be the focus of your question.

So here are your steps, with the tool use and other corrections/comments injected:


Let's say that current master/main branch is currently at version 1.0.1.


This is about what this looks like in git history: image

At step 1, the version.json content to support this is:

{
  "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
  "version": "1.0.1",
  "publicReleaseRefSpec": [
    "^refs/heads/master$",
    "^refs/heads/v\\d+(?:\\.\\d+)?$"
  ],
  "release": {
    "branchName": "release/v{version}",
    "versionIncrement": "build",
    "firstUnstableTag": ""
  }
}

Other observations

Your release/v1.0.1 branch is suitably named iff your version.json file specifies 1.0.1. But if it just specifies 1.0, the release branch should have been named release/v1.0. Version numbers in branch names should be limited to those specified in version.json. Tagging an actual release should include the full version number (including version height), and nbgv tag can be very useful for this.

I generally recommend building unstable versions in main/master and stable ones only from release branches. Except in very slow moving, stable software where I only ever want to build and ship one version directly out of master/main.

I hope this helps.

johnwc commented 8 months ago

This doesn't mention about the main point of the question. When the master/main branch is protected from direct pushes and all updates require a PR to get updates merged into main.

And I have never worked on a project that has the code in master be unstable. That was always the point of doing PR with ci/cd pipelines to allowing prebuilding the merged code and testing it, prior to PR approval.

AArnott commented 8 months ago

Ah, right.

Work in main locally when you run nbgv prepare-release. Then push the branch with a different name and create a PR from that back to main. Also, push the release branch that the tool created, but as that'll be a new branch, there won't yet be any branch protections on it.

I have never worked on a project that has the code in master be unstable. That was always the point of doing PR with ci/cd pipelines to allowing prebuilding the merged code and testing it, prior to PR approval.

That's fine. A lot of projects either don't have adequate testing to consider a PR validation pass to mean they'd be comfortable shipping a stable version on that particular commit. But if you have adequate automated testing, that's great. Building stable versions with every build throughout a development milestone prohibits pushing the package to users to test as a prerelease. This is particularly true when building libraries for which semver is important, since once you've shipped 1.0.123, semver would prohibit adding features to 1.0.124 or anything higher until you bump to 1.1. And during the course of development, breaking changes to features added in that milestone are typically allowed, but if you've been building stable the whole time, it's harder to tell whether a version of the library has leaked out and it's therefore a semver violation. For all these reasons, I usually build unstable during development (so that semver rules don't apply at all) and only switch to building stable when I'm nearing a release and am truly making only stabilizing changes.

johnwc commented 8 months ago

Do you think we could get a new command line switch added to allow running the tool in the current branch as if it was in main? So that we don't have to do the name swap trick to get it to push.

AArnott commented 8 months ago

Just testing it, it looks like it already works, without a switch. Just check out a new branch based on main and run nbgv prepare-release. It'll do all the same stuff as if you were on main, except that the changes will be made to your new branch instead of main. Then you can push that (without renaming) and create your PR. You'll still want to push the new servicing branch it created.

johnwc commented 8 months ago

@AArnott with our other versioning scheme, we had the PR number in the version so that testers could easly know what they were testing. Is it possible to add a feature that uses the PR number in the version instead of commit hash? Or is there existing config that would allow this? Something like 3.8.10-PR.1102 the source branch for PRs looks like this refs/pull/1126/merge

AArnott commented 8 months ago

NB.GV only generates deterministic versions based on git data. PR numbers are external to that, so NB.GV is not likely to add that feature. What you're asking for is possible if you write your own msbuild target that modifies the properties based on whatever your CI sets. Some docs to get you started are here: https://github.com/dotnet/Nerdbank.GitVersioning/blob/main/doc/msbuild.md#customization-through-msbuild