Files
2025-02-21 22:10:00 +01:00

244 lines
7.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -o pipefail
# Colors and styles
readonly RESET='\033[0m'
readonly BOLD='\033[1m'
readonly DIM='\033[2m'
readonly UNDERLINE='\033[4m'
readonly BLUE='\033[34m'
readonly GREEN='\033[32m'
readonly RED='\033[31m'
readonly YELLOW='\033[33m'
readonly CYAN='\033[36m'
readonly MAGENTA='\033[35m'
# Essential emojis
readonly ROCKET="🚀"
readonly CHECK="✓"
readonly ERROR="❌"
readonly SKIP="⏭️"
# Configuration
readonly RELEASE_BRANCH="2.x"
readonly REPOSITORIES=(
"flasher"
"flasher-laravel"
"flasher-symfony"
"flasher-noty"
"flasher-noty-laravel"
"flasher-noty-symfony"
"flasher-notyf"
"flasher-notyf-laravel"
"flasher-notyf-symfony"
"flasher-sweetalert"
"flasher-sweetalert-laravel"
"flasher-sweetalert-symfony"
"flasher-toastr"
"flasher-toastr-laravel"
"flasher-toastr-symfony"
)
print_header() {
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher Release ${ROCKET}${RESET}\n"
echo -e "${BOLD}Date : ${RESET}${CYAN}$(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
echo -e "${BOLD}User : ${RESET}${MAGENTA}$(whoami)${RESET}"
echo -e "${BOLD}Branch : ${RESET}${GREEN}$RELEASE_BRANCH${RESET}"
echo -e "${BOLD}Directory : ${RESET}${BLUE}$(pwd)${RESET}\n"
}
draw_progress_bar() {
local percent=$1
local width=50
local filled=$(((width * percent + 99) / 100)) # Rounded up division
local empty=$((width - filled))
echo -n "["
printf "${GREEN}█%.0s${RESET}" $(seq 1 $filled)
printf "${DIM}─%.0s${RESET}" $(seq 1 $empty)
echo -n "] ${percent}%"
}
check_tag_exists() {
local repo=$1
local tag=$2
local remote_url="git@github.com:php-flasher/$repo.git"
if git ls-remote --tags "$remote_url" | grep -q "refs/tags/$tag$"; then
return 0
else
return 1
fi
}
release_repository() {
local repo=$1
local version=$2
local tmp_dir="/tmp/php-flasher"
local remote_url="git@github.com:php-flasher/$repo.git"
echo -e "\nGitHub : ${UNDERLINE}${BLUE}https://github.com/php-flasher/${repo}${RESET}"
echo -e "Tag : ${YELLOW}$version${RESET}"
if check_tag_exists "$repo" "$version"; then
echo -e "${SKIP} ${YELLOW}Tag $version already exists, skipping...${RESET}"
return 0
fi
# Clean and create temporary directory
rm -rf "$tmp_dir"
mkdir -p "$tmp_dir"
echo -e "${CYAN}Cloning repository...${RESET}"
if ! git clone "$remote_url" "$tmp_dir" >/dev/null 2>&1; then
echo -e "${ERROR} ${RED}Failed to clone repository${RESET}"
return 1
fi
(
cd "$tmp_dir"
echo -e "${CYAN}Creating tag $version...${RESET}"
git checkout "$RELEASE_BRANCH" >/dev/null 2>&1
git tag "$version"
if ! git push origin --tags --force >/dev/null 2>&1; then
echo -e "${ERROR} ${RED}Failed to push tag${RESET}"
return 1
fi
)
echo -e "${CHECK} ${GREEN}Successfully tagged${RESET}"
return 0
}
validate_version() {
local version=$1
if [[ ! $version =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo -e "\n${ERROR} ${RED}Invalid version format: $version${RESET}"
echo -e "Version must be in format X.Y.Z or vX.Y.Z (e.g., 2.1.6 or v2.1.6)\n"
exit 1
fi
}
validate_environment() {
echo -e "${CYAN}Validating environment...${RESET}"
local has_error=0
# Check branch
local current_branch=$(git rev-parse --abbrev-ref HEAD)
echo -ne "${CYAN}Checking branch...${RESET} "
if [[ "$RELEASE_BRANCH" != "$current_branch" ]]; then
echo -e "${ERROR} ${RED}Wrong branch: $current_branch (expected: $RELEASE_BRANCH)${RESET}"
has_error=1
else
echo -e "${CHECK} ${GREEN}On correct branch: $current_branch${RESET}"
fi
# Check working directory
echo -ne "${CYAN}Checking working directory...${RESET} "
if [[ ! -z "$(git status --porcelain)" ]]; then
echo -e "${ERROR} ${RED}Working directory is not clean${RESET}"
echo -e "${DIM}Hint: Commit or stash your changes first${RESET}"
has_error=1
else
echo -e "${CHECK} ${GREEN}Working directory is clean${RESET}"
fi
# Check sync with remote
echo -ne "${CYAN}Checking remote synchronization...${RESET} "
git fetch origin > /dev/null 2>&1
local local_sha=$(git rev-parse HEAD)
local remote_sha=$(git rev-parse origin/$RELEASE_BRANCH)
if [[ $local_sha != $remote_sha ]]; then
echo -e "${ERROR} ${RED}Branch is not in sync with origin/$RELEASE_BRANCH${RESET}"
echo -e "\n${YELLOW}Local SHA: ${local_sha}${RESET}"
echo -e "${YELLOW}Remote SHA: ${remote_sha}${RESET}"
echo -e "\n${DIM}To fix this, try:${RESET}"
# Check if we have unpushed commits
if git rev-list origin/$RELEASE_BRANCH..$RELEASE_BRANCH --count > /dev/null 2>&1; then
local ahead=$(git rev-list origin/$RELEASE_BRANCH..$RELEASE_BRANCH --count)
local behind=$(git rev-list $RELEASE_BRANCH..origin/$RELEASE_BRANCH --count)
if [[ $ahead -gt 0 && $behind -gt 0 ]]; then
echo -e "${YELLOW}Your branch is $ahead commits ahead and $behind commits behind origin/$RELEASE_BRANCH${RESET}"
echo -e "1. ${CYAN}git pull origin $RELEASE_BRANCH${RESET} (to get remote changes)"
echo -e "2. ${CYAN}git push origin $RELEASE_BRANCH${RESET} (to push your changes)"
elif [[ $ahead -gt 0 ]]; then
echo -e "${YELLOW}Your branch is $ahead commits ahead of origin/$RELEASE_BRANCH${RESET}"
echo -e "Run: ${CYAN}git push origin $RELEASE_BRANCH${RESET}"
elif [[ $behind -gt 0 ]]; then
echo -e "${YELLOW}Your branch is $behind commits behind origin/$RELEASE_BRANCH${RESET}"
echo -e "Run: ${CYAN}git pull origin $RELEASE_BRANCH${RESET}"
fi
fi
has_error=1
else
echo -e "${CHECK} ${GREEN}Branch is in sync with remote${RESET}"
fi
if [[ $has_error -eq 1 ]]; then
echo -e "\n${ERROR} ${RED}Environment validation failed${RESET}"
exit 1
fi
echo -e "\n${CHECK} ${GREEN}Environment validated successfully${RESET}\n"
}
main() {
if [ "$#" -ne 1 ]; then
echo -e "${ERROR} ${RED}Version tag required${RESET}"
echo -e "Usage: $0 <version>"
echo -e "Example: $0 2.1.6\n"
exit 1
fi
local version=$1
[[ $version != v* ]] && version="v$version"
print_header
validate_version "$version"
validate_environment
local success_count=0
local skipped_count=0
local failed_count=0
local total_count=${#REPOSITORIES[@]}
local start_time=$(date +%s)
for repo in "${REPOSITORIES[@]}"; do
local current_count=$((success_count + skipped_count + failed_count + 1))
local percent=$((current_count * 100 / total_count))
echo -e "\nProgress: ${BOLD}$current_count/$total_count${RESET}"
# draw_progress_bar $percent
if release_repository "$repo" "$version"; then
if check_tag_exists "$repo" "$version"; then
((skipped_count++))
else
((success_count++))
fi
else
((failed_count++))
fi
done
local end_time=$(date +%s)
local duration=$((end_time - start_time))
# Summary
echo -e "\n${BOLD}${CYAN}Release Summary${RESET}"
echo -e "Successful : ${GREEN}$success_count${RESET}"
echo -e "Skipped : ${YELLOW}$skipped_count${RESET}"
[ $failed_count -gt 0 ] && echo -e "Failed : ${RED}$failed_count${RESET}"
echo -e "Duration : ${YELLOW}${duration}s${RESET}"
echo -e "Total repos: ${CYAN}$total_count${RESET}\n"
[ $failed_count -gt 0 ] && exit 1 || exit 0
}
main "$@"