diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 087bc42..8a8c687 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -32,6 +32,11 @@ jobs: steps: - uses: actions/checkout@v7 + with: + # MinVer derives the version from git tags and the commit count above them, so it needs the + # actual history rather than actions/checkout's default shallow clone - which contains no + # tags to find. + fetch-depth: 0 - uses: actions/setup-dotnet@v6 with: @@ -41,17 +46,13 @@ jobs: # build with, and testing on what people use beats testing on the oldest thing that works. dotnet-version: '10.x' - # On a tag the tag is the version, so nothing in the repository can disagree with what shipped. - # Off a tag this is unset and expands to nothing, leaving the csproj's own - which is - # then only ever a local default, never the thing that gets published. - - name: Take the version from the tag - if: github.ref_type == 'tag' - run: echo "VERSION_ARG=-p:Version=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV" - # No NuGet.config and no secure file: every dependency is public on nuget.org. The Azure # pipeline this replaced downloaded a secure NuGet.config it did not need. + # + # No -p:Version here: MinVer sets it from the git tag (and the commit count above one, off a + # tag), so nothing in the repository can disagree with what shipped. - name: Build - run: dotnet build Nota.CodeAnalysis.sln --configuration Release $VERSION_ARG + run: dotnet build Nota.CodeAnalysis.sln --configuration Release - name: Verify the rules report run: ./Nota.CodeAnalysis.Verification/verify.sh @@ -67,7 +68,7 @@ jobs: run: ./Nota.CodeAnalysis.Verification/verify-package.sh - name: Pack - run: dotnet pack Nota.CodeAnalysis.sln --configuration Release --no-build --output artifacts $VERSION_ARG + run: dotnet pack Nota.CodeAnalysis.sln --configuration Release --no-build --output artifacts # Kept even on a pull request, so a packaging mistake is visible without merging. - name: Upload the package diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..77a55bd --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,7 @@ + + + + v + + diff --git a/Nota.CodeAnalysis.Verification/verify-package.sh b/Nota.CodeAnalysis.Verification/verify-package.sh index 791be3a..ebcf4d5 100755 --- a/Nota.CodeAnalysis.Verification/verify-package.sh +++ b/Nota.CodeAnalysis.Verification/verify-package.sh @@ -40,10 +40,14 @@ mkdir -p "$feed" "$app" # whatever 2.2.0 was extracted first - the change under test never reaches the consumer. That is not # hypothetical; this script gave a clean pass against a regression it was written to catch, until the # version was made unique. +# +# MinVerVersionOverride, not -p:Version - MinVer computes Version itself from the git tag and +# overwrites whatever was passed in, so -p:Version here would be silently ignored and every run +# would collide on the same version, reviving the exact bug this comment describes. version="0.0.0-verify.$(date +%Y%m%d%H%M%S)" printf 'Packing %s...\n' "$version" -dotnet pack "$root/Nota.CodeAnalysis.sln" --configuration Release --output "$feed" -p:Version="$version" >"$work/pack.log" 2>&1 || { +dotnet pack "$root/Nota.CodeAnalysis.sln" --configuration Release --output "$feed" -p:MinVerVersionOverride="$version" >"$work/pack.log" 2>&1 || { printf 'pack failed:\n' >&2 cat "$work/pack.log" >&2 exit 1 diff --git a/Nota.CodeAnalysis/Nota.CodeAnalysis.csproj b/Nota.CodeAnalysis/Nota.CodeAnalysis.csproj index 492b3f0..c5c5cc9 100644 --- a/Nota.CodeAnalysis/Nota.CodeAnalysis.csproj +++ b/Nota.CodeAnalysis/Nota.CodeAnalysis.csproj @@ -4,9 +4,6 @@ true https://github.com/Notalib/Nota.CodeAnalysis true - - 2.2.1 content/README.md @@ -25,6 +22,11 @@ + + + diff --git a/README.md b/README.md index 53040a5..7416aa1 100644 --- a/README.md +++ b/README.md @@ -144,8 +144,12 @@ Releases are cut by tagging: git tag -a v2.3.0 -m "Nota.CodeAnalysis 2.3.0" && git push origin v2.3.0 ``` -The tag is the version, so nothing in the repository can disagree with what shipped. `` in -the csproj is only a local default, for anyone packing by hand. +[MinVer](https://github.com/adamralph/minver) derives the package version from that tag on every +build, so nothing in the repository can disagree with what shipped - there is no `` to edit +or forget to bump. Building straight off a tagged commit gets that tag's version exactly; anything +else gets the next patch as a pre-release with the commit count above the tag, e.g. `2.3.1-alpha.0.4`. +CI checks out full history (`fetch-depth: 0`) so MinVer can see the tags at all - a shallow clone has +none, and would fall back to `0.0.0-alpha.0`. Merging to `main` builds and verifies but does not publish, and neither do pull requests - releasing is a separate act from merging.