Skip to content

Commit ece8f9b

Browse files
Doc/spec kit and project sync (#200)
All unit tests migrated to correct location to follow defined principles. Add new rule about branch prefixes. Update CI file for unit testing.
1 parent 5ec9ec2 commit ece8f9b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+569
-495
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ jobs:
107107
run: echo "PYTHONPATH=${GITHUB_WORKSPACE}/release_notes_generator/release_notes_generator" >> $GITHUB_ENV
108108

109109
- name: Check code coverage with Pytest
110-
run: pytest --cov=. -v tests/ --cov-fail-under=80
110+
run: pytest --cov=. -v tests/unit --cov-fail-under=80
111111

112112
mypy-check:
113113
runs-on: ubuntu-latest

.specify/constitution.md

Lines changed: 103 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<!--
22
Sync Impact Report
3-
Version change: 1.0.0 -> 1.0.1
4-
Modified sections: Governance & Ownership (maintainers list)
5-
Added sections: None
3+
Version change: 1.3.0 -> 1.4.0
4+
Modified sections: Principle 13 expanded to include fix/, docs/, chore/; Quality Gates branch naming; Compliance Review
5+
Added sections: Allowed prefix list & category descriptions; CI workflow enforcement `.github/workflows/branch-prefix-check.yml`
66
Removed sections: None
7-
Change type: PATCH (metadata clarification, no principle change)
8-
Templates requiring updates: None (no template impact)
7+
Change type: MINOR (expanded enforceable governance rule)
8+
Templates requiring updates: plan-template.md (✅), tasks-template.md (✅), spec-template.md (✅), DEVELOPER.md (✅), CONTRIBUTING.md (✅), branch-prefix-check.yml (✅)
9+
Deferred TODOs: None
910
-->
1011

1112
# Release Notes Scrapper Action Constitution
@@ -65,11 +66,23 @@ manage version tagging; it consumes existing tags.
6566
7. `ReleaseNotesBuilder` iterates chapters → collects matching records → applies row format templates / duplicity markers.
6667
8. Final Markdown string emitted; composite action sets `release-notes` output.
6768

68-
### Boundary Rules
69+
### Boundary Rules (Refined)
6970
- Action inputs boundary: all configurable behavior must pass via declared inputs (no hidden runtime switches).
7071
- GitHub API boundary: all repository data access encapsulated within miner and rate limiter logic.
7172
- Formatting boundary: only row format templates and chapters influence visible line structure; business logic must not
7273
directly embed presentation markup elsewhere.
74+
- Error boundary: modules MUST NOT leak raw exceptions across boundaries; they must convert failures into logged events
75+
and structured return values (see Principle 9). Internal exceptions MAY be raised and caught within the same module.
76+
- Utility boundary: functions in `utils/` MUST be demonstrably used by at least one importing module or removed (see Principle 8 & 10).
77+
78+
### Module Boundary Follow-Up
79+
A scheduled audit SHALL verify:
80+
- `utils/` contains only actively referenced functions (dead code removal list to be created).
81+
- `generator.py` remains orchestration-only (no direct formatting or low-level API calls beyond miner invocation).
82+
- `builder/` never performs mining; strictly transforms records to Markdown.
83+
- `record/factory` isolates construction logic; future refactors MAY extract validation into a separate `validators/` module.
84+
- Logging configuration centralization: confirm no duplicate ad-hoc log setup outside `main.py`.
85+
Outcome: Produce a follow-up task list referencing each violation if found; merge only with accompanying unit tests.
7386

7487
## 3. Data & Integrations
7588

@@ -119,13 +132,39 @@ manage version tagging; it consumes existing tags.
119132
## 5. Quality & Testing
120133

121134
### Test Types
122-
- Unit tests (expected for pure utility and formatting functions).
135+
- Unit tests for pure utility, transformation, formatting, and record construction functions.
123136
- Integration tests (e.g. `integration_test.py`) covering end-to-end generation using mocked or controlled data.
124-
- No explicit contract tests yet; future addition may define record/chapter contract snapshots.
137+
- Future: contract/snapshot tests MAY be introduced for chapter output stability (not mandatory yet).
138+
139+
### Test Directory Structure (New)
140+
```
141+
tests/
142+
unit/ # All Python unit tests (test_<module>.py) - REQUIRED location
143+
integration/ # Future integration tests (current single file may migrate here)
144+
fixtures/ # Shared static test data & factories (optional)
145+
helpers/ # Helper utilities used only by tests (must be imported by tests/*)
146+
release_notes/ # Domain-specific sample data (review for possible move under fixtures/)
147+
utils/ # Test-only utility functions (rename to helpers/ or remove if redundant)
148+
```
149+
Rules:
150+
- All unit tests MUST reside under `tests/unit/` (root-level `test_*.py` files SHALL be relocated).
151+
- Naming: `test_<target>.py`; multiple related small targets MAY share one file if cohesive.
152+
- Test style: uses ONLY `pytest` (no unittest classes). Prefer functions + fixtures.
153+
- Fixtures: define shared objects in `tests/conftest.py` or per-file fixtures; keep scope minimal.
154+
- Parametrization: use `@pytest.mark.parametrize` for input matrix instead of loops.
155+
- Coverage: new logic MUST raise overall coverage or keep it steady; dropping coverage requires explicit justification.
156+
- NEW: Unit test file path MUST mirror source relative package path (Principle 12). For source file `release_notes_generator/utils/constants.py`, the test lives at `tests/unit/release_notes_generator/utils/test_constants.py`.
157+
- Branch Naming: Feature / fix / docs / chore PRs MUST originate from correctly prefixed branch (Principle 13); CI may validate.
158+
159+
### Organization & Integration
160+
- Integration tests MUST import public interfaces only (`main`, `ReleaseNotesGenerator`) not internal private helpers.
161+
- Unit tests MUST avoid real network calls; use mocking or local sample data.
162+
- Cross-test independence: tests MUST NOT rely on execution order; no shared mutation outside fixture scope.
163+
- Relocation of existing root-level unit tests into `tests/unit/` SHALL be part of first compliance PR post-amendment.
125164

126165
### Coverage
127-
- `pytest-cov` integrated; HTML coverage artifacts seen in `htmlcov/`. Target: maintain or improve existing coverage
128-
(implicit baseline > minimal demonstration). New core logic MUST include tests before implementation (Test‑First Principle).
166+
- `pytest-cov` integrated; HTML coverage artifacts under `htmlcov/`. Baseline maintained or improved. New core logic MUST
167+
include tests before implementation (Test‑First Principle).
129168

130169
### Static Analysis & Review
131170
- `pylint`, `mypy` required to pass (configuration present).
@@ -135,7 +174,9 @@ manage version tagging; it consumes existing tags.
135174
### Quality Gates (Minimum Acceptance)
136175
- Tests: ALL must pass.
137176
- Lint + type: zero blocking errors.
177+
- No unused functions/methods (see Principle 10) — introduce usage or delete in same PR.
138178
- Backward compatibility: no silent change to input names or placeholder semantics without version bump & documentation update.
179+
- Branch naming compliance (Principle 13) — allowed prefixes: feature/, fix/, docs/, chore/; rename if violated.
139180

140181
## 6. Constraints & Compatibility
141182

@@ -169,6 +210,7 @@ manage version tagging; it consumes existing tags.
169210
- Hierarchy expansion could incur additional API calls increasing latency.
170211
- Duplicate detection edge cases may confuse users if same issue intentionally spans categories.
171212
- CodeRabbit integration features may parse unintended summary content (format variance risk).
213+
- Dead code accumulation in `utils/` may reduce clarity if Principle 10 not enforced promptly.
172214

173215
### Assumptions
174216
- Repository uses semantic version tags (prefixed optionally by `v`).
@@ -200,6 +242,7 @@ manage version tagging; it consumes existing tags.
200242
### Compliance Review
201243
- PR template or automated check SHOULD reference Constitution principles (especially Test‑First & Stability) before merge.
202244
- Violations require explicit justification section in PR description.
245+
- Review checklist MUST confirm Principle 13 prefix correctness and scope alignment.
203246

204247
### Release Management
205248
- Tagging strategy external; this action consumes tags. Recommend semantic versioning for repository releases.
@@ -236,7 +279,7 @@ Ensure Constitution Check section in `plan.md` passes before advancing to detail
236279

237280
## Change Log / Versioning
238281
- Project releases follow Git tags; this constitution uses semantic versioning independent of code releases.
239-
- Current Constitution Version: 1.0.1 (initial ratification).
282+
- Current Constitution Version: 1.4.0 (amended with new principles & test structure).
240283
- Future amendments tracked via Sync Impact Report at top of this file.
241284

242285
## Core Principles
@@ -277,5 +320,53 @@ Mining MUST use rate limiter abstraction; avoid redundant API calls (e.g. re-fet
277320
MUST short-circuit when disabled. Performance considerations addressed before accepting features that multiply API calls.
278321
Rationale: Preserves quota & improves speed on large repositories.
279322

323+
### Principle 8: Lean Python Design
324+
Prefer simple functions and modules over unnecessary classes. A class MUST only be introduced when stateful behavior or
325+
polymorphism is required. Utility modules SHOULD expose pure functions. Avoid deep inheritance; favor composition.
326+
Rationale: Reduces complexity and improves readability & testability.
327+
328+
### Principle 9: Localized Error Handling & Non-Exceptional Flow
329+
Modules MUST catch internal exceptions and convert them into structured return values plus logged messages. Cross-module
330+
exception propagation (raising raw exceptions across boundaries) is prohibited except for truly unrecoverable setup
331+
failures at the entry point (`main`). Return either a valid result or a clearly logged empty/partial result.
332+
Rationale: Ensures predictable action behavior and prevents silent termination in CI pipelines.
333+
334+
### Principle 10: Dead Code Prohibition
335+
No unused methods/functions SHALL remain in the codebase (properties or inherited abstract/interface methods excepted).
336+
Utility files MUST contain only actively invoked functions. Removal of unused code MUST occur in the same PR that
337+
introduces its obsolescence.
338+
Rationale: Prevents confusion, reduces maintenance overhead, and keeps coverage meaningful.
339+
340+
### Principle 11: Focused & Informative Comments
341+
Comments MUST explain non-obvious logic, constraints, or reasoning succinctly. Prohibited: narrative, outdated, or
342+
speculative comments. Allowed: brief context before complex loops, rationale for workaround, links to issue references.
343+
Comments SHOULD be maintained or updated alongside code changes; stale comments MUST be removed.
344+
Rationale: Enhances clarity without adding noise.
345+
346+
### Principle 12: Test Path Mirroring
347+
Each unit test file MUST reside under `tests/unit/` mirroring the source package path and file name: `tests/unit/<source_root_relative_path>/test_<original_file_name>.py`.
348+
Mandatory Rules:
349+
- One test file per source file unless tightly coupled logic demands grouping (justify in PR).
350+
- Legacy non-mirrored category folders are deprecated; migrate incrementally without reducing coverage.
351+
- New or refactored modules require mirrored test path in same PR.
352+
Rationale: Ensures predictable test discovery, simplifies navigation between code and tests, and supports scalable refactors.
353+
354+
### Principle 13: Branch Naming Consistency
355+
All new branches for work MUST start with one of the approved prefixes followed by a concise kebab-case descriptor (optional numeric ID).
356+
Approved prefixes:
357+
- `feature/` – new features & enhancements
358+
- `fix/` – bug fixes / defect resolutions
359+
- `docs/` – documentation-only updates
360+
- `chore/` – maintenance, dependency bumps, CI, non-behavioral refactors
361+
Examples:
362+
`feature/add-hierarchy-support`, `fix/567-handle-empty-chapters`, `docs/improve-readme-start`, `chore/upgrade-semver-lib`
363+
Rules:
364+
- Prefix REQUIRED and MUST be in approved set; rename non-compliant branches prior to PR.
365+
- Descriptor: lowercase kebab-case; hyphen separators; no spaces/underscores/trailing slash.
366+
- Optional numeric ID may precede description (`fix/987-null-title`).
367+
- Category alignment: branch prefix MUST match primary scope of PR contents.
368+
- Avoid vague descriptors (`update`, `changes`). Prefer action or subject (`improve-logging`, `remove-dead-code`).
369+
Rationale: Standardizes history, enables automated governance checks, clarifies intent for reviewers & tooling.
370+
280371
## Governance Metadata
281-
**Version**: 1.0.1 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-12
372+
**Version**: 1.4.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14

0 commit comments

Comments
 (0)