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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -0
  3. data/README.md +33 -4
  4. data/_plugins/preview_image_generator.rb +258 -0
  5. data/_plugins/theme_version.rb +88 -0
  6. data/assets/images/previews/git-workflow-best-practices-for-modern-teams.png +0 -0
  7. data/scripts/README.md +443 -0
  8. data/scripts/analyze-commits.sh +313 -0
  9. data/scripts/build +115 -0
  10. data/scripts/build.sh +33 -0
  11. data/scripts/build.sh.legacy +174 -0
  12. data/scripts/example-usage.sh +102 -0
  13. data/scripts/fix-markdown-format.sh +265 -0
  14. data/scripts/gem-publish.sh +42 -0
  15. data/scripts/gem-publish.sh.legacy +700 -0
  16. data/scripts/generate-preview-images.sh +846 -0
  17. data/scripts/install-preview-generator.sh +531 -0
  18. data/scripts/lib/README.md +263 -0
  19. data/scripts/lib/changelog.sh +313 -0
  20. data/scripts/lib/common.sh +154 -0
  21. data/scripts/lib/gem.sh +226 -0
  22. data/scripts/lib/git.sh +205 -0
  23. data/scripts/lib/preview_generator.py +646 -0
  24. data/scripts/lib/test/run_tests.sh +140 -0
  25. data/scripts/lib/test/test_changelog.sh +87 -0
  26. data/scripts/lib/test/test_gem.sh +68 -0
  27. data/scripts/lib/test/test_git.sh +82 -0
  28. data/scripts/lib/test/test_validation.sh +72 -0
  29. data/scripts/lib/test/test_version.sh +96 -0
  30. data/scripts/lib/validation.sh +139 -0
  31. data/scripts/lib/version.sh +178 -0
  32. data/scripts/release +240 -0
  33. data/scripts/release.sh +33 -0
  34. data/scripts/release.sh.legacy +342 -0
  35. data/scripts/setup.sh +155 -0
  36. data/scripts/test-auto-version.sh +260 -0
  37. data/scripts/test-mermaid.sh +251 -0
  38. data/scripts/test.sh +156 -0
  39. data/scripts/version.sh +152 -0
  40. 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
@@ -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
@@ -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