jekyll-theme-zer0 0.22.22 → 1.1.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 +58 -16
- data/README.md +4 -4
- data/_data/prompts.yml +274 -156
- data/_includes/content/intro.html +6 -0
- data/scripts/lib/changelog.sh +25 -18
- data/scripts/lib/migrate.sh +7 -7
- data/scripts/test/lib/run_tests.sh +1 -0
- data/scripts/test/lib/test_analyze_commits.sh +129 -0
- data/scripts/utils/analyze-commits +43 -23
- 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: 61d06e485b7f208505ec171ac1d0f9b074124eb972085aaccb7a48957fe4a309
|
|
4
|
+
data.tar.gz: 8d725ba937bb2cac46d4f30d132380f6bdd24616f7e08f851bf0b8f3b3aa5383
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a4f72a346e3e8e1bad8affd72e8378d20669b5c937c187cbf1434c394a824ccdb2c303adf2cabd6734b24dac30216d294bb0047754d1c536c56e713ce5930287
|
|
7
|
+
data.tar.gz: b447257158432ebd4a5c6595af8cb842ac8b420b9624f66ebfc80e5cdc395c0b3074145051babd683675c78dcf00bd911ebb4e93522d19df6c9ab202ca1dcbe5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [
|
|
3
|
+
## [1.1.0] - 2026-04-21
|
|
4
4
|
|
|
5
5
|
### Changed
|
|
6
|
-
- Version bump:
|
|
6
|
+
- Version bump: minor release
|
|
7
7
|
|
|
8
8
|
### Commits in this release
|
|
9
|
-
-
|
|
10
|
-
-
|
|
9
|
+
- 3d91006 fix(release): replace ((var++)) with var=$((var + 1)) in release path
|
|
10
|
+
- d33e5e6 feat(intro): refocus Copilot Agent prompts on frontend/CMS workflows (#74)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## [Unreleased]
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **Version-bump workflow no longer crashes on bash 5.x runners.** `scripts/utils/analyze-commits` (and `scripts/lib/changelog.sh`, `scripts/lib/migrate.sh`) used the `((var++))` post-increment idiom. On bash 5.x, when `var` is 0 the expression evaluates to 0 → exit code 1 → `set -euo pipefail` terminates the script silently. macOS bash 3.2 was more forgiving, so the bug only surfaced in CI. Replaced all release-path sites with `var=$((var + 1))`, which always returns 0. Added a static regression check to the unit tests so the pattern can't return.
|
|
11
17
|
|
|
18
|
+
## [1.0.0] - 2026-04-20
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
First stable major release. Consolidates the breaking-change installer rewrite
|
|
21
|
+
(shipped in error as v0.22.22 due to a silent bug in the version analyzer) and
|
|
22
|
+
the fix that restored the release automation.
|
|
14
23
|
|
|
15
|
-
### ⚠️ Breaking changes
|
|
24
|
+
### ⚠️ Breaking changes
|
|
16
25
|
|
|
17
26
|
- **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
27
|
- **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 +30,9 @@
|
|
|
21
30
|
|
|
22
31
|
See [`docs/installation/migration-from-0.x.md`](docs/installation/migration-from-0.x.md) for the full flag-by-flag mapping.
|
|
23
32
|
|
|
24
|
-
### Added
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
#### Modular installer (Phases 1-7 of the refactor)
|
|
25
36
|
|
|
26
37
|
- **`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
38
|
- **`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 +45,40 @@ See [`docs/installation/migration-from-0.x.md`](docs/installation/migration-from
|
|
|
34
45
|
- **`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
46
|
- **`install upgrade`** — idempotent in-place upgrade tracked via `.zer0-installed`. `--from`, `--force`, `--dry-run`, `--auto-accept`. Refreshes agents and checks deploy-workflow drift.
|
|
36
47
|
- **`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
|
|
48
|
+
- **`.github/instructions/install.instructions.md`** — agent guidance for installer code.
|
|
38
49
|
- **`.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.
|
|
50
|
+
- **`.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.
|
|
51
|
+
- **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`.
|
|
52
|
+
- **`scripts/bin/test install`** — new test-suite group that executes all installer e2e tests.
|
|
53
|
+
|
|
54
|
+
#### Versioning & release automation (new in 1.0.0)
|
|
55
|
+
|
|
56
|
+
- 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
57
|
|
|
48
58
|
### Fixed
|
|
49
59
|
|
|
60
|
+
- **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.
|
|
61
|
+
- **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.
|
|
62
|
+
- **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
63
|
- `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
64
|
|
|
52
65
|
### Changed
|
|
53
66
|
|
|
67
|
+
- `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 ...)`.
|
|
68
|
+
- `.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
69
|
- `README.md` Installation Methods section now references the modular CLI alongside the legacy one-liner.
|
|
55
70
|
- `docs/FORKING.md` includes an `install init --profile fork` flow alongside the standalone `fork-cleanup.sh` script.
|
|
56
71
|
- `AGENTS.md` instruction map adds the new install instructions row.
|
|
57
72
|
|
|
73
|
+
## [0.22.22] - 2026-04-21
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
- Version bump: patch release
|
|
77
|
+
|
|
78
|
+
### Commits in this release
|
|
79
|
+
- 36cd015 feat(installer)!: modular installer + AI + deploy targets + test matrix (#76)
|
|
80
|
+
- 555bead docs(readme): add AI-native branding and GitHub Actions automation section
|
|
81
|
+
|
|
58
82
|
## [0.22.21] - 2026-04-19
|
|
59
83
|
|
|
60
84
|
### Changed
|
|
@@ -66,6 +90,24 @@ See [`docs/installation/migration-from-0.x.md`](docs/installation/migration-from
|
|
|
66
90
|
|
|
67
91
|
## [Unreleased]
|
|
68
92
|
|
|
93
|
+
### Changed
|
|
94
|
+
- **Copilot Agent prompts (`_data/prompts.yml`)**: rewritten to focus on
|
|
95
|
+
frontend/CMS workflows for the Jekyll theme. Replaced the previous
|
|
96
|
+
general-purpose software-engineering templates with 10 prompts split into
|
|
97
|
+
two scopes: **Page Improvements** (`improve-page`, `expand-page`,
|
|
98
|
+
`update-page`, `fix-page`, `seo-optimize`, `accessibility-audit`) that act
|
|
99
|
+
on the current page, and **Site Improvements** (`ui-ux-improvement`,
|
|
100
|
+
`new-feature`, `component-enhancement`, `performance-optimization`) for
|
|
101
|
+
theme-wide changes. Every prompt explicitly references the auto-injected
|
|
102
|
+
Page Context table.
|
|
103
|
+
- **Intro component (`_includes/content/intro.html`)**: the Copilot Agent
|
|
104
|
+
dropdown now renders Bootstrap `dropdown-header` section labels and
|
|
105
|
+
dividers when prompt entries declare a `group`. Entries without a
|
|
106
|
+
`group` continue to render as plain items (backward compatible).
|
|
107
|
+
- **Docs (`docs/implementation/copilot-agent-prompt-button.md`)**: updated
|
|
108
|
+
the prompt registry table and YAML schema to document the new `group`
|
|
109
|
+
field and the new template set.
|
|
110
|
+
|
|
69
111
|
### Added
|
|
70
112
|
- **Roadmap data file**: `_data/roadmap.yml` is now the single source of truth for the project roadmap (versions, status, dates, targets, and feature highlights).
|
|
71
113
|
- **Roadmap generator**: `scripts/generate-roadmap.rb` (and shell wrapper `scripts/generate-roadmap.sh`) renders a Mermaid gantt diagram and summary table from `_data/roadmap.yml` and injects them into `README.md` between `<!-- ROADMAP_MERMAID:START/END -->` and `<!-- ROADMAP_TABLE:START/END -->` markers. Supports `--check` mode for CI drift detection and `--stdout` for previewing.
|
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:
|
|
5
|
+
version: 1.1.0
|
|
6
6
|
layout: landing
|
|
7
7
|
tags:
|
|
8
8
|
- jekyll
|
|
@@ -20,7 +20,7 @@ categories:
|
|
|
20
20
|
- bootstrap
|
|
21
21
|
- ai-tooling
|
|
22
22
|
created: 2024-02-10T23:51:11.480Z
|
|
23
|
-
lastmod: 2026-04-
|
|
23
|
+
lastmod: 2026-04-21T05:41:17.000Z
|
|
24
24
|
draft: false
|
|
25
25
|
permalink: /
|
|
26
26
|
slug: zer0
|
|
@@ -1066,7 +1066,7 @@ git push origin feature/awesome-feature
|
|
|
1066
1066
|
|
|
1067
1067
|
| Metric | Value |
|
|
1068
1068
|
|--------|-------|
|
|
1069
|
-
| **Current Version** |
|
|
1069
|
+
| **Current Version** | 1.1.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.1.0** • [Changelog](CHANGELOG.md) • [License](LICENSE) • [Contributing](CONTRIBUTING.md) • [AI Agent Guide](AGENTS.md)
|
|
1121
1121
|
|
|
1122
1122
|
|
data/_data/prompts.yml
CHANGED
|
@@ -1,184 +1,302 @@
|
|
|
1
1
|
# _data/prompts.yml
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
#
|
|
3
|
+
# Prompt templates for the Copilot Agent issue button rendered by
|
|
4
|
+
# `_includes/content/intro.html`. Each entry becomes a dropdown item that
|
|
5
|
+
# opens a pre-filled GitHub issue assigned to @copilot.
|
|
6
|
+
#
|
|
7
|
+
# These templates are tuned for a Jekyll/CMS theme (zer0-mistakes) and focus
|
|
8
|
+
# on FRONTEND and CONTENT (CMS) improvements. Two scopes are supported via
|
|
9
|
+
# the `group` field:
|
|
10
|
+
#
|
|
11
|
+
# - "Page Improvements" – act on the page the button was clicked from.
|
|
12
|
+
# The Page Context table injected by intro.html (title, URL, file path,
|
|
13
|
+
# layout, collection, tags, etc.) is what every prompt should reference.
|
|
14
|
+
#
|
|
15
|
+
# - "Site Improvements" – act on theme-wide UI/UX, components, layouts,
|
|
16
|
+
# navigation, performance, or new features. The page is included as the
|
|
17
|
+
# example/entry point, not necessarily the only target.
|
|
18
|
+
#
|
|
19
|
+
# Schema:
|
|
20
|
+
# - id: unique slug
|
|
21
|
+
# label: short text shown in the dropdown
|
|
22
|
+
# icon: Bootstrap Icons class (https://icons.getbootstrap.com/)
|
|
23
|
+
# group: optional section header in the dropdown
|
|
24
|
+
# description: optional one-line subtitle under the label
|
|
25
|
+
# body: prompt instructions appended above the auto-generated
|
|
26
|
+
# Page Context + Environment tables in the issue body.
|
|
27
|
+
|
|
28
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
29
|
+
# Page Improvements — scoped to the current page
|
|
30
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
- id: improve-page
|
|
33
|
+
label: "Improve Page"
|
|
34
|
+
icon: "bi-stars"
|
|
35
|
+
group: "Page Improvements"
|
|
36
|
+
description: "Polish content, structure, and presentation of this page"
|
|
10
37
|
body: |
|
|
11
|
-
Act as
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
38
|
+
Act as a Senior Content Editor and Frontend Designer for the
|
|
39
|
+
zer0-mistakes Jekyll theme.
|
|
40
|
+
|
|
41
|
+
Improve the page referenced in the **Page Context** table below. Make it
|
|
42
|
+
clearer, more engaging, and visually consistent with the rest of the
|
|
43
|
+
site — without changing its core message or breaking existing links.
|
|
44
|
+
|
|
45
|
+
**Scope (this page only):**
|
|
46
|
+
- Tighten copy: remove fluff, fix grammar, improve readability
|
|
47
|
+
- Strengthen the opening hook and the closing call-to-action
|
|
48
|
+
- Verify heading hierarchy (single H1, logical H2/H3 nesting)
|
|
49
|
+
- Confirm front matter is complete: `title`, `description`, `date`,
|
|
50
|
+
`lastmod`, `layout`, `categories`, `tags`, `permalink`, `preview`
|
|
51
|
+
- Improve visual rhythm: paragraph length, lists, callouts, code blocks
|
|
52
|
+
- Validate internal links and image paths (use `relative_url`)
|
|
53
|
+
- Ensure Bootstrap 5 utility classes are used over custom CSS
|
|
22
54
|
|
|
23
55
|
**Deliverables:**
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
- id:
|
|
29
|
-
label: "
|
|
30
|
-
icon: "bi-
|
|
31
|
-
|
|
56
|
+
- A diff-style proposal of the edited Markdown (front matter + body)
|
|
57
|
+
- A short "Why these changes" rationale (3–5 bullets)
|
|
58
|
+
- A checklist of any follow-up items that are out of scope
|
|
59
|
+
|
|
60
|
+
- id: expand-page
|
|
61
|
+
label: "Expand Page"
|
|
62
|
+
icon: "bi-arrows-angle-expand"
|
|
63
|
+
group: "Page Improvements"
|
|
64
|
+
description: "Add depth, examples, and missing sections to this page"
|
|
32
65
|
body: |
|
|
33
|
-
Act as a
|
|
66
|
+
Act as a Subject Matter Expert and Technical Writer.
|
|
34
67
|
|
|
35
|
-
|
|
68
|
+
Expand the page referenced in the **Page Context** table below by adding
|
|
69
|
+
depth, real examples, and any sections that a reader would reasonably
|
|
70
|
+
expect but are currently missing.
|
|
36
71
|
|
|
37
|
-
**
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- Add
|
|
41
|
-
-
|
|
42
|
-
-
|
|
72
|
+
**Expansion targets:**
|
|
73
|
+
- Add concrete, copy-pasteable examples (code, configs, screenshots)
|
|
74
|
+
- Add a "Prerequisites" and "Next steps" / "Related" section
|
|
75
|
+
- Add a short FAQ or troubleshooting block when relevant
|
|
76
|
+
- Cross-link to related posts, docs, or theme components in this repo
|
|
77
|
+
- Add or update Mermaid diagrams where they clarify flow/architecture
|
|
78
|
+
- Keep the existing tone, structure, and front matter intact
|
|
43
79
|
|
|
44
80
|
**Deliverables:**
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
description: "
|
|
81
|
+
- The new/expanded Markdown sections, ready to merge into the page
|
|
82
|
+
- A list of any new assets needed (images, diagrams, data files)
|
|
83
|
+
- Suggested updates to `tags`, `categories`, and `description`
|
|
84
|
+
|
|
85
|
+
- id: update-page
|
|
86
|
+
label: "Update Page"
|
|
87
|
+
icon: "bi-arrow-clockwise"
|
|
88
|
+
group: "Page Improvements"
|
|
89
|
+
description: "Refresh outdated content, versions, links, and screenshots"
|
|
54
90
|
body: |
|
|
55
|
-
Act as a
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
-
|
|
91
|
+
Act as a Documentation Maintainer responsible for keeping the
|
|
92
|
+
zer0-mistakes site accurate and current.
|
|
93
|
+
|
|
94
|
+
Audit and update the page referenced in the **Page Context** table below.
|
|
95
|
+
Treat any version numbers, dates, screenshots, or external references as
|
|
96
|
+
suspect and verify them against the current state of the repository and
|
|
97
|
+
the wider ecosystem.
|
|
98
|
+
|
|
99
|
+
**Update checklist:**
|
|
100
|
+
- Bump version numbers, release names, and dependency references
|
|
101
|
+
- Replace deprecated Jekyll/Bootstrap patterns with current equivalents
|
|
102
|
+
- Refresh screenshots, GIFs, and embedded examples
|
|
103
|
+
- Re-validate every external link; replace dead or moved URLs
|
|
104
|
+
- Update `lastmod` in the front matter and add a brief "Updated" note
|
|
105
|
+
- Reconcile content with related files in this repo (configs, layouts,
|
|
106
|
+
includes) so instructions match what the codebase actually does
|
|
65
107
|
|
|
66
108
|
**Deliverables:**
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
- Any
|
|
109
|
+
- Updated Markdown for the page (front matter + body)
|
|
110
|
+
- A short changelog summarising what was refreshed and why
|
|
111
|
+
- Any follow-up issues to file for changes outside this page
|
|
70
112
|
|
|
71
|
-
- id:
|
|
72
|
-
label: "
|
|
113
|
+
- id: fix-page
|
|
114
|
+
label: "Fix Page Issue"
|
|
73
115
|
icon: "bi-bug"
|
|
74
|
-
|
|
116
|
+
group: "Page Improvements"
|
|
117
|
+
description: "Report a typo, broken link, layout glitch, or content bug"
|
|
75
118
|
body: |
|
|
76
|
-
Act as a
|
|
119
|
+
Act as a Frontend QA Engineer for the zer0-mistakes Jekyll theme.
|
|
77
120
|
|
|
78
|
-
|
|
121
|
+
Investigate and fix the issue described below on the page referenced in
|
|
122
|
+
the **Page Context** table. Reproduce it locally with `docker-compose up`
|
|
123
|
+
before proposing a change.
|
|
79
124
|
|
|
80
|
-
**Please
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
125
|
+
**Please describe (fill in before submitting):**
|
|
126
|
+
- **What is wrong?** <!-- typo, broken link, image, layout, behaviour -->
|
|
127
|
+
- **Where on the page?** <!-- section heading, line, screenshot region -->
|
|
128
|
+
- **Expected:** <!-- what should appear / happen -->
|
|
129
|
+
- **Actual:** <!-- what currently appears / happens -->
|
|
130
|
+
- **Browser / device (if visual):** <!-- e.g. Chrome 124 desktop, iOS Safari -->
|
|
85
131
|
|
|
86
|
-
**
|
|
132
|
+
**Deliverables:**
|
|
133
|
+
- Root-cause analysis (content vs. layout vs. include vs. config)
|
|
134
|
+
- Minimal, surgical fix (Markdown, Liquid, SCSS, or front matter)
|
|
135
|
+
- Verification steps and a passing `bundle exec jekyll build`
|
|
136
|
+
|
|
137
|
+
- id: seo-optimize
|
|
138
|
+
label: "SEO Optimize"
|
|
139
|
+
icon: "bi-graph-up-arrow"
|
|
140
|
+
group: "Page Improvements"
|
|
141
|
+
description: "Improve discoverability, metadata, and structured data"
|
|
142
|
+
body: |
|
|
143
|
+
Act as a Technical SEO Specialist.
|
|
87
144
|
|
|
88
|
-
|
|
145
|
+
Optimise the page referenced in the **Page Context** table below for
|
|
146
|
+
search engines and social sharing, without sacrificing readability.
|
|
89
147
|
|
|
90
|
-
**
|
|
148
|
+
**Audit and improve:**
|
|
149
|
+
- Front matter `title` (≤ 60 chars) and `description` (150–160 chars)
|
|
150
|
+
- Primary keyword in H1, first paragraph, and at least one H2
|
|
151
|
+
- `permalink` is short, lowercase, and hyphen-separated
|
|
152
|
+
- `tags` and `categories` align with site taxonomy
|
|
153
|
+
- `preview` image exists, has descriptive alt text, and good aspect ratio
|
|
154
|
+
- Open Graph + Twitter Card metadata via existing includes
|
|
155
|
+
- JSON-LD structured data (Article / BlogPosting) where applicable
|
|
156
|
+
- Internal links to high-value related pages, with descriptive anchors
|
|
91
157
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
158
|
+
**Deliverables:**
|
|
159
|
+
- Updated front matter
|
|
160
|
+
- Specific in-body edits (H1/H2/intro)
|
|
161
|
+
- A keyword/intent map (primary + 3–5 secondary)
|
|
162
|
+
- Any sitemap, robots, or `_config.yml` changes required
|
|
163
|
+
|
|
164
|
+
- id: accessibility-audit
|
|
165
|
+
label: "Accessibility Audit"
|
|
166
|
+
icon: "bi-universal-access"
|
|
167
|
+
group: "Page Improvements"
|
|
168
|
+
description: "Audit this page for WCAG 2.1 AA compliance"
|
|
96
169
|
body: |
|
|
97
|
-
Act as
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
170
|
+
Act as an Accessibility (a11y) Engineer.
|
|
171
|
+
|
|
172
|
+
Audit the page referenced in the **Page Context** table below against
|
|
173
|
+
WCAG 2.1 AA and propose concrete fixes in Markdown, Liquid, or SCSS.
|
|
174
|
+
|
|
175
|
+
**Audit areas:**
|
|
176
|
+
- Semantic HTML and heading order
|
|
177
|
+
- Alt text on every meaningful image; empty alt on decorative ones
|
|
178
|
+
- Sufficient colour contrast (≥ 4.5:1 body, ≥ 3:1 large text/UI)
|
|
179
|
+
- Keyboard navigability and visible focus states
|
|
180
|
+
- ARIA attributes on Bootstrap components (modals, dropdowns, tabs)
|
|
181
|
+
- Form labels, error messages, and `aria-describedby` associations
|
|
182
|
+
- Skip links and landmark regions (`<main>`, `<nav>`, `<aside>`)
|
|
183
|
+
- Reduced-motion and prefers-color-scheme respect
|
|
184
|
+
|
|
185
|
+
**Deliverables:**
|
|
186
|
+
- Findings table: issue, WCAG criterion, severity, fix
|
|
187
|
+
- Patches for the page and any shared includes that need updating
|
|
188
|
+
- A re-test plan (axe-core, Lighthouse, manual keyboard pass)
|
|
189
|
+
|
|
190
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
191
|
+
# Site Improvements — theme-wide UI/UX, components, and features
|
|
192
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
193
|
+
|
|
194
|
+
- id: ui-ux-improvement
|
|
195
|
+
label: "UI/UX Improvement"
|
|
196
|
+
icon: "bi-palette"
|
|
197
|
+
group: "Site Improvements"
|
|
198
|
+
description: "Propose a design or UX refinement for the theme"
|
|
118
199
|
body: |
|
|
119
|
-
Act as
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
|
|
131
|
-
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
200
|
+
Act as a Senior UI/UX Designer working in Bootstrap 5 and Jekyll.
|
|
201
|
+
|
|
202
|
+
Propose a UI/UX improvement for the zer0-mistakes theme. Use the page
|
|
203
|
+
referenced in the **Page Context** table below as the starting example;
|
|
204
|
+
where the change applies site-wide, call that out explicitly.
|
|
205
|
+
|
|
206
|
+
**Cover in your proposal:**
|
|
207
|
+
- **Problem / opportunity** — what user pain or quality gap exists?
|
|
208
|
+
- **Affected surfaces** — layouts, includes, components, or data files
|
|
209
|
+
- **Design direction** — spacing, typography, colour, motion, hierarchy
|
|
210
|
+
- **Bootstrap-first approach** — utilities and components over custom CSS
|
|
211
|
+
- **Responsive behaviour** — xs / sm / md / lg / xl / xxl breakpoints
|
|
212
|
+
- **Accessibility** — contrast, focus, ARIA, reduced-motion
|
|
213
|
+
- **Dark mode / colour scheme** considerations
|
|
214
|
+
- **Before/after sketch or description** of the change
|
|
215
|
+
|
|
216
|
+
**Deliverables:**
|
|
217
|
+
- A concrete change list mapped to files in `_layouts/`, `_includes/`,
|
|
218
|
+
`_sass/`, and `assets/`
|
|
219
|
+
- SCSS / Liquid / HTML snippets ready to drop in
|
|
220
|
+
- A short test plan covering desktop + mobile + keyboard
|
|
221
|
+
|
|
222
|
+
- id: new-feature
|
|
223
|
+
label: "New Feature"
|
|
224
|
+
icon: "bi-lightbulb"
|
|
225
|
+
group: "Site Improvements"
|
|
226
|
+
description: "Propose a new site-wide feature or capability"
|
|
135
227
|
body: |
|
|
136
|
-
Act as a
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
**
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
-
|
|
147
|
-
|
|
148
|
-
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
228
|
+
Act as a Product Manager + Frontend Engineer for the zer0-mistakes
|
|
229
|
+
Jekyll theme.
|
|
230
|
+
|
|
231
|
+
Propose a new feature for the site or theme. Use the page referenced in
|
|
232
|
+
the **Page Context** table below as the inspiration / first consumer of
|
|
233
|
+
the feature where it makes sense.
|
|
234
|
+
|
|
235
|
+
**Please describe:**
|
|
236
|
+
- **User story** — As a [reader / author / theme adopter], I want…
|
|
237
|
+
- **Problem solved** and the success metric
|
|
238
|
+
- **Scope** — pages, layouts, includes, data files, configs touched
|
|
239
|
+
- **Configuration** — what goes into `_config.yml` / `_data/*.yml`?
|
|
240
|
+
- **Dependencies** — any new gems, JS libs, or vendor assets?
|
|
241
|
+
- **Privacy / analytics** — does it need consent gating?
|
|
242
|
+
- **Rollout plan** — feature flag, opt-in via front matter, default-on?
|
|
243
|
+
- **Out of scope** items
|
|
244
|
+
|
|
245
|
+
**Deliverables:**
|
|
246
|
+
- A minimal, working implementation plan (file-by-file)
|
|
247
|
+
- Sample Liquid / HTML / SCSS / JS scaffolding
|
|
248
|
+
- Documentation stub for `docs/` or `pages/_docs/`
|
|
249
|
+
- CHANGELOG entry following Keep a Changelog format
|
|
250
|
+
|
|
251
|
+
- id: component-enhancement
|
|
252
|
+
label: "Component Enhancement"
|
|
253
|
+
icon: "bi-puzzle"
|
|
254
|
+
group: "Site Improvements"
|
|
255
|
+
description: "Improve a Jekyll layout, include, or shared component"
|
|
152
256
|
body: |
|
|
153
|
-
Act as a
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
257
|
+
Act as a Senior Jekyll Theme Developer.
|
|
258
|
+
|
|
259
|
+
Enhance a shared component used by the page referenced in the
|
|
260
|
+
**Page Context** table below — a layout in `_layouts/`, an include in
|
|
261
|
+
`_includes/`, or a partial in `_sass/`. Improvements should benefit every
|
|
262
|
+
page that uses the component, not just this one.
|
|
263
|
+
|
|
264
|
+
**Targets to consider:**
|
|
265
|
+
- Cleaner Liquid: safe `default:` filters, fewer nested `if`s
|
|
266
|
+
- Parameterise hard-coded values via `include.*` arguments
|
|
267
|
+
- Consistent BEM-style class names and Bootstrap utility usage
|
|
268
|
+
- Add the standard component header comment block
|
|
269
|
+
- Improve mobile responsiveness and accessibility
|
|
270
|
+
- Document parameters and usage in the file header
|
|
271
|
+
|
|
272
|
+
**Deliverables:**
|
|
273
|
+
- The enhanced file(s), preserving backward compatibility
|
|
274
|
+
- A migration note if any include parameters changed
|
|
275
|
+
- Before/after rendering notes for at least one page that uses it
|
|
276
|
+
- A test plan: `docker-compose exec jekyll bundle exec jekyll build`
|
|
277
|
+
|
|
278
|
+
- id: performance-optimization
|
|
279
|
+
label: "Performance Optimization"
|
|
280
|
+
icon: "bi-speedometer2"
|
|
281
|
+
group: "Site Improvements"
|
|
282
|
+
description: "Improve load time, Core Web Vitals, and asset delivery"
|
|
173
283
|
body: |
|
|
174
|
-
Act as
|
|
284
|
+
Act as a Web Performance Engineer.
|
|
175
285
|
|
|
176
|
-
|
|
286
|
+
Profile and optimise the site, using the page referenced in the
|
|
287
|
+
**Page Context** table below as a representative measurement target.
|
|
177
288
|
|
|
178
|
-
**
|
|
179
|
-
-
|
|
180
|
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
289
|
+
**Investigate:**
|
|
290
|
+
- Core Web Vitals: LCP (Largest Contentful Paint), CLS (Cumulative
|
|
291
|
+
Layout Shift), and INP (Interaction to Next Paint) for this page
|
|
292
|
+
- Render-blocking CSS/JS in `_includes/core/head.html` and `js-cdn.html`
|
|
293
|
+
- Vendored Bootstrap and Bootstrap Icons under `assets/vendor/`
|
|
294
|
+
- Image strategy: dimensions, `loading="lazy"`, modern formats
|
|
295
|
+
- Liquid hot spots: nested loops, repeated `where` filters
|
|
296
|
+
- Build output size in `_site/` and unused CSS
|
|
297
|
+
|
|
298
|
+
**Deliverables:**
|
|
299
|
+
- Lighthouse / WebPageTest results before and after
|
|
300
|
+
- Specific patches to layouts, includes, SCSS, and config
|
|
301
|
+
- Any new build steps or scripts (must be opt-in, GitHub Pages-safe)
|
|
302
|
+
- A short report on tradeoffs and follow-ups
|
|
@@ -96,7 +96,13 @@
|
|
|
96
96
|
<span class="d-none d-sm-inline ms-1">Copilot Agent</span>
|
|
97
97
|
</button>
|
|
98
98
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="copilotAgentDropdown">
|
|
99
|
+
{% assign current_group = "" %}
|
|
99
100
|
{% for prompt in site.data.prompts %}
|
|
101
|
+
{% if prompt.group and prompt.group != current_group %}
|
|
102
|
+
{% unless forloop.first %}<li><hr class="dropdown-divider"></li>{% endunless %}
|
|
103
|
+
<li><h6 class="dropdown-header">{{ prompt.group }}</h6></li>
|
|
104
|
+
{% assign current_group = prompt.group %}
|
|
105
|
+
{% endif %}
|
|
100
106
|
{% capture issue_title %}[{{ prompt.label }}] {{ page.title }}{% endcapture %}
|
|
101
107
|
{% capture issue_body %}{{ prompt.body }}
|
|
102
108
|
---
|
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}"
|
|
@@ -130,7 +137,7 @@ generate_changelog() {
|
|
|
130
137
|
while IFS='|' read -r hash subject author date; do
|
|
131
138
|
[[ -z "$hash" ]] && continue
|
|
132
139
|
|
|
133
|
-
((commit_count
|
|
140
|
+
commit_count=$((commit_count + 1))
|
|
134
141
|
|
|
135
142
|
# Skip merge commits
|
|
136
143
|
if echo "$subject" | grep -qE "^Merge (branch|pull request|remote-tracking branch)"; then
|
data/scripts/lib/migrate.sh
CHANGED
|
@@ -146,18 +146,18 @@ install_admin_pages() {
|
|
|
146
146
|
|
|
147
147
|
if [[ ! -f "$template_file" ]]; then
|
|
148
148
|
warn "Template not found: $template_file — skipping"
|
|
149
|
-
((skipped
|
|
149
|
+
skipped=$((skipped + 1))
|
|
150
150
|
continue
|
|
151
151
|
fi
|
|
152
152
|
|
|
153
153
|
if [[ -f "$output_file" ]] && [[ "$force" != "true" ]]; then
|
|
154
154
|
info "Already exists (use --force to overwrite): $output_file"
|
|
155
|
-
((skipped
|
|
155
|
+
skipped=$((skipped + 1))
|
|
156
156
|
continue
|
|
157
157
|
fi
|
|
158
158
|
|
|
159
159
|
dry_run_exec "Render ${page}.md" render_template "$template_file" "$output_file"
|
|
160
|
-
((installed
|
|
160
|
+
installed=$((installed + 1))
|
|
161
161
|
debug "Installed: $output_file"
|
|
162
162
|
done
|
|
163
163
|
|
|
@@ -193,24 +193,24 @@ verify_admin_pages() {
|
|
|
193
193
|
local page page_file
|
|
194
194
|
for page in "${ADMIN_PAGES[@]}"; do
|
|
195
195
|
page_file="$output_dir/${page}.md"
|
|
196
|
-
((total
|
|
196
|
+
total=$((total + 1))
|
|
197
197
|
|
|
198
198
|
if [[ ! -f "$page_file" ]]; then
|
|
199
199
|
warn "Missing: $page_file"
|
|
200
|
-
((errors
|
|
200
|
+
errors=$((errors + 1))
|
|
201
201
|
continue
|
|
202
202
|
fi
|
|
203
203
|
|
|
204
204
|
# Check required front matter fields
|
|
205
205
|
if ! grep -q 'layout: admin' "$page_file" 2>/dev/null; then
|
|
206
206
|
warn "Missing 'layout: admin' in $page_file"
|
|
207
|
-
((errors
|
|
207
|
+
errors=$((errors + 1))
|
|
208
208
|
continue
|
|
209
209
|
fi
|
|
210
210
|
|
|
211
211
|
if ! grep -q 'permalink:' "$page_file" 2>/dev/null; then
|
|
212
212
|
warn "Missing 'permalink' in $page_file"
|
|
213
|
-
((errors
|
|
213
|
+
errors=$((errors + 1))
|
|
214
214
|
continue
|
|
215
215
|
fi
|
|
216
216
|
|
|
@@ -0,0 +1,129 @@
|
|
|
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"
|
|
110
|
+
|
|
111
|
+
echo -e "\nTesting safety against ((var++)) + set -e crash on bash 5.x..."
|
|
112
|
+
|
|
113
|
+
# Regression test: in bash 5.x, ((var++)) when var is 0 returns exit code 1,
|
|
114
|
+
# which under `set -euo pipefail` (used by both the analyzer and the CI workflow
|
|
115
|
+
# step that calls it) terminates the script silently. The fix is to use
|
|
116
|
+
# var=$((var + 1)) which always returns 0. This static check ensures we never
|
|
117
|
+
# reintroduce the ((var++)) pattern in the release-path scripts.
|
|
118
|
+
if grep -qE '\(\([a-zA-Z_][a-zA-Z0-9_]*\+\+\)\)' "$ANALYZER"; then
|
|
119
|
+
assert_true "false" "analyze-commits is free of ((var++)) post-increments"
|
|
120
|
+
else
|
|
121
|
+
assert_true "true" "analyze-commits is free of ((var++)) post-increments"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
CHANGELOG_LIB="$(cd "$SCRIPT_DIR/../../lib" && pwd)/changelog.sh"
|
|
125
|
+
if grep -qE '\(\([a-zA-Z_][a-zA-Z0-9_]*\+\+\)\)' "$CHANGELOG_LIB"; then
|
|
126
|
+
assert_true "false" "changelog.sh is free of ((var++)) post-increments"
|
|
127
|
+
else
|
|
128
|
+
assert_true "true" "changelog.sh is free of ((var++)) post-increments"
|
|
129
|
+
fi
|
|
@@ -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
|
|
@@ -96,17 +110,17 @@ analyze_commit() {
|
|
|
96
110
|
|
|
97
111
|
# Critical/breaking change files (MAJOR)
|
|
98
112
|
if echo "$file" | grep -qE "(Gemfile|gemspec|_config\.yml|docker-compose\.yml|Dockerfile)$"; then
|
|
99
|
-
((critical_files
|
|
113
|
+
critical_files=$((critical_files + 1))
|
|
100
114
|
log_debug "Critical file detected: $file"
|
|
101
115
|
|
|
102
116
|
# Feature files (MINOR)
|
|
103
117
|
elif echo "$file" | grep -qE "(_layouts/|_includes/|assets/|pages/.*\.md$|\.rb$|\.js$)"; then
|
|
104
|
-
((feature_files
|
|
118
|
+
feature_files=$((feature_files + 1))
|
|
105
119
|
log_debug "Feature file detected: $file"
|
|
106
120
|
|
|
107
121
|
# Documentation and minor files (PATCH)
|
|
108
122
|
elif echo "$file" | grep -qE "(README|CHANGELOG|\.md$|\.txt$|\.yml$|\.yaml$|test/)"; then
|
|
109
|
-
((patch_files
|
|
123
|
+
patch_files=$((patch_files + 1))
|
|
110
124
|
log_debug "Patch file detected: $file"
|
|
111
125
|
fi
|
|
112
126
|
done <<< "$commit_files"
|
|
@@ -157,17 +171,17 @@ determine_overall_bump() {
|
|
|
157
171
|
|
|
158
172
|
case "$bump_level" in
|
|
159
173
|
"major")
|
|
160
|
-
((major_count
|
|
174
|
+
major_count=$((major_count + 1))
|
|
161
175
|
highest_bump="major"
|
|
162
176
|
;;
|
|
163
177
|
"minor")
|
|
164
|
-
((minor_count
|
|
178
|
+
minor_count=$((minor_count + 1))
|
|
165
179
|
if [[ "$highest_bump" != "major" ]]; then
|
|
166
180
|
highest_bump="minor"
|
|
167
181
|
fi
|
|
168
182
|
;;
|
|
169
183
|
"patch")
|
|
170
|
-
((patch_count
|
|
184
|
+
patch_count=$((patch_count + 1))
|
|
171
185
|
if [[ "$highest_bump" == "none" ]]; then
|
|
172
186
|
highest_bump="patch"
|
|
173
187
|
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:
|
|
4
|
+
version: 1.1.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
|