-
Notifications
You must be signed in to change notification settings - Fork 4
144 lines (125 loc) · 5.6 KB
/
Copy pathcheck-version-bump.yml
File metadata and controls
144 lines (125 loc) · 5.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# Release-affecting changes under Contentstack.Management*/ or Directory.Build.props / core csproj
# require Directory.Build.props Version + CHANGELOG.md updates vs latest tag.
name: Check Version Bump
on:
pull_request:
jobs:
version-bump:
name: Version & changelog bump
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect changed files
id: detect
run: |
FILES=$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}")
echo "Changed files:"
echo "$FILES"
CODE_CHANGED=false
while IFS= read -r f; do
[ -z "$f" ] && continue
case "$f" in
Contentstack.Management.Core.Unit.Tests/*|Contentstack.Management.Core.Tests/*)
continue
;;
esac
if [[ "$f" == "Directory.Build.props" ]] || \
[[ "$f" == Contentstack.Management.Core/* ]] || \
[[ "$f" == Contentstack.Management.ASPNETCore/* ]]; then
CODE_CHANGED=true
break
fi
done <<< "$FILES"
PROPS_CHANGED=false
CHANGELOG_CHANGED=false
echo "$FILES" | grep -qx 'Directory.Build.props' && PROPS_CHANGED=true
echo "$FILES" | grep -qx 'CHANGELOG.md' && CHANGELOG_CHANGED=true
VERSION_FILES_OK=false
if [ "$PROPS_CHANGED" = true ] && [ "$CHANGELOG_CHANGED" = true ]; then
VERSION_FILES_OK=true
fi
echo "code_changed=$CODE_CHANGED" >> "$GITHUB_OUTPUT"
echo "version_files_ok=$VERSION_FILES_OK" >> "$GITHUB_OUTPUT"
- name: Skip when no release-affecting code changed
if: steps.detect.outputs.code_changed != 'true'
run: |
echo "No management SDK / version props changes. Skipping version-bump check."
exit 0
- name: Fail when version files were not both updated
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_ok != 'true'
run: |
echo "::error::Bump <Version> in Directory.Build.props and add a ## [vX.Y.Z] section at the top of CHANGELOG.md."
exit 1
- name: Validate version vs latest tag and changelog header
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_ok == 'true'
run: |
set -euo pipefail
PROJ_VERSION=$(python3 <<'PY'
import re
text = open("Directory.Build.props").read()
m = re.search(r"<Version>\s*([^<]+)\s*</Version>", text)
if not m:
raise SystemExit("Could not read <Version> from Directory.Build.props")
print(m.group(1).strip())
PY
)
git fetch --tags --force 2>/dev/null || true
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
if [ -z "$LATEST_TAG" ]; then
echo "No existing tags found. Skipping semver vs tag check."
CHANGELOG_HEAD=$(sed -nE 's/^## \[v?([0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z][0-9A-Za-z.-]*)?)\].*/\1/p' CHANGELOG.md | head -1)
if [ -z "$CHANGELOG_HEAD" ]; then
echo "::error::Could not find a ## [vX.Y.Z] entry at the top of CHANGELOG.md."
exit 1
fi
if [ "$CHANGELOG_HEAD" != "$PROJ_VERSION" ]; then
echo "::error::CHANGELOG top version ($CHANGELOG_HEAD) does not match Directory.Build.props Version ($PROJ_VERSION)."
exit 1
fi
exit 0
fi
LATEST_VERSION="${LATEST_TAG#v}"
CMP=$(python3 <<PY
import re, sys
def parse(v):
m = re.match(r"^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$", v)
if not m:
print(f"::error::Invalid semver: {v}", file=sys.stderr)
sys.exit(1)
major, minor, patch, pre = m.groups()
return (int(major), int(minor), int(patch)), pre
def compare(proj, latest):
proj_core, proj_pre = parse(proj)
latest_core, latest_pre = parse(latest)
if proj_core != latest_core:
return 1 if proj_core > latest_core else -1
# Same core version: no-prerelease (a real release) outranks any prerelease.
if proj_pre is None and latest_pre is None:
return 0
if proj_pre is None:
return 1
if latest_pre is None:
return -1
if proj_pre == latest_pre:
return 0
return 1 if proj_pre > latest_pre else -1
print(compare("$PROJ_VERSION", "$LATEST_VERSION"))
PY
)
if [ "$CMP" -le 0 ]; then
echo "::error::Version ($PROJ_VERSION) must be strictly greater than latest tag version ($LATEST_VERSION)."
exit 1
fi
CHANGELOG_HEAD=$(sed -nE 's/^## \[v?([0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z][0-9A-Za-z.-]*)?)\].*/\1/p' CHANGELOG.md | head -1)
if [ -z "$CHANGELOG_HEAD" ]; then
echo "::error::Could not find a ## [vX.Y.Z] entry at the top of CHANGELOG.md."
exit 1
fi
if [ "$CHANGELOG_HEAD" != "$PROJ_VERSION" ]; then
echo "::error::CHANGELOG top version ($CHANGELOG_HEAD) does not match Directory.Build.props Version ($PROJ_VERSION)."
exit 1
fi
echo "Version bump check passed: Directory.Build.props and CHANGELOG at $PROJ_VERSION (latest tag: $LATEST_TAG)."