jekyll-theme-zer0 0.7.2 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +72 -0
- data/README.md +33 -4
- data/_plugins/preview_image_generator.rb +258 -0
- data/_plugins/theme_version.rb +88 -0
- data/assets/images/previews/git-workflow-best-practices-for-modern-teams.png +0 -0
- data/scripts/README.md +443 -0
- data/scripts/analyze-commits.sh +313 -0
- data/scripts/build +115 -0
- data/scripts/build.sh +33 -0
- data/scripts/build.sh.legacy +174 -0
- data/scripts/example-usage.sh +102 -0
- data/scripts/fix-markdown-format.sh +265 -0
- data/scripts/gem-publish.sh +42 -0
- data/scripts/gem-publish.sh.legacy +700 -0
- data/scripts/generate-preview-images.sh +846 -0
- data/scripts/install-preview-generator.sh +531 -0
- data/scripts/lib/README.md +263 -0
- data/scripts/lib/changelog.sh +313 -0
- data/scripts/lib/common.sh +154 -0
- data/scripts/lib/gem.sh +226 -0
- data/scripts/lib/git.sh +205 -0
- data/scripts/lib/preview_generator.py +646 -0
- data/scripts/lib/test/run_tests.sh +140 -0
- data/scripts/lib/test/test_changelog.sh +87 -0
- data/scripts/lib/test/test_gem.sh +68 -0
- data/scripts/lib/test/test_git.sh +82 -0
- data/scripts/lib/test/test_validation.sh +72 -0
- data/scripts/lib/test/test_version.sh +96 -0
- data/scripts/lib/validation.sh +139 -0
- data/scripts/lib/version.sh +178 -0
- data/scripts/release +240 -0
- data/scripts/release.sh +33 -0
- data/scripts/release.sh.legacy +342 -0
- data/scripts/setup.sh +155 -0
- data/scripts/test-auto-version.sh +260 -0
- data/scripts/test-mermaid.sh +251 -0
- data/scripts/test.sh +156 -0
- data/scripts/version.sh +152 -0
- metadata +37 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Common utilities library for zer0-mistakes release scripts
|
|
4
|
+
# Provides shared functions for logging, error handling, and utilities
|
|
5
|
+
# Source this file in other scripts: source "$(dirname "$0")/lib/common.sh"
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
# Colors for output
|
|
10
|
+
export RED='\033[0;31m'
|
|
11
|
+
export GREEN='\033[0;32m'
|
|
12
|
+
export YELLOW='\033[1;33m'
|
|
13
|
+
export BLUE='\033[0;34m'
|
|
14
|
+
export CYAN='\033[0;36m'
|
|
15
|
+
export PURPLE='\033[0;35m'
|
|
16
|
+
export NC='\033[0m' # No Color
|
|
17
|
+
|
|
18
|
+
# Global flags
|
|
19
|
+
export DRY_RUN=${DRY_RUN:-false}
|
|
20
|
+
export VERBOSE=${VERBOSE:-false}
|
|
21
|
+
export INTERACTIVE=${INTERACTIVE:-true}
|
|
22
|
+
|
|
23
|
+
# Logging functions
|
|
24
|
+
log() {
|
|
25
|
+
echo -e "${GREEN}[LOG]${NC} $1"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
info() {
|
|
29
|
+
echo -e "${BLUE}[INFO]${NC} $1"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
step() {
|
|
33
|
+
echo -e "${CYAN}[STEP]${NC} $1"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
success() {
|
|
37
|
+
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
warn() {
|
|
41
|
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
error() {
|
|
45
|
+
echo -e "${RED}[ERROR]${NC} $1" >&2
|
|
46
|
+
exit 1
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
debug() {
|
|
50
|
+
if [[ "$VERBOSE" == "true" ]]; then
|
|
51
|
+
echo -e "${PURPLE}[DEBUG]${NC} $1" >&2
|
|
52
|
+
fi
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# User confirmation
|
|
56
|
+
confirm() {
|
|
57
|
+
local message="$1"
|
|
58
|
+
|
|
59
|
+
if [[ "$INTERACTIVE" == "false" ]]; then
|
|
60
|
+
debug "Non-interactive mode: auto-confirming '$message'"
|
|
61
|
+
return 0
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
echo -e "${YELLOW}$message (y/N)${NC}"
|
|
65
|
+
read -r response
|
|
66
|
+
[[ "$response" =~ ^[Yy]$ ]]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Dry run wrapper
|
|
70
|
+
dry_run_exec() {
|
|
71
|
+
local description="$1"
|
|
72
|
+
shift
|
|
73
|
+
|
|
74
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
75
|
+
info "[DRY RUN] Would execute: $description"
|
|
76
|
+
debug "Command: $*"
|
|
77
|
+
return 0
|
|
78
|
+
else
|
|
79
|
+
debug "Executing: $*"
|
|
80
|
+
"$@"
|
|
81
|
+
fi
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# Check if command exists
|
|
85
|
+
command_exists() {
|
|
86
|
+
command -v "$1" &> /dev/null
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Validate required command
|
|
90
|
+
require_command() {
|
|
91
|
+
local cmd="$1"
|
|
92
|
+
local install_hint="${2:-}"
|
|
93
|
+
|
|
94
|
+
if ! command_exists "$cmd"; then
|
|
95
|
+
error "Required command not found: $cmd${install_hint:+ ($install_hint)}"
|
|
96
|
+
fi
|
|
97
|
+
debug "Found required command: $cmd"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Check if file exists
|
|
101
|
+
require_file() {
|
|
102
|
+
local file="$1"
|
|
103
|
+
local description="${2:-file}"
|
|
104
|
+
|
|
105
|
+
if [[ ! -f "$file" ]]; then
|
|
106
|
+
error "Required $description not found: $file"
|
|
107
|
+
fi
|
|
108
|
+
debug "Found required file: $file"
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# Get script directory
|
|
112
|
+
get_script_dir() {
|
|
113
|
+
local script_path="${BASH_SOURCE[0]}"
|
|
114
|
+
while [[ -L "$script_path" ]]; do
|
|
115
|
+
local dir="$(cd -P "$(dirname "$script_path")" && pwd)"
|
|
116
|
+
script_path="$(readlink "$script_path")"
|
|
117
|
+
[[ "$script_path" != /* ]] && script_path="$dir/$script_path"
|
|
118
|
+
done
|
|
119
|
+
cd -P "$(dirname "$script_path")" && pwd
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# Get repository root
|
|
123
|
+
get_repo_root() {
|
|
124
|
+
git rev-parse --show-toplevel 2>/dev/null || error "Not in a git repository"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Print header
|
|
128
|
+
print_header() {
|
|
129
|
+
local title="$1"
|
|
130
|
+
echo -e "${BLUE}================================${NC}"
|
|
131
|
+
echo -e "${BLUE}$title${NC}"
|
|
132
|
+
echo -e "${BLUE}================================${NC}"
|
|
133
|
+
echo ""
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Print summary
|
|
137
|
+
print_summary() {
|
|
138
|
+
local title="$1"
|
|
139
|
+
shift
|
|
140
|
+
|
|
141
|
+
echo ""
|
|
142
|
+
echo -e "${CYAN}📋 $title${NC}"
|
|
143
|
+
for item in "$@"; do
|
|
144
|
+
echo -e " $item"
|
|
145
|
+
done
|
|
146
|
+
echo ""
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# Export functions for use in other scripts
|
|
150
|
+
export -f log info step success warn error debug
|
|
151
|
+
export -f confirm dry_run_exec
|
|
152
|
+
export -f command_exists require_command require_file
|
|
153
|
+
export -f get_script_dir get_repo_root
|
|
154
|
+
export -f print_header print_summary
|
data/scripts/lib/gem.sh
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Gem operations library for zer0-mistakes release scripts
|
|
4
|
+
# Provides functions for building, validating, and publishing gems
|
|
5
|
+
|
|
6
|
+
# Source common utilities
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
source "$SCRIPT_DIR/common.sh"
|
|
9
|
+
source "$SCRIPT_DIR/git.sh"
|
|
10
|
+
source "$SCRIPT_DIR/changelog.sh"
|
|
11
|
+
|
|
12
|
+
# Constants (check if already defined)
|
|
13
|
+
if [[ -z "${GEMSPEC_FILE:-}" ]]; then
|
|
14
|
+
readonly GEMSPEC_FILE="jekyll-theme-zer0.gemspec"
|
|
15
|
+
fi
|
|
16
|
+
if [[ -z "${GEM_NAME:-}" ]]; then
|
|
17
|
+
readonly GEM_NAME="jekyll-theme-zer0"
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Build the gem
|
|
21
|
+
build_gem() {
|
|
22
|
+
local version="$1"
|
|
23
|
+
local gem_file="${GEM_NAME}-${version}.gem"
|
|
24
|
+
|
|
25
|
+
step "Building gem $gem_file..."
|
|
26
|
+
|
|
27
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
28
|
+
info "[DRY RUN] Would build $gem_file"
|
|
29
|
+
return 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Clean up old gem files
|
|
33
|
+
rm -f ${GEM_NAME}-*.gem
|
|
34
|
+
|
|
35
|
+
# Validate gemspec
|
|
36
|
+
if ! ruby -c "$GEMSPEC_FILE" > /dev/null 2>&1; then
|
|
37
|
+
error "Invalid gemspec: $GEMSPEC_FILE"
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Build gem
|
|
41
|
+
if ! gem build "$GEMSPEC_FILE"; then
|
|
42
|
+
error "Failed to build gem"
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Verify gem was created
|
|
46
|
+
if [[ ! -f "$gem_file" ]]; then
|
|
47
|
+
error "Gem file not found after build: $gem_file"
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Show gem info
|
|
51
|
+
local file_count
|
|
52
|
+
file_count=$(tar -tzf "$gem_file" 2>/dev/null | wc -l | tr -d ' ')
|
|
53
|
+
local file_size
|
|
54
|
+
file_size=$(ls -lh "$gem_file" | awk '{print $5}')
|
|
55
|
+
|
|
56
|
+
success "Built $gem_file"
|
|
57
|
+
info " Files: $file_count"
|
|
58
|
+
info " Size: $file_size"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Check if gem version exists on RubyGems
|
|
62
|
+
gem_version_exists() {
|
|
63
|
+
local version="$1"
|
|
64
|
+
|
|
65
|
+
debug "Checking if $GEM_NAME ($version) exists on RubyGems..."
|
|
66
|
+
|
|
67
|
+
if gem list --remote "$GEM_NAME" | grep -q "$GEM_NAME ($version)"; then
|
|
68
|
+
debug "Version $version already exists on RubyGems"
|
|
69
|
+
return 0
|
|
70
|
+
else
|
|
71
|
+
debug "Version $version does not exist on RubyGems"
|
|
72
|
+
return 1
|
|
73
|
+
fi
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Publish gem to RubyGems
|
|
77
|
+
publish_gem() {
|
|
78
|
+
local version="$1"
|
|
79
|
+
local gem_file="${GEM_NAME}-${version}.gem"
|
|
80
|
+
|
|
81
|
+
step "Publishing gem to RubyGems..."
|
|
82
|
+
|
|
83
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
84
|
+
info "[DRY RUN] Would publish $gem_file to RubyGems"
|
|
85
|
+
return 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Verify gem file exists
|
|
89
|
+
if [[ ! -f "$gem_file" ]]; then
|
|
90
|
+
error "Gem file not found: $gem_file (run build first)"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Check if version already exists
|
|
94
|
+
if gem_version_exists "$version"; then
|
|
95
|
+
error "Version $version already exists on RubyGems"
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# Confirm publication
|
|
99
|
+
if ! confirm "Publish $gem_file to RubyGems?"; then
|
|
100
|
+
warn "Gem publication cancelled by user"
|
|
101
|
+
return 1
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Publish
|
|
105
|
+
if ! gem push "$gem_file"; then
|
|
106
|
+
error "Failed to publish gem to RubyGems"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
success "Published $gem_file to RubyGems"
|
|
110
|
+
info "View at: https://rubygems.org/gems/$GEM_NAME/versions/$version"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# Create GitHub release
|
|
114
|
+
create_github_release() {
|
|
115
|
+
local version="$1"
|
|
116
|
+
local tag="v$version"
|
|
117
|
+
local gem_file="${GEM_NAME}-${version}.gem"
|
|
118
|
+
|
|
119
|
+
step "Creating GitHub release for $tag..."
|
|
120
|
+
|
|
121
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
122
|
+
info "[DRY RUN] Would create GitHub release for $tag"
|
|
123
|
+
return 0
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
# Check if gh CLI is available
|
|
127
|
+
if ! command_exists "gh"; then
|
|
128
|
+
warn "GitHub CLI (gh) not found. Skipping GitHub release."
|
|
129
|
+
info "Install from: https://cli.github.com/"
|
|
130
|
+
return 1
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# Extract release notes from CHANGELOG
|
|
134
|
+
local release_notes
|
|
135
|
+
release_notes=$(extract_release_notes "$version")
|
|
136
|
+
|
|
137
|
+
if [[ -z "$release_notes" ]]; then
|
|
138
|
+
warn "No release notes found in CHANGELOG for version $version"
|
|
139
|
+
release_notes="Release version $version"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Save release notes to temp file
|
|
143
|
+
local notes_file=$(mktemp)
|
|
144
|
+
echo "$release_notes" > "$notes_file"
|
|
145
|
+
|
|
146
|
+
# Create release
|
|
147
|
+
local gh_args=(
|
|
148
|
+
"release" "create" "$tag"
|
|
149
|
+
"--title" "🚀 Jekyll Theme Zer0 $tag"
|
|
150
|
+
"--notes-file" "$notes_file"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# Add gem file if it exists
|
|
154
|
+
if [[ -f "$gem_file" ]]; then
|
|
155
|
+
gh_args+=("$gem_file")
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
if gh "${gh_args[@]}"; then
|
|
159
|
+
success "Created GitHub release for $tag"
|
|
160
|
+
info "View at: https://github.com/$(get_repo_info)/releases/tag/$tag"
|
|
161
|
+
else
|
|
162
|
+
warn "Failed to create GitHub release"
|
|
163
|
+
rm -f "$notes_file"
|
|
164
|
+
return 1
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
rm -f "$notes_file"
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
# Run tests
|
|
171
|
+
run_tests() {
|
|
172
|
+
step "Running test suite..."
|
|
173
|
+
|
|
174
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
175
|
+
info "[DRY RUN] Would run: bundle exec rspec"
|
|
176
|
+
return 0
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
# Install dependencies if needed
|
|
180
|
+
if [[ ! -d "vendor/bundle" ]]; then
|
|
181
|
+
info "Installing dependencies..."
|
|
182
|
+
bundle install --quiet
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
# Run tests
|
|
186
|
+
if bundle exec rspec; then
|
|
187
|
+
success "All tests passed"
|
|
188
|
+
else
|
|
189
|
+
error "Tests failed. Fix issues before proceeding."
|
|
190
|
+
fi
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
# Clean up gem files
|
|
194
|
+
cleanup_gem_files() {
|
|
195
|
+
local version="${1:-}"
|
|
196
|
+
|
|
197
|
+
step "Cleaning up gem files..."
|
|
198
|
+
|
|
199
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
200
|
+
info "[DRY RUN] Would remove gem files"
|
|
201
|
+
return 0
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
if [[ -n "$version" ]]; then
|
|
205
|
+
local gem_file="${GEM_NAME}-${version}.gem"
|
|
206
|
+
if [[ -f "$gem_file" ]]; then
|
|
207
|
+
if confirm "Remove local gem file $gem_file?"; then
|
|
208
|
+
rm -f "$gem_file"
|
|
209
|
+
info "Removed $gem_file"
|
|
210
|
+
fi
|
|
211
|
+
fi
|
|
212
|
+
else
|
|
213
|
+
if confirm "Remove all local gem files?"; then
|
|
214
|
+
rm -f ${GEM_NAME}-*.gem
|
|
215
|
+
info "Removed all gem files"
|
|
216
|
+
fi
|
|
217
|
+
fi
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
# Export functions
|
|
221
|
+
export -f build_gem
|
|
222
|
+
export -f gem_version_exists
|
|
223
|
+
export -f publish_gem
|
|
224
|
+
export -f create_github_release
|
|
225
|
+
export -f run_tests
|
|
226
|
+
export -f cleanup_gem_files
|
data/scripts/lib/git.sh
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Git operations library for zer0-mistakes release scripts
|
|
4
|
+
# Provides functions for tags, commits, and repository operations
|
|
5
|
+
|
|
6
|
+
# Source common utilities
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
source "$SCRIPT_DIR/common.sh"
|
|
9
|
+
|
|
10
|
+
# Get the last version tag
|
|
11
|
+
get_last_version_tag() {
|
|
12
|
+
debug "Finding last version tag..."
|
|
13
|
+
|
|
14
|
+
local last_tag
|
|
15
|
+
last_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
|
16
|
+
|
|
17
|
+
if [[ -z "$last_tag" ]]; then
|
|
18
|
+
# If no tags exist, use initial commit
|
|
19
|
+
last_tag=$(git rev-list --max-parents=0 HEAD)
|
|
20
|
+
debug "No tags found, using initial commit: $last_tag"
|
|
21
|
+
else
|
|
22
|
+
debug "Last version tag: $last_tag"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
echo "$last_tag"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Check if tag exists
|
|
29
|
+
tag_exists() {
|
|
30
|
+
local tag="$1"
|
|
31
|
+
git tag -l | grep -q "^$tag$"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Get commits between two references
|
|
35
|
+
get_commits_between() {
|
|
36
|
+
local from_ref="$1"
|
|
37
|
+
local to_ref="${2:-HEAD}"
|
|
38
|
+
|
|
39
|
+
debug "Getting commits: $from_ref..$to_ref"
|
|
40
|
+
|
|
41
|
+
git log --pretty=format:"%H|%s|%an|%ad" --date=short "$from_ref..$to_ref" 2>/dev/null || echo ""
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Get files changed in a commit
|
|
45
|
+
get_commit_files() {
|
|
46
|
+
local commit_hash="$1"
|
|
47
|
+
|
|
48
|
+
git diff-tree --no-commit-id --name-only -r "$commit_hash" 2>/dev/null || echo ""
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Get commit message
|
|
52
|
+
get_commit_message() {
|
|
53
|
+
local commit_hash="$1"
|
|
54
|
+
|
|
55
|
+
git log --format="%s%n%b" -n 1 "$commit_hash"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Get commit subject (first line)
|
|
59
|
+
get_commit_subject() {
|
|
60
|
+
local commit_hash="$1"
|
|
61
|
+
|
|
62
|
+
git log --format="%s" -n 1 "$commit_hash"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Create git commit
|
|
66
|
+
create_commit() {
|
|
67
|
+
local version="$1"
|
|
68
|
+
local message="${2:-Release version $version}"
|
|
69
|
+
|
|
70
|
+
step "Creating commit..."
|
|
71
|
+
|
|
72
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
73
|
+
info "[DRY RUN] Would create commit: $message"
|
|
74
|
+
return 0
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Add files
|
|
78
|
+
git add lib/jekyll-theme-zer0/version.rb CHANGELOG.md
|
|
79
|
+
[[ -f "package.json" ]] && git add package.json
|
|
80
|
+
|
|
81
|
+
# Create commit
|
|
82
|
+
git commit -m "chore: release version $version
|
|
83
|
+
|
|
84
|
+
- Version bump to $version
|
|
85
|
+
- Updated changelog with commit history
|
|
86
|
+
- Automated release via release script" || error "Failed to create commit"
|
|
87
|
+
|
|
88
|
+
success "Created commit for version $version"
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# Create git tag
|
|
92
|
+
create_tag() {
|
|
93
|
+
local version="$1"
|
|
94
|
+
local tag="v$version"
|
|
95
|
+
local message="${2:-Release version $version}"
|
|
96
|
+
|
|
97
|
+
step "Creating tag $tag..."
|
|
98
|
+
|
|
99
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
100
|
+
info "[DRY RUN] Would create tag: $tag"
|
|
101
|
+
return 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
if tag_exists "$tag"; then
|
|
105
|
+
warn "Tag $tag already exists"
|
|
106
|
+
if ! confirm "Overwrite existing tag $tag?"; then
|
|
107
|
+
error "Tag creation cancelled"
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# Delete existing tag
|
|
111
|
+
git tag -d "$tag"
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# Create annotated tag
|
|
115
|
+
git tag -a "$tag" -m "$message" || error "Failed to create tag $tag"
|
|
116
|
+
|
|
117
|
+
success "Created tag $tag"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# Commit and tag together
|
|
121
|
+
commit_and_tag() {
|
|
122
|
+
local version="$1"
|
|
123
|
+
|
|
124
|
+
create_commit "$version"
|
|
125
|
+
create_tag "$version"
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# Push changes to remote
|
|
129
|
+
push_changes() {
|
|
130
|
+
local remote="${1:-origin}"
|
|
131
|
+
local branch="${2:-main}"
|
|
132
|
+
|
|
133
|
+
step "Pushing changes to $remote/$branch..."
|
|
134
|
+
|
|
135
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
136
|
+
info "[DRY RUN] Would push to $remote $branch --tags"
|
|
137
|
+
return 0
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
if ! confirm "Push changes and tags to $remote/$branch?"; then
|
|
141
|
+
warn "Push cancelled by user"
|
|
142
|
+
return 1
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Push branch and tags
|
|
146
|
+
git push "$remote" "$branch" --tags || error "Failed to push changes"
|
|
147
|
+
|
|
148
|
+
success "Pushed changes and tags to $remote/$branch"
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# Get current branch
|
|
152
|
+
get_current_branch() {
|
|
153
|
+
git rev-parse --abbrev-ref HEAD
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# Get remote URL
|
|
157
|
+
get_remote_url() {
|
|
158
|
+
local remote="${1:-origin}"
|
|
159
|
+
|
|
160
|
+
git remote get-url "$remote" 2>/dev/null || echo ""
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# Extract owner/repo from remote URL
|
|
164
|
+
get_repo_info() {
|
|
165
|
+
local remote="${1:-origin}"
|
|
166
|
+
local url
|
|
167
|
+
|
|
168
|
+
url=$(get_remote_url "$remote")
|
|
169
|
+
|
|
170
|
+
if [[ -z "$url" ]]; then
|
|
171
|
+
error "Could not get remote URL for $remote"
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# Extract owner/repo from various Git URL formats
|
|
175
|
+
if [[ "$url" =~ github\.com[:/]([^/]+)/([^/.]+) ]]; then
|
|
176
|
+
local owner="${BASH_REMATCH[1]}"
|
|
177
|
+
local repo="${BASH_REMATCH[2]}"
|
|
178
|
+
echo "$owner/$repo"
|
|
179
|
+
else
|
|
180
|
+
error "Could not parse GitHub owner/repo from URL: $url"
|
|
181
|
+
fi
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# Count commits since tag
|
|
185
|
+
count_commits_since() {
|
|
186
|
+
local from_ref="$1"
|
|
187
|
+
|
|
188
|
+
git rev-list --count "$from_ref..HEAD" 2>/dev/null || echo "0"
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
# Export functions
|
|
192
|
+
export -f get_last_version_tag
|
|
193
|
+
export -f tag_exists
|
|
194
|
+
export -f get_commits_between
|
|
195
|
+
export -f get_commit_files
|
|
196
|
+
export -f get_commit_message
|
|
197
|
+
export -f get_commit_subject
|
|
198
|
+
export -f create_commit
|
|
199
|
+
export -f create_tag
|
|
200
|
+
export -f commit_and_tag
|
|
201
|
+
export -f push_changes
|
|
202
|
+
export -f get_current_branch
|
|
203
|
+
export -f get_remote_url
|
|
204
|
+
export -f get_repo_info
|
|
205
|
+
export -f count_commits_since
|