Skip to content

Commit 763b230

Browse files
committed
Use four-part version (X.Y.Z.BuildNumber) for release tags
- Directory.Build.props conditionally appends BuildNumber to VersionPrefix - ReleaseManifest reads BuildNumber env var to match effective version - Workflow outputs full_version (e.g. 0.2.0.31) for tag and validation - Remove static run-name, rely on default commit message display Made-with: Cursor
1 parent 7a928b0 commit 763b230

3 files changed

Lines changed: 28 additions & 15 deletions

File tree

.github/workflows/ci.yml

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ on:
77
branches: [main]
88
workflow_dispatch:
99

10-
run-name: >-
11-
${{
12-
github.event_name == 'pull_request'
13-
&& format('PR #{0} · {1}', github.event.pull_request.number, github.head_ref)
14-
|| format('{0} #{1}', github.ref_name, github.run_number)
15-
}}
16-
1710
permissions:
1811
contents: read
1912

@@ -35,6 +28,7 @@ jobs:
3528
timeout-minutes: 5
3629
outputs:
3730
version: ${{ steps.resolve.outputs.version }}
31+
full_version: ${{ steps.resolve.outputs.full_version }}
3832
tag: ${{ steps.resolve.outputs.tag }}
3933
sha: ${{ steps.resolve.outputs.sha }}
4034
is_release: ${{ steps.resolve.outputs.is_release }}
@@ -62,26 +56,35 @@ jobs:
6256
exit 1
6357
fi
6458
65-
TAG="v$VERSION"
6659
SHA="$(git rev-parse HEAD)"
6760
6861
IS_RELEASE="false"
6962
if [ "${{ github.event_name }}" != "pull_request" ] && [ "${{ github.ref }}" = "refs/heads/main" ]; then
7063
IS_RELEASE="true"
7164
fi
7265
66+
if [ "$IS_RELEASE" = "true" ]; then
67+
FULL_VERSION="${VERSION}.${{ github.run_number }}"
68+
else
69+
FULL_VERSION="$VERSION"
70+
fi
71+
TAG="v$FULL_VERSION"
72+
7373
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
74+
echo "full_version=$FULL_VERSION" >> "$GITHUB_OUTPUT"
7475
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
7576
echo "sha=$SHA" >> "$GITHUB_OUTPUT"
7677
echo "is_release=$IS_RELEASE" >> "$GITHUB_OUTPUT"
77-
echo "Resolved: version=$VERSION tag=$TAG sha=$SHA is_release=$IS_RELEASE"
78+
echo "Resolved: version=$VERSION full_version=$FULL_VERSION tag=$TAG sha=$SHA is_release=$IS_RELEASE"
7879
7980
- name: Version summary
8081
shell: bash
8182
run: |
8283
VERSION="${{ steps.resolve.outputs.version }}"
84+
FULL_VERSION="${{ steps.resolve.outputs.full_version }}"
8385
IS_RELEASE="${{ steps.resolve.outputs.is_release }}"
8486
SHA="${{ steps.resolve.outputs.sha }}"
87+
TAG="${{ steps.resolve.outputs.tag }}"
8588
8689
IFS='.' read -r CUR_MAJOR CUR_MINOR CUR_PATCH <<< "$VERSION"
8790
@@ -111,8 +114,9 @@ jobs:
111114
echo ""
112115
echo "| Property | Value |"
113116
echo "|----------|-------|"
114-
echo "| **Version** | \`$VERSION\` |"
115-
echo "| **Tag** | \`v$VERSION\` |"
117+
echo "| **Version** | \`$FULL_VERSION\` |"
118+
echo "| **Base Version** | \`$VERSION\` |"
119+
echo "| **Tag** | \`$TAG\` |"
116120
echo "| **Previous Tag** | \`$PREV_TAG\` |"
117121
echo "| **Bump Type** | **$BUMP** |"
118122
echo "| **Mode** | $MODE |"
@@ -155,6 +159,8 @@ jobs:
155159
needs: resolve-version
156160
runs-on: ${{ matrix.os }}
157161
timeout-minutes: 30
162+
env:
163+
BuildNumber: ${{ needs.resolve-version.outputs.is_release == 'true' && github.run_number || '' }}
158164
strategy:
159165
fail-fast: false
160166
matrix: ${{ fromJSON(needs.resolve-version.outputs.build_matrix) }}
@@ -210,7 +216,7 @@ jobs:
210216
if: needs.resolve-version.outputs.is_release == 'true' && matrix.pack
211217
shell: bash
212218
run: |
213-
EXPECTED_VERSION="${{ needs.resolve-version.outputs.version }}"
219+
EXPECTED_VERSION="${{ needs.resolve-version.outputs.full_version }}"
214220
215221
shopt -s nullglob
216222
FILES=(artifacts/packages/*.nupkg artifacts/packages/*.snupkg)
@@ -292,7 +298,7 @@ jobs:
292298
shell: bash
293299
run: |
294300
set -euo pipefail
295-
EXPECTED_VERSION="${{ needs.resolve-version.outputs.version }}"
301+
EXPECTED_VERSION="${{ needs.resolve-version.outputs.full_version }}"
296302
MANIFEST="packages/release-manifest.json"
297303
298304
if [ ! -f "$MANIFEST" ]; then
@@ -305,7 +311,7 @@ jobs:
305311
from pathlib import Path
306312
307313
manifest = json.loads(Path("packages/release-manifest.json").read_text())
308-
expected = "${{ needs.resolve-version.outputs.version }}"
314+
expected = "${{ needs.resolve-version.outputs.full_version }}"
309315
310316
if manifest.get("version") != expected:
311317
print(f"::error::Version mismatch: manifest={manifest.get('version')} expected={expected}")

Directory.Build.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
Bump this value via PR when preparing a new release. -->
1212
<PropertyGroup>
1313
<VersionPrefix>0.2.0</VersionPrefix>
14+
<VersionPrefix Condition="'$(BuildNumber)' != ''">$(VersionPrefix).$(BuildNumber)</VersionPrefix>
1415
</PropertyGroup>
1516

1617
<!-- Local builds default to prerelease to avoid confusion with stable releases.

build/BuildTask.Targets.ReleaseManifest.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ string ReadVersionPrefixFromProps()
5252
var match = Regex.Match(content, @"<VersionPrefix>\s*([^<]+?)\s*</VersionPrefix>", RegexOptions.Singleline);
5353
if (!match.Success)
5454
throw new InvalidOperationException($"<VersionPrefix> not found in {DirectoryBuildPropsFile}");
55-
return match.Groups[1].Value.Trim();
55+
var version = match.Groups[1].Value.Trim();
56+
57+
var buildNumber = Environment.GetEnvironmentVariable("BuildNumber");
58+
if (!string.IsNullOrWhiteSpace(buildNumber))
59+
version = $"{version}.{buildNumber}";
60+
61+
return version;
5662
}
5763

5864
static string GetGitHeadSha()

0 commit comments

Comments
 (0)