Test workflows #17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Validate Versioning and Changelog | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| paths: | |
| - 'packages/ui/**' | |
| - '.github/workflows/validate-versioning.yml' | |
| jobs: | |
| validate: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install semver package | |
| run: npm install semver | |
| - name: Check for changes in package | |
| id: check-changes | |
| run: | | |
| # Check for changes in package files (excluding dist, node_modules, and package-lock.json) | |
| CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep "^packages/ui/" | grep -v "^packages/ui/dist/" | grep -v "^packages/ui/node_modules/" | grep -v "package-lock.json$" || true) | |
| if [ -n "$CHANGED_FILES" ]; then | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| echo "Package files have been modified:" | |
| echo "$CHANGED_FILES" | |
| else | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| echo "No relevant package files modified (excluding dist, node_modules, package-lock.json)" | |
| fi | |
| - name: Validate versioning and changelog | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| run: | | |
| set -e | |
| PACKAGE_DIR="packages/ui" | |
| 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 "❌ 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 "❌ ERROR: Version in package.json was not bumped!" | |
| echo "Current version: $CURRENT_VERSION" | |
| echo "Base version: $BASE_VERSION" | |
| echo "Please bump the version in packages/ui/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 "❌ ERROR: Version must be greater than the 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 "❌ 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::Package Lock Validation" | |
| # Verify version in package-lock.json matches package.json | |
| LOCKFILE_TOP_VERSION=$(node -e "console.log(require('./$PACKAGE_DIR/package-lock.json').version)") | |
| LOCKFILE_PACKAGE_VERSION=$(node -e "console.log(require('./$PACKAGE_DIR/package-lock.json').packages[''].version)") | |
| echo "package.json version: $CURRENT_VERSION" | |
| echo "package-lock.json top-level version: $LOCKFILE_TOP_VERSION" | |
| echo "package-lock.json packages[''].version: $LOCKFILE_PACKAGE_VERSION" | |
| if [ "$LOCKFILE_TOP_VERSION" != "$CURRENT_VERSION" ]; then | |
| echo "::error file=$PACKAGE_DIR/package-lock.json::Version mismatch in package-lock.json (top-level)!" | |
| echo "❌ ERROR: Version mismatch in package-lock.json (top-level)!" | |
| echo "package.json version: $CURRENT_VERSION" | |
| echo "package-lock.json top-level version: $LOCKFILE_TOP_VERSION" | |
| echo "Please update the top-level 'version' field in $PACKAGE_DIR/package-lock.json" | |
| exit 1 | |
| fi | |
| if [ "$LOCKFILE_PACKAGE_VERSION" != "$CURRENT_VERSION" ]; then | |
| echo "::error file=$PACKAGE_DIR/package-lock.json::Version mismatch in package-lock.json (packages[''])!" | |
| echo "❌ ERROR: Version mismatch in package-lock.json (packages[''])!" | |
| echo "package.json version: $CURRENT_VERSION" | |
| echo "package-lock.json packages[''].version: $LOCKFILE_PACKAGE_VERSION" | |
| echo "Please update the packages[''].version field in $PACKAGE_DIR/package-lock.json" | |
| exit 1 | |
| fi | |
| echo "✅ Version in package-lock.json matches package.json: $CURRENT_VERSION (both top-level and packages[''])" | |
| 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 "❌ ERROR: 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) | |
| if [ -z "$CHANGELOG_LINE" ]; then | |
| echo "::error file=$CHANGELOG_FILE::Could not find changelog entry line" | |
| echo "❌ ERROR: Could not find changelog entry line" | |
| exit 1 | |
| fi | |
| 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 "❌ ERROR: 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 "❌ ERROR: 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!" | |