11#! /bin/bash
2+ #
3+ # Tag and push a release.
4+ #
5+ # CI (.github/workflows/release.yml) handles the actual GitHub Release
6+ # creation on tag push. This script's only job is to verify CHANGELOG
7+ # matches the version, ensure the working tree is clean, and tag.
8+ #
9+ # kyte-php is distributed via Composer (packagist.org), which auto-
10+ # discovers tags from GitHub. Once the tag exists upstream, customers
11+ # can `composer require keyqcloud/kyte-php:^X.Y` to pull it.
12+ #
13+ # Usage: ./release.sh 4.4.0
214
3- print_error () {
4- echo " \033[1;31m$1 \033[0m"
5- }
6-
7- if [ " $# " -eq 1 ]; then
8- # Check the CHANGELOG.md
9- changelog_version=$( awk ' /## /{print $2;exit}' CHANGELOG.md)
10-
11- if [ " $changelog_version " != " $1 " ]; then
12- print_error " Version in CHANGELOG.md does not match the release version."
13- exit 1
14- fi
15-
16- # Define the path to the Version.php file
17- php_version_file_path=" src/Core/Version.php"
18-
19- # Extract the version from the PHP file
20- php_version=$( awk -F ' =' ' /const MAJOR/{major=$2} /const MINOR/{minor=$2} /const PATCH/{patch=$2} END{print major"."minor"."patch}' " $php_version_file_path " )
21-
22- # Remove semicolons using tr
23- php_version=$( echo " $php_version " | tr -d ' ;' )
24-
25- # Compare the desired version with the PHP version
26- if [ " $1 " != " $php_version " ]; then
27- print_error " Version mismatch: Desired version $1 , Version.php is $php_version "
28- exit 1
29- fi
30-
31- echo " Creating tag for release version $1 "
32-
33- git tag " v$1 "
34-
35- if [ $? -eq 0 ]; then
36- echo " Git tag created successfully for v$1 ."
37- # Push the tag to the origin
38- git push origin --tags
39-
40- if [ $? -eq 0 ]; then
41- echo " Git push successful. New release v$1 is available"
42- else
43- print_error " Git push failed."
44- exit 1
45- fi
46- else
47- print_error " Git tag creation failed."
48- exit 1
49- fi
50- fi
15+ set -e
16+
17+ print_error () { printf " \033[1;31m%s\033[0m\n" " $1 " ; }
18+ print_success () { printf " \033[1;32m%s\033[0m\n" " $1 " ; }
19+
20+ if [ " $# " -ne 1 ]; then
21+ print_error " Usage: ./release.sh <version>"
22+ print_error " Example: ./release.sh 4.4.0"
23+ exit 1
24+ fi
25+
26+ VERSION=" $1 "
27+
28+ # Sanity-check CHANGELOG has the new version at the top.
29+ CHANGELOG_VERSION=$( awk ' /^## /{print $2; exit}' CHANGELOG.md)
30+ if [ " $CHANGELOG_VERSION " != " $VERSION " ]; then
31+ print_error " Version in CHANGELOG.md ($CHANGELOG_VERSION ) does not match $VERSION ."
32+ print_error " Update CHANGELOG.md to add a '## $VERSION ' section before releasing."
33+ exit 1
34+ fi
35+
36+ # Refuse to tag against a dirty tree — would tag unintended state.
37+ if ! git diff-index --quiet HEAD --; then
38+ print_error " Working tree is not clean. Commit or stash changes first."
39+ git status --short
40+ exit 1
41+ fi
42+
43+ # Refuse to tag if we're not on master.
44+ CURRENT_BRANCH=$( git rev-parse --abbrev-ref HEAD)
45+ if [ " $CURRENT_BRANCH " != " master" ]; then
46+ print_error " Releases must be tagged from master. Current branch: $CURRENT_BRANCH "
47+ exit 1
48+ fi
49+
50+ # Refuse to tag if local master is behind origin.
51+ git fetch origin master --quiet
52+ LOCAL=$( git rev-parse master)
53+ REMOTE=$( git rev-parse origin/master)
54+ if [ " $LOCAL " != " $REMOTE " ]; then
55+ print_error " Local master is not in sync with origin/master. Push or pull first."
56+ exit 1
57+ fi
58+
59+ # Refuse to tag if the tag already exists locally or upstream.
60+ if git rev-parse " v$VERSION " > /dev/null 2>&1 ; then
61+ print_error " Tag v$VERSION already exists locally."
62+ exit 1
63+ fi
64+ if git ls-remote --tags origin " v$VERSION " 2> /dev/null | grep -q " v$VERSION " ; then
65+ print_error " Tag v$VERSION already exists on origin."
66+ exit 1
67+ fi
68+
69+ print_success " Tagging v$VERSION ..."
70+ git tag " v$VERSION "
71+ git push origin " v$VERSION "
72+
73+ print_success " "
74+ print_success " Tagged v$VERSION and pushed."
75+ print_success " GitHub Actions will now extract release notes from CHANGELOG.md"
76+ print_success " and create the GitHub Release."
77+ print_success " Watch: https://github.com/keyqcloud/kyte-php/actions"
78+ print_success " "
79+ print_success " Once the GitHub Release is published, Packagist will auto-detect"
80+ print_success " the new tag within minutes. Customers pulling via Composer with"
81+ print_success " a constraint matching v$VERSION (e.g., ^${VERSION%% .* } .${VERSION#* .} "
82+ print_success " or ^${VERSION%% .* } .${VERSION#* .} .0) will receive it on next update."
0 commit comments