Created
October 14, 2025 01:04
-
-
Save minademian/e33bf8e269d879d2cbb8b15cfb94d046 to your computer and use it in GitHub Desktop.
bump-version for custom WordPress plugins and themes
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
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| # ------------------------------------------------------------------------------ | |
| # bump-version.sh | |
| # | |
| # Bumps the project version (major, minor, or patch) across: | |
| # Up to three files, typically: | |
| # 1. package.json (default) | |
| # 2. plugin or theme file(s) | |
| # | |
| # Options: | |
| # --dry-run Show what would happen, without changing files. | |
| # --git Commit and tag the new version in Git. | |
| # --file <path> Specify first file (default: package.json) | |
| # --file1 <path> Specify additional file #1 | |
| # --file2 <path> Specify additional file #2 | |
| # | |
| # Compatible with macOS and Linux. | |
| # ------------------------------------------------------------------------------ | |
| # Usage: | |
| # ./scripts/bump-version.sh [major|minor|patch] | |
| # [--dry-run] [--git] | |
| # [--file path] [--file1 path] [--file2 path] | |
| # ------------------------------------------------------------------------------ | |
| if [[ $# -lt 1 ]]; then | |
| echo "❌ Usage: $0 [major|minor|patch] [--dry-run] [--git] [--file path] [--file1 path] [--file2 path]" | |
| exit 1 | |
| fi | |
| BUMP_TYPE="$1" | |
| shift | |
| # --- Defaults ----------------------------------------------------------------- | |
| DRY_RUN=false | |
| DO_GIT=false | |
| FILE_MAIN="package.json" | |
| FILE_1="" | |
| FILE_2="" | |
| # --- Parse optional flags ----------------------------------------------------- | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --dry-run) | |
| DRY_RUN=true | |
| ;; | |
| --git) | |
| DO_GIT=true | |
| ;; | |
| --file) | |
| shift | |
| [[ $# -eq 0 ]] && { echo "❌ Missing argument after --file"; exit 1; } | |
| FILE_MAIN="$1" | |
| ;; | |
| --file1) | |
| shift | |
| [[ $# -eq 0 ]] && { echo "❌ Missing argument after --file1"; exit 1; } | |
| FILE_1="$1" | |
| ;; | |
| --file2) | |
| shift | |
| [[ $# -eq 0 ]] && { echo "❌ Missing argument after --file2"; exit 1; } | |
| FILE_2="$1" | |
| ;; | |
| *) | |
| echo "❌ Unknown option: $1" | |
| echo "Usage: $0 [major|minor|patch] [--dry-run] [--git] [--file path] [--file1 path] [--file2 path]" | |
| exit 1 | |
| ;; | |
| esac | |
| shift | |
| done | |
| # --- Validate bump type ------------------------------------------------------- | |
| if [[ "$BUMP_TYPE" != "major" && "$BUMP_TYPE" != "minor" && "$BUMP_TYPE" != "patch" ]]; then | |
| echo "❌ Invalid bump type: $BUMP_TYPE" | |
| echo " Must be one of: major, minor, patch" | |
| exit 1 | |
| fi | |
| # --- Build file list ---------------------------------------------------------- | |
| FILES_TO_UPDATE=("$FILE_MAIN") | |
| [[ -n "$FILE_1" ]] && FILES_TO_UPDATE+=("$FILE_1") | |
| [[ -n "$FILE_2" ]] && FILES_TO_UPDATE+=("$FILE_2") | |
| # --- Ensure files exist ------------------------------------------------------- | |
| for file in "${FILES_TO_UPDATE[@]}"; do | |
| if [[ ! -f "$file" ]]; then | |
| echo "❌ $file not found." | |
| exit 1 | |
| fi | |
| done | |
| # --- Extract current version -------------------------------------------------- | |
| # If main file is package.json, parse JSON; otherwise, fall back to regex. | |
| if [[ "$FILE_MAIN" == "package.json" ]]; then | |
| CURR_VERSION=$(grep -Eo '"version": *"[0-9]+\.[0-9]+\.[0-9]+"' "$FILE_MAIN" | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+') | |
| else | |
| CURR_VERSION=$(grep -Eo 'Version: *[0-9]+\.[0-9]+\.[0-9]+' "$FILE_MAIN" | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+') | |
| fi | |
| if [[ -z "$CURR_VERSION" ]]; then | |
| echo "❌ Could not find valid version in $FILE_MAIN" | |
| exit 1 | |
| fi | |
| IFS='.' read -r MAJOR MINOR PATCH <<<"$CURR_VERSION" | |
| # --- Compute new version ------------------------------------------------------ | |
| case "$BUMP_TYPE" in | |
| major) | |
| ((MAJOR++)) | |
| MINOR=0 | |
| PATCH=0 | |
| ;; | |
| minor) | |
| ((MINOR++)) | |
| PATCH=0 | |
| ;; | |
| patch) | |
| ((PATCH++)) | |
| ;; | |
| esac | |
| NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" | |
| echo "" | |
| echo "🔢 Bumping version: $CURR_VERSION → $NEW_VERSION" | |
| $DRY_RUN && echo "🧪 Dry run mode (no changes will be made)" | |
| echo "" | |
| # --- Apply replacements ------------------------------------------------------- | |
| if ! $DRY_RUN; then | |
| for file in "${FILES_TO_UPDATE[@]}"; do | |
| if grep -q '"version":' "$file"; then | |
| sed -i.bak "s/\"version\": *\"$CURR_VERSION\"/\"version\": \"$NEW_VERSION\"/" "$file" | |
| else | |
| sed -i.bak "s/Version: *$CURR_VERSION/Version: $NEW_VERSION/" "$file" | |
| fi | |
| rm -f "$file.bak" | |
| done | |
| fi | |
| # --- Git commit and tag (optional) -------------------------------------------- | |
| if $DO_GIT; then | |
| if $DRY_RUN; then | |
| echo "💾 Would create Git commit and tag: v$NEW_VERSION" | |
| else | |
| echo "💾 Creating Git commit and tag..." | |
| git add "${FILES_TO_UPDATE[@]}" | |
| git commit -m "chore(release): bump version to v$NEW_VERSION" | |
| git tag "v$NEW_VERSION" | |
| echo "✅ Created commit and tag: v$NEW_VERSION" | |
| fi | |
| fi | |
| echo "" | |
| echo "✅ Done!" | |
| echo " New version: $NEW_VERSION" | |
| printf " Files updated:\n" | |
| for f in "${FILES_TO_UPDATE[@]}"; do | |
| echo " • $f" | |
| done | |
| $DRY_RUN && echo " (Dry run only — no changes applied)" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment