jekyll-theme-zer0 0.22.22 → 1.0.0
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 +30 -21
- data/README.md +3 -3
- data/scripts/lib/changelog.sh +24 -17
- data/scripts/test/lib/run_tests.sh +1 -0
- data/scripts/test/lib/test_analyze_commits.sh +109 -0
- data/scripts/utils/analyze-commits +37 -17
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb0abcd4c89fc980be5dc8a2ca5d073a32e248d7bea194c9eb905bd02453f3b4
|
|
4
|
+
data.tar.gz: 156f5db5110105ad33e03d7e3be40ec8ff56f8d5cdab6c2cd5cdd8ababd190f2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd44c6d89e293c8d03e6599ff58cb1cc568e0c9281d360ddc49300ef54b9eb56bc32d8e4508fad22b821b3782d87c6ed8a79c706faf65fbc1e9d1399869c16ac
|
|
7
|
+
data.tar.gz: b3823b150fccbcd91c52919686e9f904e28945f0e235e52b7d26b0a5407f51e562f682b3efbd2add0a3e30185c513b26070f1941029813bb15b65e9cf9b5445c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.
|
|
3
|
+
## [1.0.0] - 2026-04-20
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
First stable major release. Consolidates the breaking-change installer rewrite
|
|
6
|
+
(shipped in error as v0.22.22 due to a silent bug in the version analyzer) and
|
|
7
|
+
the fix that restored the release automation.
|
|
7
8
|
|
|
8
|
-
###
|
|
9
|
-
- 36cd015 feat(installer)!: modular installer + AI + deploy targets + test matrix (#76)
|
|
10
|
-
- 555bead docs(readme): add AI-native branding and GitHub Actions automation section
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## [Unreleased — targeting 1.0.0]
|
|
14
|
-
|
|
15
|
-
### ⚠️ Breaking changes (1.0.0 prep)
|
|
9
|
+
### ⚠️ Breaking changes
|
|
16
10
|
|
|
17
11
|
- **Modular installer.** The 2,400-line monolithic `install.sh` is decomposed into a CLI dispatcher (`scripts/bin/install`) backed by focused library modules (`scripts/lib/install/*.sh`) and declarative YAML profiles (`templates/profiles/*.yml`). The legacy `curl | bash` one-liner still works — it bootstraps the same pipeline.
|
|
18
12
|
- **Legacy mode flags deprecated.** `--full`, `--minimal`, `--fork`, `--remote`, `--github` continue to work in 1.0.x with a one-line deprecation warning. They map 1:1 to `install init --profile <name>`. Targeted removal: 2.0.
|
|
@@ -21,7 +15,9 @@
|
|
|
21
15
|
|
|
22
16
|
See [`docs/installation/migration-from-0.x.md`](docs/installation/migration-from-0.x.md) for the full flag-by-flag mapping.
|
|
23
17
|
|
|
24
|
-
### Added
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
#### Modular installer (Phases 1-7 of the refactor)
|
|
25
21
|
|
|
26
22
|
- **`scripts/bin/install`** — canonical CLI with subcommands: `init`, `wizard [--ai]`, `agents`, `deploy`, `doctor [--ai] [--quiet] [--json]`, `diagnose [--ai]`, `upgrade`, `list-profiles`, `list-targets`, `version`, `help`.
|
|
27
23
|
- **`scripts/lib/install/`** — focused modules: `core`, `platform`, `template`, `fs`, `config`, `pages`, `profile`, `wizard_interactive`, `doctor`, `upgrade`, `agents`, `ai/{openai,wizard,diagnose,suggest}`, `deploy/{registry,github-pages,azure-swa,docker-prod}`. All bash 3.2 compatible.
|
|
@@ -34,27 +30,40 @@ See [`docs/installation/migration-from-0.x.md`](docs/installation/migration-from
|
|
|
34
30
|
- **`install doctor`** — platform/tooling/site/AI health check with PASS/WARN/FAIL counters, `--quiet` and `--json` modes. Used as preflight in `install init` (opt out with `--skip-doctor`).
|
|
35
31
|
- **`install upgrade`** — idempotent in-place upgrade tracked via `.zer0-installed`. `--from`, `--force`, `--dry-run`, `--auto-accept`. Refreshes agents and checks deploy-workflow drift.
|
|
36
32
|
- **`docs/installation/`** — full doc tree: `index`, `architecture`, `profiles`, `deploy-targets`, `ai-features`, `migration-from-0.x`, `customization`.
|
|
37
|
-
- **`.github/instructions/install.instructions.md`** — agent guidance for installer code
|
|
33
|
+
- **`.github/instructions/install.instructions.md`** — agent guidance for installer code.
|
|
38
34
|
- **`.github/workflows/doctor.yml`** — CI matrix (ubuntu-latest, macos-latest) running `install doctor --json` on every push/PR touching installer code.
|
|
39
|
-
- **`.github/workflows/install-matrix.yml`** — full installer e2e matrix (ubuntu-latest + macos-latest × ruby 2.7/3.0/3.2) plus a `curl|bash` bootstrap smoke job.
|
|
40
|
-
- **Installer e2e suites** under `test/`:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- **`scripts/bin/test install`** — new test-suite group that executes all `test/test_install_*.sh` files.
|
|
35
|
+
- **`.github/workflows/install-matrix.yml`** — full installer e2e matrix (ubuntu-latest + macos-latest × ruby 2.7/3.0/3.2) plus a `curl|bash` bootstrap smoke job.
|
|
36
|
+
- **Installer e2e suites** under `test/`: `test_install_profiles.sh`, `test_install_deploy.sh`, `test_install_ai_mock.sh`, `test_install_legacy_flags.sh`, `test_install_idempotency.sh`.
|
|
37
|
+
- **`scripts/bin/test install`** — new test-suite group that executes all installer e2e tests.
|
|
38
|
+
|
|
39
|
+
#### Versioning & release automation (new in 1.0.0)
|
|
40
|
+
|
|
41
|
+
- New unit-test file `scripts/test/lib/test_analyze_commits.sh` (15 assertions) covering: scoped conventional types, `!` breaking-change marker, `BREAKING CHANGE` / `BREAKING-CHANGE` footers, and stdout/stderr separation. Wired into `scripts/test/lib/run_tests.sh`.
|
|
47
42
|
|
|
48
43
|
### Fixed
|
|
49
44
|
|
|
45
|
+
- **Versioning automation no longer silently swallows analyzer crashes.** `scripts/utils/analyze-commits` called `log_info` / `log_warning` / `log_debug` / `log_error` helpers that were never defined in `scripts/lib/common.sh`, causing the script to exit 127 with empty stdout. The version-bump workflow then fell back to `patch` via `2>/dev/null || echo "patch"`, which is exactly what shipped v0.22.22 instead of the intended v1.0.0 for the breaking-change installer rewrite (PR #76). The analyzer now defines stderr-only logging helpers, and the workflow refuses to publish on analyzer failure or invalid output.
|
|
46
|
+
- **Conventional Commits `!` breaking-change marker is now recognised.** `feat!:`, `fix(scope)!:`, and `refactor(api)!:` correctly trigger a major bump in both the version analyzer and changelog categoriser. Previously only the long-form `BREAKING CHANGE:` footer was detected.
|
|
47
|
+
- **Scoped types are recognised everywhere.** `feat(auth):`, `fix(api):`, `chore(deps):`, etc. are now properly classified by `analyze-commits` and grouped correctly in `changelog.sh`.
|
|
50
48
|
- `install.sh` — `gh_args[@]: unbound variable` crash when invoking the github profile with no fork environment variables set (`set -u` + empty array). Guarded with `${gh_args[@]+"${gh_args[@]}"}`.
|
|
51
49
|
|
|
52
50
|
### Changed
|
|
53
51
|
|
|
52
|
+
- `scripts/utils/analyze-commits` now guarantees that **only** the bump type (`patch|minor|major|none`) is written to stdout. All progress and debug output is sent to stderr, so callers can safely use `BUMP=$(./analyze-commits ...)`.
|
|
53
|
+
- `.github/workflows/version-bump.yml` streams the analyzer's stderr into a collapsible job-log group and validates the returned bump type, failing the run with an annotated error if the analyzer crashes or returns garbage.
|
|
54
54
|
- `README.md` Installation Methods section now references the modular CLI alongside the legacy one-liner.
|
|
55
55
|
- `docs/FORKING.md` includes an `install init --profile fork` flow alongside the standalone `fork-cleanup.sh` script.
|
|
56
56
|
- `AGENTS.md` instruction map adds the new install instructions row.
|
|
57
57
|
|
|
58
|
+
## [0.22.22] - 2026-04-21
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
- Version bump: patch release
|
|
62
|
+
|
|
63
|
+
### Commits in this release
|
|
64
|
+
- 36cd015 feat(installer)!: modular installer + AI + deploy targets + test matrix (#76)
|
|
65
|
+
- 555bead docs(readme): add AI-native branding and GitHub Actions automation section
|
|
66
|
+
|
|
58
67
|
## [0.22.21] - 2026-04-19
|
|
59
68
|
|
|
60
69
|
### Changed
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: zer0-mistakes
|
|
3
3
|
sub-title: AI-Native Jekyll Theme
|
|
4
4
|
description: AI-native Jekyll theme for GitHub Pages — Docker-first development, AI-powered installation, multi-agent integration (Copilot, Codex, Cursor, Claude), AI preview-image generation, and AIEO content optimization with Bootstrap 5.3.
|
|
5
|
-
version: 0.
|
|
5
|
+
version: 1.0.0
|
|
6
6
|
layout: landing
|
|
7
7
|
tags:
|
|
8
8
|
- jekyll
|
|
@@ -1066,7 +1066,7 @@ git push origin feature/awesome-feature
|
|
|
1066
1066
|
|
|
1067
1067
|
| Metric | Value |
|
|
1068
1068
|
|--------|-------|
|
|
1069
|
-
| **Current Version** | 0.
|
|
1069
|
+
| **Current Version** | 1.0.0 ([RubyGems](https://rubygems.org/gems/jekyll-theme-zer0), [CHANGELOG](/CHANGELOG)) |
|
|
1070
1070
|
| **Documented Features** | 43 ([Feature Registry](https://github.com/bamr87/zer0-mistakes/blob/main/_data/features.yml)) |
|
|
1071
1071
|
| **Setup Time** | 2-5 minutes ([install.sh benchmarks](https://github.com/bamr87/zer0-mistakes/blob/main/install.sh)) |
|
|
1072
1072
|
| **Documentation Pages** | 70+ ([browse docs](/pages/)) |
|
|
@@ -1117,6 +1117,6 @@ And these AI partners that make zer0-mistakes truly AI-native:
|
|
|
1117
1117
|
|
|
1118
1118
|
**Built with ❤️ — and a little help from our AI partners — for the Jekyll community**
|
|
1119
1119
|
|
|
1120
|
-
**
|
|
1120
|
+
**v1.0.0** • [Changelog](CHANGELOG.md) • [License](LICENSE) • [Contributing](CONTRIBUTING.md) • [AI Agent Guide](AGENTS.md)
|
|
1121
1121
|
|
|
1122
1122
|
|
data/scripts/lib/changelog.sh
CHANGED
|
@@ -28,50 +28,57 @@ categorize_commit() {
|
|
|
28
28
|
local commit_full
|
|
29
29
|
commit_full=$(get_commit_message "$commit_hash")
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
# Conventional Commits "BREAKING CHANGE:" / "BREAKING:" footer
|
|
32
|
+
if echo "$commit_full" | grep -qiE "^BREAKING[ -]CHANGE:|^BREAKING:"; then
|
|
32
33
|
echo "breaking"
|
|
33
34
|
return 0
|
|
34
35
|
fi
|
|
35
36
|
|
|
36
|
-
# Conventional
|
|
37
|
+
# Conventional Commits "!" subject marker (e.g. feat!:, refactor(api)!:)
|
|
38
|
+
if echo "$subject" | grep -qE "^[a-zA-Z]+(\([^)]+\))?!:"; then
|
|
39
|
+
echo "breaking"
|
|
40
|
+
return 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Conventional commit patterns (allow optional scope)
|
|
37
44
|
case "$subject_lower" in
|
|
38
|
-
feat:*|feature:*|add:*|new
|
|
45
|
+
feat:*|feat\(*|feature:*|feature\(*|add:*|add\(*|new:*|new\(*)
|
|
39
46
|
echo "added"
|
|
40
47
|
;;
|
|
41
|
-
fix:*|bugfix:*|bug:*|patch
|
|
48
|
+
fix:*|fix\(*|bugfix:*|bugfix\(*|bug:*|bug\(*|patch:*|patch\(*)
|
|
42
49
|
echo "fixed"
|
|
43
50
|
;;
|
|
44
|
-
perf:*|performance
|
|
51
|
+
perf:*|perf\(*|performance:*|performance\(*)
|
|
45
52
|
echo "changed"
|
|
46
53
|
;;
|
|
47
|
-
refactor
|
|
54
|
+
refactor:*|refactor\(*)
|
|
48
55
|
echo "changed"
|
|
49
56
|
;;
|
|
50
|
-
style
|
|
57
|
+
style:*|style\(*)
|
|
51
58
|
echo "changed"
|
|
52
59
|
;;
|
|
53
|
-
docs:*|doc
|
|
60
|
+
docs:*|docs\(*|doc:*|doc\(*)
|
|
54
61
|
echo "changed"
|
|
55
62
|
;;
|
|
56
|
-
test
|
|
63
|
+
test:*|test\(*)
|
|
57
64
|
echo "changed"
|
|
58
65
|
;;
|
|
59
|
-
chore
|
|
66
|
+
chore:*|chore\(*)
|
|
60
67
|
echo "changed"
|
|
61
68
|
;;
|
|
62
|
-
ci
|
|
69
|
+
ci:*|ci\(*)
|
|
63
70
|
echo "changed"
|
|
64
71
|
;;
|
|
65
|
-
build
|
|
72
|
+
build:*|build\(*)
|
|
66
73
|
echo "changed"
|
|
67
74
|
;;
|
|
68
|
-
revert:*|remove:*|delete
|
|
75
|
+
revert:*|revert\(*|remove:*|remove\(*|delete:*|delete\(*)
|
|
69
76
|
echo "removed"
|
|
70
77
|
;;
|
|
71
|
-
deprecate:*|deprecated
|
|
78
|
+
deprecate:*|deprecate\(*|deprecated:*|deprecated\(*)
|
|
72
79
|
echo "deprecated"
|
|
73
80
|
;;
|
|
74
|
-
security:*|sec
|
|
81
|
+
security:*|security\(*|sec:*|sec\(*)
|
|
75
82
|
echo "security"
|
|
76
83
|
;;
|
|
77
84
|
*)
|
|
@@ -84,8 +91,8 @@ categorize_commit() {
|
|
|
84
91
|
clean_commit_message() {
|
|
85
92
|
local subject="$1"
|
|
86
93
|
|
|
87
|
-
# Remove conventional commit prefix
|
|
88
|
-
subject=$(echo "$subject" | sed -E 's/^(feat|feature|fix|bugfix|bug|patch|perf|performance|refactor|style|docs|doc|test|chore|ci|build|revert|remove|delete|deprecate|deprecated|security|sec)(\([^)]*\))
|
|
94
|
+
# Remove conventional commit prefix (with optional scope and ! breaking marker)
|
|
95
|
+
subject=$(echo "$subject" | sed -E 's/^(feat|feature|fix|bugfix|bug|patch|perf|performance|refactor|style|docs|doc|test|chore|ci|build|revert|remove|delete|deprecate|deprecated|security|sec)(\([^)]*\))?!?:[[:space:]]*//')
|
|
89
96
|
|
|
90
97
|
# Capitalize first letter
|
|
91
98
|
subject="$(echo "${subject:0:1}" | tr '[:lower:]' '[:upper:]')${subject:1}"
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Unit tests for scripts/utils/analyze-commits
|
|
4
|
+
#
|
|
5
|
+
# These tests build a throwaway git repo per case so we can verify that:
|
|
6
|
+
# 1. The analyzer never crashes on its own log calls (regression test for
|
|
7
|
+
# the silent log_info bug that caused a v1.0.0 release to be published
|
|
8
|
+
# as a patch in v0.22.22).
|
|
9
|
+
# 2. Conventional Commits "!" breaking-change marker triggers a major bump.
|
|
10
|
+
# 3. Scoped types like `feat(scope):` are still recognised.
|
|
11
|
+
# 4. The analyzer writes ONLY the bump type to stdout (logs go to stderr),
|
|
12
|
+
# so callers like the version-bump workflow can rely on
|
|
13
|
+
# `BUMP=$(./analyze-commits ...)`.
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
ANALYZER="$(cd "$SCRIPT_DIR/../../utils" && pwd)/analyze-commits"
|
|
17
|
+
|
|
18
|
+
set +e
|
|
19
|
+
|
|
20
|
+
print_suite_header "analyze-commits"
|
|
21
|
+
|
|
22
|
+
# Helper: run analyzer in an isolated git repo containing one commit with the
|
|
23
|
+
# given subject (and optional body). Echoes the bump type from stdout only.
|
|
24
|
+
_analyzer_for_commit() {
|
|
25
|
+
local subject="$1"
|
|
26
|
+
local body="${2:-}"
|
|
27
|
+
|
|
28
|
+
local tmp
|
|
29
|
+
tmp=$(mktemp -d)
|
|
30
|
+
(
|
|
31
|
+
cd "$tmp" || exit 1
|
|
32
|
+
git init -q -b main 2>/dev/null || git init -q
|
|
33
|
+
git config user.email "test@example.com"
|
|
34
|
+
git config user.name "Test"
|
|
35
|
+
git config commit.gpgsign false
|
|
36
|
+
echo "seed" > seed.txt
|
|
37
|
+
git add seed.txt
|
|
38
|
+
git commit -q -m "chore: seed"
|
|
39
|
+
echo "change" > change.txt
|
|
40
|
+
git add change.txt
|
|
41
|
+
if [[ -n "$body" ]]; then
|
|
42
|
+
git commit -q -m "$subject" -m "$body"
|
|
43
|
+
else
|
|
44
|
+
git commit -q -m "$subject"
|
|
45
|
+
fi
|
|
46
|
+
# Run analyzer; capture stdout only (stderr goes to caller for debugging on failure)
|
|
47
|
+
"$ANALYZER" HEAD~1..HEAD 2>/dev/null
|
|
48
|
+
)
|
|
49
|
+
local rc=$?
|
|
50
|
+
rm -rf "$tmp"
|
|
51
|
+
return $rc
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
_run_case() {
|
|
55
|
+
local subject="$1"
|
|
56
|
+
local expected="$2"
|
|
57
|
+
local body="${3:-}"
|
|
58
|
+
local label="$4"
|
|
59
|
+
|
|
60
|
+
local actual
|
|
61
|
+
actual=$(_analyzer_for_commit "$subject" "$body")
|
|
62
|
+
assert_equals "$expected" "$actual" "$label"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
echo "Testing conventional commit bump detection..."
|
|
66
|
+
|
|
67
|
+
_run_case "feat: add login" "minor" "" "feat: → minor"
|
|
68
|
+
_run_case "feat(auth): add login" "minor" "" "feat(scope): → minor"
|
|
69
|
+
_run_case "fix: handle null" "patch" "" "fix: → patch"
|
|
70
|
+
_run_case "fix(api): null guard" "patch" "" "fix(scope): → patch"
|
|
71
|
+
_run_case "chore: cleanup" "patch" "" "chore: → patch"
|
|
72
|
+
_run_case "docs(readme): typo" "patch" "" "docs(scope): → patch"
|
|
73
|
+
_run_case "ci(release): tweak" "patch" "" "ci(scope): → patch"
|
|
74
|
+
|
|
75
|
+
echo -e "\nTesting breaking-change detection..."
|
|
76
|
+
|
|
77
|
+
_run_case "feat!: drop legacy api" "major" "" "feat!: → major"
|
|
78
|
+
_run_case "feat(installer)!: modular rewrite" "major" "" "feat(scope)!: → major"
|
|
79
|
+
_run_case "refactor(api)!: rename endpoint" "major" "" "refactor(scope)!: → major"
|
|
80
|
+
_run_case "fix!: change return shape" "major" "" "fix!: → major"
|
|
81
|
+
_run_case "feat: redesign" "major" "BREAKING CHANGE: removes old config" "BREAKING CHANGE footer → major"
|
|
82
|
+
_run_case "feat: redesign" "major" "BREAKING-CHANGE: removes old config" "BREAKING-CHANGE footer → major"
|
|
83
|
+
|
|
84
|
+
echo -e "\nTesting stdout/stderr separation (regression for silent log_info bug)..."
|
|
85
|
+
|
|
86
|
+
# The whole point: with stderr discarded, stdout MUST be exactly one of
|
|
87
|
+
# patch|minor|major|none. If log helpers leak to stdout, this fails.
|
|
88
|
+
out=$(_analyzer_for_commit "feat: anything")
|
|
89
|
+
case "$out" in
|
|
90
|
+
patch|minor|major|none) assert_true "true" "stdout contains only the bump type" ;;
|
|
91
|
+
*) assert_true "false" "stdout contains only the bump type (got: '$out')" ;;
|
|
92
|
+
esac
|
|
93
|
+
|
|
94
|
+
# And with stderr captured we should also see log lines — proving they exist
|
|
95
|
+
# but go to the right stream.
|
|
96
|
+
tmp=$(mktemp -d)
|
|
97
|
+
(
|
|
98
|
+
cd "$tmp" || exit 1
|
|
99
|
+
git init -q -b main 2>/dev/null || git init -q
|
|
100
|
+
git config user.email "test@example.com"
|
|
101
|
+
git config user.name "Test"
|
|
102
|
+
git config commit.gpgsign false
|
|
103
|
+
echo seed > a; git add a; git commit -q -m "chore: seed"
|
|
104
|
+
echo x > b; git add b; git commit -q -m "feat: x"
|
|
105
|
+
"$ANALYZER" HEAD~1..HEAD 2>err.log >out.log
|
|
106
|
+
grep -qE "Analyzing|bump" err.log
|
|
107
|
+
) && assert_true "true" "Logs are written to stderr" \
|
|
108
|
+
|| assert_true "false" "Logs are written to stderr"
|
|
109
|
+
rm -rf "$tmp"
|
|
@@ -18,10 +18,17 @@ source "$LIB_DIR/common.sh"
|
|
|
18
18
|
COMMIT_RANGE="${1:-HEAD~1..HEAD}"
|
|
19
19
|
DEBUG=${DEBUG:-false}
|
|
20
20
|
|
|
21
|
-
#
|
|
21
|
+
# ----------------------------------------------------------------------------
|
|
22
|
+
# IMPORTANT: stdout is reserved for the bump-type result (patch|minor|major|none).
|
|
23
|
+
# All log output MUST go to stderr or it will be captured by callers like the
|
|
24
|
+
# version-bump workflow that uses `BUMP_TYPE=$(./analyze-commits ...)`.
|
|
25
|
+
# ----------------------------------------------------------------------------
|
|
26
|
+
log_info() { echo -e "${BLUE}[INFO]${NC} $*" >&2; }
|
|
27
|
+
log_warning() { echo -e "${YELLOW}[WARN]${NC} $*" >&2; }
|
|
28
|
+
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
|
|
22
29
|
log_debug() {
|
|
23
|
-
if [[ "$DEBUG" == "true" ]]; then
|
|
24
|
-
|
|
30
|
+
if [[ "$DEBUG" == "true" ]] || [[ "${VERBOSE:-false}" == "true" ]]; then
|
|
31
|
+
echo -e "${PURPLE}[DEBUG]${NC} $*" >&2
|
|
25
32
|
fi
|
|
26
33
|
}
|
|
27
34
|
|
|
@@ -38,14 +45,14 @@ analyze_commit() {
|
|
|
38
45
|
log_debug "Analyzing commit: $commit_hash"
|
|
39
46
|
log_debug "Message: $(echo "$commit_message" | head -1)"
|
|
40
47
|
|
|
41
|
-
# Check for breaking changes (MAJOR)
|
|
42
|
-
if echo "$commit_message" | grep -
|
|
48
|
+
# Check for breaking changes in body (MAJOR) — Conventional Commits spec
|
|
49
|
+
if echo "$commit_message" | grep -qiE "^BREAKING[ -]CHANGE:|^BREAKING:"; then
|
|
43
50
|
echo "major"
|
|
44
51
|
return 0
|
|
45
52
|
fi
|
|
46
53
|
|
|
47
54
|
# Check for major version indicators in commit message
|
|
48
|
-
if echo "$commit_message" | grep -qE "^(major|MAJOR|breaking|BREAKING)[
|
|
55
|
+
if echo "$commit_message" | grep -qE "^(major|MAJOR|breaking|BREAKING)[[:space:]:]"; then
|
|
49
56
|
echo "major"
|
|
50
57
|
return 0
|
|
51
58
|
fi
|
|
@@ -53,32 +60,39 @@ analyze_commit() {
|
|
|
53
60
|
# Check commit message patterns for conventional commits
|
|
54
61
|
local subject_line=$(echo "$commit_message" | head -1)
|
|
55
62
|
|
|
63
|
+
# Conventional Commits "!" breaking-change marker (MAJOR)
|
|
64
|
+
# Matches: feat!:, fix!:, feat(scope)!:, refactor(api)!:, etc.
|
|
65
|
+
if echo "$subject_line" | grep -qE "^[a-zA-Z]+(\([^)]+\))?!:"; then
|
|
66
|
+
echo "major"
|
|
67
|
+
return 0
|
|
68
|
+
fi
|
|
69
|
+
|
|
56
70
|
# MAJOR changes
|
|
57
|
-
if echo "$subject_line" | grep -qE "^(revert|remove|delete)[
|
|
71
|
+
if echo "$subject_line" | grep -qE "^(revert|remove|delete)(\([^)]+\))?:.*[Bb]reaking"; then
|
|
58
72
|
echo "major"
|
|
59
73
|
return 0
|
|
60
74
|
fi
|
|
61
75
|
|
|
62
|
-
# MINOR changes (new features)
|
|
63
|
-
if echo "$subject_line" | grep -qE "^(feat|feature|add|new)[
|
|
76
|
+
# MINOR changes (new features) — supports optional scope, e.g. feat(api):
|
|
77
|
+
if echo "$subject_line" | grep -qE "^(feat|feature|add|new)(\([^)]+\))?:"; then
|
|
64
78
|
echo "minor"
|
|
65
79
|
return 0
|
|
66
80
|
fi
|
|
67
81
|
|
|
68
82
|
# MINOR changes - significant additions
|
|
69
|
-
if echo "$subject_line" | grep -
|
|
83
|
+
if echo "$subject_line" | grep -qiE "^(enhance|improve|update)(\([^)]+\))?:.*feature"; then
|
|
70
84
|
echo "minor"
|
|
71
85
|
return 0
|
|
72
86
|
fi
|
|
73
87
|
|
|
74
|
-
# PATCH changes (bug fixes, small improvements)
|
|
75
|
-
if echo "$subject_line" | grep -qE "^(fix|bug|patch|hotfix|chore|docs|style|refactor|test|perf)[
|
|
88
|
+
# PATCH changes (bug fixes, small improvements) — supports optional scope
|
|
89
|
+
if echo "$subject_line" | grep -qE "^(fix|bug|patch|hotfix|chore|docs|style|refactor|test|perf|ci|build)(\([^)]+\))?:"; then
|
|
76
90
|
echo "patch"
|
|
77
91
|
return 0
|
|
78
92
|
fi
|
|
79
93
|
|
|
80
94
|
# PATCH changes - maintenance and small improvements
|
|
81
|
-
if echo "$subject_line" | grep -qE "^(update|improve|enhance|optimize|clean)[
|
|
95
|
+
if echo "$subject_line" | grep -qE "^(update|improve|enhance|optimize|clean)(\([^)]+\))?:"; then
|
|
82
96
|
echo "patch"
|
|
83
97
|
return 0
|
|
84
98
|
fi
|
|
@@ -288,10 +302,16 @@ ENVIRONMENT:
|
|
|
288
302
|
DEBUG=true # Enable debug output
|
|
289
303
|
|
|
290
304
|
CONVENTIONAL COMMIT PATTERNS:
|
|
291
|
-
feat:, feature:, add:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
305
|
+
feat:, feature:, add: → minor
|
|
306
|
+
feat(scope): → minor
|
|
307
|
+
fix:, bug:, patch: → patch
|
|
308
|
+
feat!:, fix!:, refactor(api)!: → major (Conventional Commits "!" marker)
|
|
309
|
+
BREAKING CHANGE:, BREAKING: → major (commit body footer)
|
|
310
|
+
chore:, docs:, style:, ci: → patch
|
|
311
|
+
|
|
312
|
+
OUTPUT CONTRACT:
|
|
313
|
+
Only the bump type is written to stdout. All progress/log output goes to
|
|
314
|
+
stderr so callers can safely use \`BUMP=\$(./analyze-commits ...)\`.
|
|
295
315
|
EOF
|
|
296
316
|
exit 0
|
|
297
317
|
fi
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-theme-zer0
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Amr Abdel
|
|
@@ -421,6 +421,7 @@ files:
|
|
|
421
421
|
- scripts/test/integration/auto-version
|
|
422
422
|
- scripts/test/integration/mermaid
|
|
423
423
|
- scripts/test/lib/run_tests.sh
|
|
424
|
+
- scripts/test/lib/test_analyze_commits.sh
|
|
424
425
|
- scripts/test/lib/test_changelog.sh
|
|
425
426
|
- scripts/test/lib/test_gem.sh
|
|
426
427
|
- scripts/test/lib/test_git.sh
|