-
Notifications
You must be signed in to change notification settings - Fork 0
209 lines (177 loc) · 9.35 KB
/
validate-versioning.yaml
File metadata and controls
209 lines (177 loc) · 9.35 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
name: Validate Versioning and Changelog
on:
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v5
with:
version: "10"
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: "22"
cache: "pnpm"
- name: Install semver package
run: pnpm add semver
- name: Check for changes in package
id: check-changes
run: |
# Get actual list of packages
PACKAGES=$(find packages -maxdepth 1 -mindepth 1 -type d -printf "%f\n")
echo "All packages found: $PACKAGES"
# Check for changes in package files (excluding dist, node_modules)
CHANGED_PACKAGES=""
for pkg in $PACKAGES; do
CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- packages/$pkg | grep -v -E "dist|node_modules" || true)
if [ -n "$CHANGED" ]; then
CHANGED_PACKAGES="$CHANGED_PACKAGES $pkg"
fi
done
if [ -z "$CHANGED_PACKAGES" ]; then
echo "No packages changed"
echo "has_changes=false" >> $GITHUB_OUTPUT
echo "No relevant package files modified (excluding dist, node_modules)"
else
echo "Changed packages: $CHANGED_PACKAGES"
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "changed_packages=$CHANGED_PACKAGES" >> $GITHUB_OUTPUT
fi
- name: Skip if no packages changed
if: steps.check-changes.outputs.has_changes == 'false'
run: |
echo "No package changes detected. Skipping version and changelog validation."
exit 0
- name: Validate versioning and changelog
if: steps.check-changes.outputs.has_changes == 'true'
run: |
set -e
# Validate each changed package
for PACKAGE in ${{ steps.check-changes.outputs.changed_packages }}; do
PACKAGE_DIR="packages/$PACKAGE"
echo "::group::Version Validation"
echo "Starting validation for package: $PACKAGE_DIR"
# Get current version from package.json
CURRENT_VERSION=$(node -e "console.log(require('./$PACKAGE_DIR/package.json').version)")
echo "Current version in package.json: $CURRENT_VERSION"
# Get base version from base branch
git fetch origin ${{ github.base_ref }} --depth=1 || true
BASE_VERSION=$(git show origin/${{ github.base_ref }}:$PACKAGE_DIR/package.json 2>/dev/null | node -e "const fs=require('fs'); const data=fs.readFileSync(0,'utf-8'); console.log(JSON.parse(data).version)" || echo "0.0.0")
echo "Base version in package.json: $BASE_VERSION"
# Validate version format and check if version was increased (semantic versioning)
echo "Validating version format and increment..."
set +e
VERSION_CHECK=$(node -e "
const semver = require('semver');
const current = '$CURRENT_VERSION';
const base = '$BASE_VERSION';
// Validate current version format
if (!semver.valid(current)) { console.error('INVALID_CURRENT'); process.exit(1); }
// Validate base version format (if not 0.0.0)
if (base !== '0.0.0' && !semver.valid(base)) { console.error('INVALID_BASE'); process.exit(1); }
// Check if versions are the same
if (current === base) { console.error('SAME_VERSION'); process.exit(1); }
// Check if current version is greater than base version
if (!semver.gt(current, base)) { console.error('VERSION_NOT_INCREASED'); process.exit(1); }
// Calculate suggested versions
const patch = semver.inc(base, 'patch');
const minor = semver.inc(base, 'minor');
const major = semver.inc(base, 'major');
console.log('OK');
console.log('PATCH=' + patch);
console.log('MINOR=' + minor);
console.log('MAJOR=' + major);
" 2>&1)
VERSION_CHECK_EXIT=$?
set -e
echo "Full version check output:"
echo "$VERSION_CHECK"
VERSION_CHECK_OUTPUT=$(echo "$VERSION_CHECK" | head -1 | tr -d '\r\n')
echo "First line of output: '$VERSION_CHECK_OUTPUT'"
echo "Exit code: $VERSION_CHECK_EXIT"
if [ $VERSION_CHECK_EXIT -ne 0 ]; then
echo "::error file=$PACKAGE_DIR/package.json::Version validation failed"
if echo "$VERSION_CHECK" | grep -q "INVALID_CURRENT"; then
echo "::error::Current version '$CURRENT_VERSION' is not a valid semantic version!"
echo "Please use semantic versioning format (e.g., 1.0.0, 1.0.1, 1.1.0, 2.0.0)"
exit 1
elif echo "$VERSION_CHECK" | grep -q "INVALID_BASE"; then
echo "⚠️ WARNING: Base version '$BASE_VERSION' is not a valid semantic version"
echo "Assuming version bump is valid (first release or manual version)"
elif echo "$VERSION_CHECK" | grep -q "SAME_VERSION"; then
echo "::error file=$PACKAGE_DIR/package.json::Version was not bumped!"
echo "Current version: $CURRENT_VERSION"
echo "Base version: $BASE_VERSION"
echo "Please bump the version in package.json"
exit 1
elif echo "$VERSION_CHECK" | grep -q "VERSION_NOT_INCREASED"; then
PATCH_VER=$(echo "$VERSION_CHECK" | grep "PATCH=" | cut -d= -f2)
MINOR_VER=$(echo "$VERSION_CHECK" | grep "MINOR=" | cut -d= -f2)
MAJOR_VER=$(echo "$VERSION_CHECK" | grep "MAJOR=" | cut -d= -f2)
echo "::error file=$PACKAGE_DIR/package.json::Version must be greater than base version!"
echo "Current version: $CURRENT_VERSION"
echo "Base version: $BASE_VERSION"
echo "The new version must be higher according to semantic versioning rules."
echo "Suggested versions:"
echo " - Patch: $BASE_VERSION -> $PATCH_VER"
echo " - Minor: $BASE_VERSION -> $MINOR_VER"
echo " - Major: $BASE_VERSION -> $MAJOR_VER"
exit 1
else
echo "::error::Unknown version validation error"
echo "Exit code: $VERSION_CHECK_EXIT"
echo "Full output was:"
echo "$VERSION_CHECK"
exit 1
fi
else
echo "✅ Version was bumped from $BASE_VERSION to $CURRENT_VERSION (valid semver increment)"
fi
echo "::endgroup::"
echo "::group::Changelog Validation"
# Check if changelog has entry for this version
CHANGELOG_FILE="$PACKAGE_DIR/CHANGELOG.md"
echo "Checking changelog file: $CHANGELOG_FILE"
echo "Looking for version: $CURRENT_VERSION"
if ! grep -q "^## \\[$CURRENT_VERSION\\]" "$CHANGELOG_FILE"; then
echo "::error file=$CHANGELOG_FILE::Changelog entry for version $CURRENT_VERSION not found!"
echo "Please add a changelog entry in $CHANGELOG_FILE with the format:"
echo "## [$CURRENT_VERSION] - YYYY-MM-DD"
exit 1
fi
echo "✅ Changelog entry found for version $CURRENT_VERSION"
# Verify changelog entry is not empty (has content after the version header)
CHANGELOG_LINE=$(grep -n "^## \\[$CURRENT_VERSION\\]" "$CHANGELOG_FILE" | cut -d: -f1)
echo "Changelog entry found at line: $CHANGELOG_LINE"
# Check if there's content after the version header (skip empty entries)
NEXT_VERSION_LINE=$(tail -n +$((CHANGELOG_LINE + 1)) "$CHANGELOG_FILE" | grep -n "^## \\[" | head -1 | cut -d: -f1)
if [ -z "$NEXT_VERSION_LINE" ]; then
# This is the latest version, check if there's any content after the header
LINES_AFTER_HEADER=$(tail -n +$((CHANGELOG_LINE + 1)) "$CHANGELOG_FILE" | grep -v '^$' | head -1)
if [ -z "$LINES_AFTER_HEADER" ]; then
echo "::error file=$CHANGELOG_FILE::Changelog entry for version $CURRENT_VERSION is empty!"
echo "Please add at least one change entry (Added, Changed, Fixed, etc.)"
exit 1
fi
else
# Check if there's content between this version and the next
LINES_BETWEEN=$(sed -n "$((CHANGELOG_LINE + 1)),$((CHANGELOG_LINE + NEXT_VERSION_LINE - 1))p" "$CHANGELOG_FILE" | grep -v '^$' | head -1)
if [ -z "$LINES_BETWEEN" ]; then
echo "::error file=$CHANGELOG_FILE::Changelog entry for version $CURRENT_VERSION is empty!"
echo "Please add at least one change entry (Added, Changed, Fixed, etc.)"
exit 1
fi
fi
echo "✅ Changelog entry for version $CURRENT_VERSION has content"
echo "::endgroup::"
echo "::notice::All validations passed successfully for package $PACKAGE!"
done