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,700 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Comprehensive Gem Publication Script for zer0-mistakes Jekyll theme
|
|
4
|
+
# Usage: ./scripts/gem-publish.sh [patch|minor|major] [options]
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Colors for output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
CYAN='\033[0;36m'
|
|
14
|
+
PURPLE='\033[0;35m'
|
|
15
|
+
NC='\033[0m' # No Color
|
|
16
|
+
|
|
17
|
+
# Default values
|
|
18
|
+
VERSION_TYPE="${1:-patch}"
|
|
19
|
+
DRY_RUN=false
|
|
20
|
+
SKIP_TESTS=false
|
|
21
|
+
SKIP_CHANGELOG=false
|
|
22
|
+
SKIP_PUBLISH=false
|
|
23
|
+
CREATE_GITHUB_RELEASE=true
|
|
24
|
+
INTERACTIVE=true
|
|
25
|
+
AUTOMATED_RELEASE=false
|
|
26
|
+
AUTO_COMMIT_RANGE=""
|
|
27
|
+
|
|
28
|
+
# Parse arguments
|
|
29
|
+
while [[ $# -gt 0 ]]; do
|
|
30
|
+
case $1 in
|
|
31
|
+
--dry-run)
|
|
32
|
+
DRY_RUN=true
|
|
33
|
+
shift
|
|
34
|
+
;;
|
|
35
|
+
--skip-tests)
|
|
36
|
+
SKIP_TESTS=true
|
|
37
|
+
shift
|
|
38
|
+
;;
|
|
39
|
+
--skip-changelog)
|
|
40
|
+
SKIP_CHANGELOG=true
|
|
41
|
+
shift
|
|
42
|
+
;;
|
|
43
|
+
--skip-publish)
|
|
44
|
+
SKIP_PUBLISH=true
|
|
45
|
+
shift
|
|
46
|
+
;;
|
|
47
|
+
--no-github-release)
|
|
48
|
+
CREATE_GITHUB_RELEASE=false
|
|
49
|
+
shift
|
|
50
|
+
;;
|
|
51
|
+
--non-interactive)
|
|
52
|
+
INTERACTIVE=false
|
|
53
|
+
shift
|
|
54
|
+
;;
|
|
55
|
+
--automated-release)
|
|
56
|
+
AUTOMATED_RELEASE=true
|
|
57
|
+
INTERACTIVE=false
|
|
58
|
+
shift
|
|
59
|
+
;;
|
|
60
|
+
--auto-commit-range=*)
|
|
61
|
+
AUTO_COMMIT_RANGE="${1#*=}"
|
|
62
|
+
shift
|
|
63
|
+
;;
|
|
64
|
+
patch|minor|major)
|
|
65
|
+
VERSION_TYPE="$1"
|
|
66
|
+
shift
|
|
67
|
+
;;
|
|
68
|
+
--help)
|
|
69
|
+
# show_usage will be called after function definitions
|
|
70
|
+
SHOW_HELP=true
|
|
71
|
+
shift
|
|
72
|
+
;;
|
|
73
|
+
*)
|
|
74
|
+
echo -e "${RED}Unknown option: $1${NC}"
|
|
75
|
+
exit 1
|
|
76
|
+
;;
|
|
77
|
+
esac
|
|
78
|
+
done
|
|
79
|
+
|
|
80
|
+
# Function to show usage
|
|
81
|
+
show_usage() {
|
|
82
|
+
cat << EOF
|
|
83
|
+
🚀 Comprehensive Gem Publication Script for zer0-mistakes
|
|
84
|
+
|
|
85
|
+
USAGE:
|
|
86
|
+
./scripts/gem-publish.sh [patch|minor|major] [OPTIONS]
|
|
87
|
+
|
|
88
|
+
VERSION TYPES:
|
|
89
|
+
patch Bump patch version (0.0.X) - Bug fixes
|
|
90
|
+
minor Bump minor version (0.X.0) - New features
|
|
91
|
+
major Bump major version (X.0.0) - Breaking changes
|
|
92
|
+
|
|
93
|
+
OPTIONS:
|
|
94
|
+
--dry-run Show what would be done without making changes
|
|
95
|
+
--skip-tests Skip running tests before release
|
|
96
|
+
--skip-changelog Skip automatic changelog generation
|
|
97
|
+
--skip-publish Skip publishing to RubyGems
|
|
98
|
+
--no-github-release Skip creating GitHub release
|
|
99
|
+
--non-interactive Run without user prompts
|
|
100
|
+
--automated-release Enable fully automated release mode
|
|
101
|
+
--auto-commit-range=RANGE Use specific commit range for changelog
|
|
102
|
+
--help Show this help message
|
|
103
|
+
|
|
104
|
+
WORKFLOW:
|
|
105
|
+
1. Validate environment and dependencies
|
|
106
|
+
2. Generate changelog from commit history
|
|
107
|
+
3. Version bump and update files
|
|
108
|
+
4. Run comprehensive tests
|
|
109
|
+
5. Build and validate gem
|
|
110
|
+
6. Publish to RubyGems
|
|
111
|
+
7. Create GitHub Release with assets
|
|
112
|
+
8. Push changes and tags to repository
|
|
113
|
+
|
|
114
|
+
EXAMPLES:
|
|
115
|
+
./scripts/gem-publish.sh patch # Patch release with full workflow
|
|
116
|
+
./scripts/gem-publish.sh minor --dry-run # Preview minor version bump
|
|
117
|
+
./scripts/gem-publish.sh major --skip-tests # Major release, skip tests
|
|
118
|
+
|
|
119
|
+
EOF
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# Function to log messages with different levels
|
|
123
|
+
log() {
|
|
124
|
+
echo -e "${GREEN}[GEM-PUBLISH]${NC} $1"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
warn() {
|
|
128
|
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
error() {
|
|
132
|
+
echo -e "${RED}[ERROR]${NC} $1"
|
|
133
|
+
exit 1
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
info() {
|
|
137
|
+
echo -e "${BLUE}[INFO]${NC} $1"
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
step() {
|
|
141
|
+
echo -e "${CYAN}[STEP]${NC} $1"
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
success() {
|
|
145
|
+
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# Function to ask for user confirmation
|
|
149
|
+
confirm() {
|
|
150
|
+
if [[ "$INTERACTIVE" == false ]]; then
|
|
151
|
+
return 0
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
echo -e "${YELLOW}$1 (y/N)${NC}"
|
|
155
|
+
read -r response
|
|
156
|
+
[[ "$response" =~ ^[Yy]$ ]]
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Function to validate environment
|
|
160
|
+
validate_environment() {
|
|
161
|
+
step "Validating environment..."
|
|
162
|
+
|
|
163
|
+
# Check if we're in a git repository
|
|
164
|
+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
165
|
+
error "Not in a git repository"
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
# Check if working directory is clean
|
|
169
|
+
if [[ -n $(git status --porcelain) ]]; then
|
|
170
|
+
error "Working directory is not clean. Please commit or stash changes first."
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Check required files
|
|
174
|
+
local required_files=(
|
|
175
|
+
"lib/jekyll-theme-zer0/version.rb"
|
|
176
|
+
"jekyll-theme-zer0.gemspec"
|
|
177
|
+
"CHANGELOG.md"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
for file in "${required_files[@]}"; do
|
|
181
|
+
if [[ ! -f "$file" ]]; then
|
|
182
|
+
error "Required file not found: $file"
|
|
183
|
+
fi
|
|
184
|
+
done
|
|
185
|
+
|
|
186
|
+
# Check required commands
|
|
187
|
+
local required_commands=("git" "ruby" "gem" "bundle" "jq")
|
|
188
|
+
for cmd in "${required_commands[@]}"; do
|
|
189
|
+
if ! command -v "$cmd" &> /dev/null; then
|
|
190
|
+
error "Required command not found: $cmd"
|
|
191
|
+
fi
|
|
192
|
+
done
|
|
193
|
+
|
|
194
|
+
# Check if authenticated with RubyGems
|
|
195
|
+
if [[ "$SKIP_PUBLISH" != true ]] && [[ ! -f ~/.gem/credentials ]]; then
|
|
196
|
+
error "Not authenticated with RubyGems. Run 'gem signin' first."
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
success "Environment validation complete"
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
# Function to get current version
|
|
203
|
+
get_current_version() {
|
|
204
|
+
local version=$(grep -o 'VERSION = "[^"]*"' lib/jekyll-theme-zer0/version.rb | sed 's/VERSION = "\(.*\)"/\1/')
|
|
205
|
+
if [[ -z "$version" ]]; then
|
|
206
|
+
error "Could not read version from lib/jekyll-theme-zer0/version.rb"
|
|
207
|
+
fi
|
|
208
|
+
echo "$version"
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
# Function to calculate new version
|
|
212
|
+
calculate_new_version() {
|
|
213
|
+
local current_version="$1"
|
|
214
|
+
local version_type="$2"
|
|
215
|
+
|
|
216
|
+
IFS='.' read -ra VERSION_PARTS <<< "$current_version"
|
|
217
|
+
local major=${VERSION_PARTS[0]}
|
|
218
|
+
local minor=${VERSION_PARTS[1]}
|
|
219
|
+
local patch=${VERSION_PARTS[2]}
|
|
220
|
+
|
|
221
|
+
case $version_type in
|
|
222
|
+
major)
|
|
223
|
+
major=$((major + 1))
|
|
224
|
+
minor=0
|
|
225
|
+
patch=0
|
|
226
|
+
;;
|
|
227
|
+
minor)
|
|
228
|
+
minor=$((minor + 1))
|
|
229
|
+
patch=0
|
|
230
|
+
;;
|
|
231
|
+
patch)
|
|
232
|
+
patch=$((patch + 1))
|
|
233
|
+
;;
|
|
234
|
+
esac
|
|
235
|
+
|
|
236
|
+
echo "$major.$minor.$patch"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
# Function to get the last version tag
|
|
240
|
+
get_last_version_tag() {
|
|
241
|
+
local last_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
|
242
|
+
if [[ -z "$last_tag" ]]; then
|
|
243
|
+
# If no tags, use initial commit
|
|
244
|
+
echo $(git rev-list --max-parents=0 HEAD)
|
|
245
|
+
else
|
|
246
|
+
echo "$last_tag"
|
|
247
|
+
fi
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
# Function to generate changelog from commits
|
|
251
|
+
generate_changelog() {
|
|
252
|
+
local current_version="$1"
|
|
253
|
+
local new_version="$2"
|
|
254
|
+
local last_tag="$3"
|
|
255
|
+
|
|
256
|
+
step "Generating changelog from commit history..."
|
|
257
|
+
|
|
258
|
+
# Get commits since last version or use provided range
|
|
259
|
+
local commits
|
|
260
|
+
if [[ -n "$AUTO_COMMIT_RANGE" ]]; then
|
|
261
|
+
# Use the provided commit range for automated releases
|
|
262
|
+
log "Using automated commit range: $AUTO_COMMIT_RANGE"
|
|
263
|
+
commits=$(git log --pretty=format:"%H|%s|%an|%ad" --date=short "$AUTO_COMMIT_RANGE")
|
|
264
|
+
elif [[ "$last_tag" =~ ^v[0-9] ]]; then
|
|
265
|
+
commits=$(git log --pretty=format:"%H|%s|%an|%ad" --date=short "${last_tag}..HEAD")
|
|
266
|
+
else
|
|
267
|
+
commits=$(git log --pretty=format:"%H|%s|%an|%ad" --date=short "${last_tag}..HEAD")
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
if [[ -z "$commits" ]]; then
|
|
271
|
+
warn "No commits found since last version tag"
|
|
272
|
+
return 0
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
# Categorize commits
|
|
276
|
+
local added=()
|
|
277
|
+
local changed=()
|
|
278
|
+
local fixed=()
|
|
279
|
+
local deprecated=()
|
|
280
|
+
local removed=()
|
|
281
|
+
local security=()
|
|
282
|
+
local other=()
|
|
283
|
+
|
|
284
|
+
while IFS='|' read -r hash subject author date; do
|
|
285
|
+
local subject_lower=$(echo "$subject" | tr '[:upper:]' '[:lower:]')
|
|
286
|
+
|
|
287
|
+
if [[ "$subject_lower" =~ ^(feat|feature)(\(.*\))?:.*$ ]]; then
|
|
288
|
+
added+=("- $(echo "$subject" | sed 's/^[Ff]eat[ure]*(\([^)]*\)): *//' | sed 's/^[Ff]eat[ure]*: *//')")
|
|
289
|
+
elif [[ "$subject_lower" =~ ^(fix|bugfix)(\(.*\))?:.*$ ]]; then
|
|
290
|
+
fixed+=("- $(echo "$subject" | sed 's/^[Ff]ix[bugfix]*(\([^)]*\)): *//' | sed 's/^[Ff]ix[bugfix]*: *//')")
|
|
291
|
+
elif [[ "$subject_lower" =~ ^(perf|performance)(\(.*\))?:.*$ ]]; then
|
|
292
|
+
changed+=("- Performance: $(echo "$subject" | sed 's/^[Pp]erf[ormance]*(\([^)]*\)): *//' | sed 's/^[Pp]erf[ormance]*: *//')")
|
|
293
|
+
elif [[ "$subject_lower" =~ ^(refactor)(\(.*\))?:.*$ ]]; then
|
|
294
|
+
changed+=("- Refactor: $(echo "$subject" | sed 's/^[Rr]efactor(\([^)]*\)): *//' | sed 's/^[Rr]efactor: *//')")
|
|
295
|
+
elif [[ "$subject_lower" =~ ^(style)(\(.*\))?:.*$ ]]; then
|
|
296
|
+
changed+=("- Style: $(echo "$subject" | sed 's/^[Ss]tyle(\([^)]*\)): *//' | sed 's/^[Ss]tyle: *//')")
|
|
297
|
+
elif [[ "$subject_lower" =~ ^(docs|doc)(\(.*\))?:.*$ ]]; then
|
|
298
|
+
changed+=("- Documentation: $(echo "$subject" | sed 's/^[Dd]ocs*(\([^)]*\)): *//' | sed 's/^[Dd]ocs*: *//')")
|
|
299
|
+
elif [[ "$subject_lower" =~ ^(chore)(\(.*\))?:.*$ ]]; then
|
|
300
|
+
changed+=("- $(echo "$subject" | sed 's/^[Cc]hore(\([^)]*\)): *//' | sed 's/^[Cc]hore: *//')")
|
|
301
|
+
elif [[ "$subject_lower" =~ ^(test)(\(.*\))?:.*$ ]]; then
|
|
302
|
+
changed+=("- Testing: $(echo "$subject" | sed 's/^[Tt]est(\([^)]*\)): *//' | sed 's/^[Tt]est: *//')")
|
|
303
|
+
elif [[ "$subject_lower" =~ ^(ci)(\(.*\))?:.*$ ]]; then
|
|
304
|
+
changed+=("- CI/CD: $(echo "$subject" | sed 's/^[Cc][Ii](\([^)]*\)): *//' | sed 's/^[Cc][Ii]: *//')")
|
|
305
|
+
elif [[ "$subject_lower" =~ ^(build)(\(.*\))?:.*$ ]]; then
|
|
306
|
+
changed+=("- Build: $(echo "$subject" | sed 's/^[Bb]uild(\([^)]*\)): *//' | sed 's/^[Bb]uild: *//')")
|
|
307
|
+
elif [[ "$subject_lower" =~ ^(security|sec)(\(.*\))?:.*$ ]]; then
|
|
308
|
+
security+=("- $(echo "$subject" | sed 's/^[Ss]ec[urity]*(\([^)]*\)): *//' | sed 's/^[Ss]ec[urity]*: *//')")
|
|
309
|
+
elif [[ "$subject_lower" =~ deprecat ]]; then
|
|
310
|
+
deprecated+=("- $(echo "$subject")")
|
|
311
|
+
elif [[ "$subject_lower" =~ ^(remove|rm)(\(.*\))?:.*$ ]]; then
|
|
312
|
+
removed+=("- $(echo "$subject" | sed 's/^[Rr]m*[emove]*(\([^)]*\)): *//' | sed 's/^[Rr]m*[emove]*: *//')")
|
|
313
|
+
else
|
|
314
|
+
other+=("- $subject")
|
|
315
|
+
fi
|
|
316
|
+
done <<< "$commits"
|
|
317
|
+
|
|
318
|
+
# Create changelog entry
|
|
319
|
+
local changelog_entry=""
|
|
320
|
+
local date=$(date +"%Y-%m-%d")
|
|
321
|
+
|
|
322
|
+
changelog_entry+="## [$new_version] - $date\n\n"
|
|
323
|
+
|
|
324
|
+
if [[ ${#added[@]} -gt 0 ]]; then
|
|
325
|
+
changelog_entry+="### Added\n"
|
|
326
|
+
for item in "${added[@]}"; do
|
|
327
|
+
changelog_entry+="$item\n"
|
|
328
|
+
done
|
|
329
|
+
changelog_entry+="\n"
|
|
330
|
+
fi
|
|
331
|
+
|
|
332
|
+
if [[ ${#changed[@]} -gt 0 ]]; then
|
|
333
|
+
changelog_entry+="### Changed\n"
|
|
334
|
+
for item in "${changed[@]}"; do
|
|
335
|
+
changelog_entry+="$item\n"
|
|
336
|
+
done
|
|
337
|
+
changelog_entry+="\n"
|
|
338
|
+
fi
|
|
339
|
+
|
|
340
|
+
if [[ ${#deprecated[@]} -gt 0 ]]; then
|
|
341
|
+
changelog_entry+="### Deprecated\n"
|
|
342
|
+
for item in "${deprecated[@]}"; do
|
|
343
|
+
changelog_entry+="$item\n"
|
|
344
|
+
done
|
|
345
|
+
changelog_entry+="\n"
|
|
346
|
+
fi
|
|
347
|
+
|
|
348
|
+
if [[ ${#removed[@]} -gt 0 ]]; then
|
|
349
|
+
changelog_entry+="### Removed\n"
|
|
350
|
+
for item in "${removed[@]}"; do
|
|
351
|
+
changelog_entry+="$item\n"
|
|
352
|
+
done
|
|
353
|
+
changelog_entry+="\n"
|
|
354
|
+
fi
|
|
355
|
+
|
|
356
|
+
if [[ ${#fixed[@]} -gt 0 ]]; then
|
|
357
|
+
changelog_entry+="### Fixed\n"
|
|
358
|
+
for item in "${fixed[@]}"; do
|
|
359
|
+
changelog_entry+="$item\n"
|
|
360
|
+
done
|
|
361
|
+
changelog_entry+="\n"
|
|
362
|
+
fi
|
|
363
|
+
|
|
364
|
+
if [[ ${#security[@]} -gt 0 ]]; then
|
|
365
|
+
changelog_entry+="### Security\n"
|
|
366
|
+
for item in "${security[@]}"; do
|
|
367
|
+
changelog_entry+="$item\n"
|
|
368
|
+
done
|
|
369
|
+
changelog_entry+="\n"
|
|
370
|
+
fi
|
|
371
|
+
|
|
372
|
+
if [[ ${#other[@]} -gt 0 ]]; then
|
|
373
|
+
changelog_entry+="### Other\n"
|
|
374
|
+
for item in "${other[@]}"; do
|
|
375
|
+
changelog_entry+="$item\n"
|
|
376
|
+
done
|
|
377
|
+
changelog_entry+="\n"
|
|
378
|
+
fi
|
|
379
|
+
|
|
380
|
+
# Update CHANGELOG.md
|
|
381
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
382
|
+
# Create backup
|
|
383
|
+
cp CHANGELOG.md CHANGELOG.md.bak
|
|
384
|
+
|
|
385
|
+
# Insert new entry after the first line (preserving header)
|
|
386
|
+
{
|
|
387
|
+
head -n 1 CHANGELOG.md
|
|
388
|
+
echo ""
|
|
389
|
+
echo -e "$changelog_entry"
|
|
390
|
+
tail -n +2 CHANGELOG.md
|
|
391
|
+
} > CHANGELOG.md.tmp && mv CHANGELOG.md.tmp CHANGELOG.md
|
|
392
|
+
|
|
393
|
+
rm CHANGELOG.md.bak 2>/dev/null || true
|
|
394
|
+
fi
|
|
395
|
+
|
|
396
|
+
info "Generated changelog entry for version $new_version"
|
|
397
|
+
echo -e "${PURPLE}Changelog Preview:${NC}"
|
|
398
|
+
echo -e "$changelog_entry" | head -20
|
|
399
|
+
|
|
400
|
+
if [[ "$INTERACTIVE" == true ]]; then
|
|
401
|
+
echo -e "${YELLOW}Continue with this changelog? (y/N)${NC}"
|
|
402
|
+
read -r response
|
|
403
|
+
if [[ ! "$response" =~ ^[Yy]$ ]]; then
|
|
404
|
+
error "Changelog generation cancelled by user"
|
|
405
|
+
fi
|
|
406
|
+
fi
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
# Function to update version in files
|
|
410
|
+
update_version_files() {
|
|
411
|
+
local new_version="$1"
|
|
412
|
+
|
|
413
|
+
step "Updating version in files..."
|
|
414
|
+
|
|
415
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
416
|
+
info "Would update version to $new_version in:"
|
|
417
|
+
info " - lib/jekyll-theme-zer0/version.rb"
|
|
418
|
+
info " - package.json"
|
|
419
|
+
return 0
|
|
420
|
+
fi
|
|
421
|
+
|
|
422
|
+
# Update version.rb
|
|
423
|
+
sed -i.bak "s/VERSION = \".*\"/VERSION = \"$new_version\"/" lib/jekyll-theme-zer0/version.rb
|
|
424
|
+
rm lib/jekyll-theme-zer0/version.rb.bak 2>/dev/null || true
|
|
425
|
+
|
|
426
|
+
# Update package.json if it exists
|
|
427
|
+
if [[ -f "package.json" ]]; then
|
|
428
|
+
jq ".version = \"$new_version\"" package.json > package.json.tmp && mv package.json.tmp package.json
|
|
429
|
+
fi
|
|
430
|
+
|
|
431
|
+
success "Version files updated to $new_version"
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
# Function to run tests
|
|
435
|
+
run_tests() {
|
|
436
|
+
if [[ "$SKIP_TESTS" == true ]]; then
|
|
437
|
+
warn "Skipping tests as requested"
|
|
438
|
+
return 0
|
|
439
|
+
fi
|
|
440
|
+
|
|
441
|
+
step "Running test suite..."
|
|
442
|
+
|
|
443
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
444
|
+
info "Would run: bundle exec rspec"
|
|
445
|
+
return 0
|
|
446
|
+
fi
|
|
447
|
+
|
|
448
|
+
# Install dependencies
|
|
449
|
+
bundle install --quiet
|
|
450
|
+
|
|
451
|
+
# Run tests
|
|
452
|
+
if bundle exec rspec; then
|
|
453
|
+
success "All tests passed"
|
|
454
|
+
else
|
|
455
|
+
error "Tests failed. Fix issues before proceeding."
|
|
456
|
+
fi
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
# Function to build gem
|
|
460
|
+
build_gem() {
|
|
461
|
+
local version="$1"
|
|
462
|
+
|
|
463
|
+
step "Building gem..."
|
|
464
|
+
|
|
465
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
466
|
+
info "Would build jekyll-theme-zer0-${version}.gem"
|
|
467
|
+
return 0
|
|
468
|
+
fi
|
|
469
|
+
|
|
470
|
+
# Clean up old gem files
|
|
471
|
+
rm -f jekyll-theme-zer0-*.gem
|
|
472
|
+
|
|
473
|
+
# Validate gemspec
|
|
474
|
+
ruby -c jekyll-theme-zer0.gemspec > /dev/null
|
|
475
|
+
|
|
476
|
+
# Build gem
|
|
477
|
+
if gem build jekyll-theme-zer0.gemspec; then
|
|
478
|
+
success "Successfully built jekyll-theme-zer0-${version}.gem"
|
|
479
|
+
|
|
480
|
+
# Show gem contents summary
|
|
481
|
+
info "Gem contents summary:"
|
|
482
|
+
local file_count=$(tar -tzf "jekyll-theme-zer0-${version}.gem" | wc -l)
|
|
483
|
+
info " Total files: $file_count"
|
|
484
|
+
info " Gem size: $(ls -lh jekyll-theme-zer0-${version}.gem | awk '{print $5}')"
|
|
485
|
+
else
|
|
486
|
+
error "Failed to build gem"
|
|
487
|
+
fi
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
# Function to publish gem
|
|
491
|
+
publish_gem() {
|
|
492
|
+
local version="$1"
|
|
493
|
+
|
|
494
|
+
if [[ "$SKIP_PUBLISH" == true ]]; then
|
|
495
|
+
warn "Skipping gem publication as requested"
|
|
496
|
+
return 0
|
|
497
|
+
fi
|
|
498
|
+
|
|
499
|
+
step "Publishing gem to RubyGems..."
|
|
500
|
+
|
|
501
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
502
|
+
info "Would publish jekyll-theme-zer0-${version}.gem to RubyGems"
|
|
503
|
+
return 0
|
|
504
|
+
fi
|
|
505
|
+
|
|
506
|
+
# Check if version already exists
|
|
507
|
+
if gem list --remote jekyll-theme-zer0 | grep -q "jekyll-theme-zer0 (${version})"; then
|
|
508
|
+
error "Version ${version} already exists on RubyGems"
|
|
509
|
+
fi
|
|
510
|
+
|
|
511
|
+
# Publish
|
|
512
|
+
if confirm "Publish jekyll-theme-zer0-${version}.gem to RubyGems?"; then
|
|
513
|
+
if gem push "jekyll-theme-zer0-${version}.gem"; then
|
|
514
|
+
success "Successfully published to RubyGems"
|
|
515
|
+
info "Gem available at: https://rubygems.org/gems/jekyll-theme-zer0"
|
|
516
|
+
else
|
|
517
|
+
error "Failed to publish gem"
|
|
518
|
+
fi
|
|
519
|
+
else
|
|
520
|
+
warn "Gem publication cancelled by user"
|
|
521
|
+
fi
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
# Function to commit and tag
|
|
525
|
+
commit_and_tag() {
|
|
526
|
+
local version="$1"
|
|
527
|
+
|
|
528
|
+
step "Committing changes and creating tag..."
|
|
529
|
+
|
|
530
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
531
|
+
info "Would commit changes and create tag v$version"
|
|
532
|
+
return 0
|
|
533
|
+
fi
|
|
534
|
+
|
|
535
|
+
# Add files to git
|
|
536
|
+
git add lib/jekyll-theme-zer0/version.rb CHANGELOG.md
|
|
537
|
+
[[ -f "package.json" ]] && git add package.json
|
|
538
|
+
|
|
539
|
+
# Commit
|
|
540
|
+
git commit -m "chore: release version $version
|
|
541
|
+
|
|
542
|
+
- Version bump to $version
|
|
543
|
+
- Updated changelog with commit history
|
|
544
|
+
- Automated release via gem-publish script"
|
|
545
|
+
|
|
546
|
+
# Create tag
|
|
547
|
+
git tag -a "v$version" -m "Release version $version"
|
|
548
|
+
|
|
549
|
+
success "Created commit and tag v$version"
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
# Function to create GitHub release
|
|
553
|
+
create_github_release() {
|
|
554
|
+
local version="$1"
|
|
555
|
+
|
|
556
|
+
if [[ "$CREATE_GITHUB_RELEASE" != true ]]; then
|
|
557
|
+
warn "Skipping GitHub release creation as requested"
|
|
558
|
+
return 0
|
|
559
|
+
fi
|
|
560
|
+
|
|
561
|
+
step "Creating GitHub release..."
|
|
562
|
+
|
|
563
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
564
|
+
info "Would create GitHub release for v$version"
|
|
565
|
+
return 0
|
|
566
|
+
fi
|
|
567
|
+
|
|
568
|
+
# Check if gh CLI is available
|
|
569
|
+
if ! command -v gh &> /dev/null; then
|
|
570
|
+
warn "GitHub CLI (gh) not found. Skipping GitHub release creation."
|
|
571
|
+
info "You can create the release manually at: https://github.com/bamr87/zer0-mistakes/releases/new"
|
|
572
|
+
return 0
|
|
573
|
+
fi
|
|
574
|
+
|
|
575
|
+
# Extract changelog for this version
|
|
576
|
+
local release_notes=$(awk "/^## \[$version\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md)
|
|
577
|
+
|
|
578
|
+
# Create release
|
|
579
|
+
if gh release create "v$version" \
|
|
580
|
+
--title "Release v$version" \
|
|
581
|
+
--notes "$release_notes" \
|
|
582
|
+
"jekyll-theme-zer0-${version}.gem"; then
|
|
583
|
+
success "GitHub release created successfully"
|
|
584
|
+
else
|
|
585
|
+
warn "Failed to create GitHub release"
|
|
586
|
+
fi
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
# Function to push changes
|
|
590
|
+
push_changes() {
|
|
591
|
+
step "Pushing changes to repository..."
|
|
592
|
+
|
|
593
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
594
|
+
info "Would push changes and tags to origin"
|
|
595
|
+
return 0
|
|
596
|
+
fi
|
|
597
|
+
|
|
598
|
+
if confirm "Push changes and tags to repository?"; then
|
|
599
|
+
git push origin main --tags
|
|
600
|
+
success "Changes and tags pushed to repository"
|
|
601
|
+
else
|
|
602
|
+
warn "Repository push cancelled by user"
|
|
603
|
+
fi
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
# Function to cleanup
|
|
607
|
+
cleanup() {
|
|
608
|
+
step "Cleaning up temporary files..."
|
|
609
|
+
|
|
610
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
611
|
+
# Remove gem file after successful publication
|
|
612
|
+
if [[ "$SKIP_PUBLISH" != true ]] && [[ -f "jekyll-theme-zer0-${NEW_VERSION}.gem" ]]; then
|
|
613
|
+
if confirm "Remove local gem file?"; then
|
|
614
|
+
rm -f "jekyll-theme-zer0-${NEW_VERSION}.gem"
|
|
615
|
+
info "Local gem file removed"
|
|
616
|
+
fi
|
|
617
|
+
fi
|
|
618
|
+
fi
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
# Main execution function
|
|
622
|
+
main() {
|
|
623
|
+
# Check if help was requested
|
|
624
|
+
if [[ "${SHOW_HELP:-false}" == true ]]; then
|
|
625
|
+
show_usage
|
|
626
|
+
exit 0
|
|
627
|
+
fi
|
|
628
|
+
|
|
629
|
+
if [[ "$AUTOMATED_RELEASE" == true ]]; then
|
|
630
|
+
echo -e "${CYAN}🤖 Automated Release Mode${NC}"
|
|
631
|
+
echo -e "${CYAN}Version: $VERSION_TYPE bump (automatic)${NC}"
|
|
632
|
+
else
|
|
633
|
+
echo -e "${PURPLE}🚀 Comprehensive Gem Publication Script${NC}"
|
|
634
|
+
echo -e "${PURPLE}Version: $VERSION_TYPE bump${NC}"
|
|
635
|
+
fi
|
|
636
|
+
echo ""
|
|
637
|
+
|
|
638
|
+
# Validate environment
|
|
639
|
+
validate_environment
|
|
640
|
+
|
|
641
|
+
# Get current version
|
|
642
|
+
local current_version=$(get_current_version)
|
|
643
|
+
info "Current version: $current_version"
|
|
644
|
+
|
|
645
|
+
# Calculate new version
|
|
646
|
+
local new_version=$(calculate_new_version "$current_version" "$VERSION_TYPE")
|
|
647
|
+
info "New version: $new_version"
|
|
648
|
+
|
|
649
|
+
# Get last version tag for changelog
|
|
650
|
+
local last_tag=$(get_last_version_tag)
|
|
651
|
+
info "Last version tag: $last_tag"
|
|
652
|
+
|
|
653
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
654
|
+
echo -e "${YELLOW}🔍 DRY RUN MODE - No changes will be made${NC}"
|
|
655
|
+
echo ""
|
|
656
|
+
fi
|
|
657
|
+
|
|
658
|
+
# Show summary
|
|
659
|
+
echo -e "${CYAN}📋 Release Summary:${NC}"
|
|
660
|
+
echo -e " Current Version: $current_version"
|
|
661
|
+
echo -e " New Version: $new_version"
|
|
662
|
+
echo -e " Version Type: $VERSION_TYPE"
|
|
663
|
+
echo -e " Last Tag: $last_tag"
|
|
664
|
+
echo ""
|
|
665
|
+
|
|
666
|
+
if [[ "$INTERACTIVE" == true ]] && ! confirm "Continue with release?"; then
|
|
667
|
+
info "Release cancelled by user"
|
|
668
|
+
exit 0
|
|
669
|
+
fi
|
|
670
|
+
|
|
671
|
+
# Execute release workflow
|
|
672
|
+
if [[ "$SKIP_CHANGELOG" != true ]]; then
|
|
673
|
+
generate_changelog "$current_version" "$new_version" "$last_tag"
|
|
674
|
+
fi
|
|
675
|
+
|
|
676
|
+
update_version_files "$new_version"
|
|
677
|
+
run_tests
|
|
678
|
+
build_gem "$new_version"
|
|
679
|
+
commit_and_tag "$new_version"
|
|
680
|
+
publish_gem "$new_version"
|
|
681
|
+
create_github_release "$new_version"
|
|
682
|
+
push_changes
|
|
683
|
+
cleanup
|
|
684
|
+
|
|
685
|
+
# Final success message
|
|
686
|
+
echo ""
|
|
687
|
+
echo -e "${GREEN}🎉 Release Complete!${NC}"
|
|
688
|
+
echo -e "${GREEN}Version $new_version has been successfully released${NC}"
|
|
689
|
+
echo ""
|
|
690
|
+
echo -e "${CYAN}📋 Release Information:${NC}"
|
|
691
|
+
echo -e " 📦 RubyGems: https://rubygems.org/gems/jekyll-theme-zer0"
|
|
692
|
+
echo -e " 🏷️ GitHub Release: https://github.com/bamr87/zer0-mistakes/releases/tag/v$new_version"
|
|
693
|
+
echo -e " 🔄 Repository: https://github.com/bamr87/zer0-mistakes"
|
|
694
|
+
echo ""
|
|
695
|
+
|
|
696
|
+
export NEW_VERSION="$new_version"
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
# Run main function
|
|
700
|
+
main "$@"
|