Skip to content

Commit cb1a288

Browse files
fix: resolve merge conflicts in CHANGELOG.md and pyproject.toml by dev-engineer
2 parents 20d5a62 + d2e13af commit cb1a288

15 files changed

Lines changed: 316 additions & 116 deletions

File tree

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @Coding-Dev-Tools

.github/workflows/ci.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@ jobs:
2323
- name: Run ruff check
2424
run: ruff check src/ tests/
2525

26+
- name: Check formatting
27+
run: ruff format --check src/ tests/
28+
2629
test:
2730
runs-on: ubuntu-latest
2831
strategy:
2932
matrix:
30-
python-version: ["3.10", "3.11", "3.12"]
33+
python-version: ["3.10", "3.11", "3.12", "3.13"]
3134

3235
steps:
3336
- uses: actions/checkout@v6

.github/workflows/publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ jobs:
1313
id-token: write
1414

1515
steps:
16-
- uses: actions/checkout@v4
16+
- uses: actions/checkout@v6
1717

1818
- name: Set up Python
19-
uses: actions/setup-python@v5
19+
uses: actions/setup-python@v6
2020
with:
2121
python-version: '3.12'
2222

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: release-audit
2+
3+
on:
4+
pull_request:
5+
branches: [main, master]
6+
push:
7+
branches: [main, master]
8+
workflow_dispatch:
9+
10+
jobs:
11+
audit:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v6
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v6
18+
with:
19+
python-version: "3.11"
20+
21+
- name: Run release audit
22+
run: |
23+
python3 - <<'PY'
24+
import json, pathlib, sys
25+
26+
repo = pathlib.Path.cwd()
27+
scorecard = {"overall_grade": "A", "angles_passing": 0, "angles_total": 8, "blockers": 0, "angles": []}
28+
29+
def check(name, grade, detail):
30+
scorecard["angles"].append({"angle": name, "grade": grade, "detail": detail})
31+
if grade == "A":
32+
scorecard["angles_passing"] += 1
33+
elif grade == "F":
34+
scorecard["blockers"] += 1
35+
36+
# 1. README
37+
readme = repo / "README.md"
38+
if readme.exists() and len(readme.read_text()) > 200:
39+
check("README", "A", "README.md exists and has content")
40+
else:
41+
check("README", "F", "README.md missing or too short")
42+
43+
# 2. License
44+
lic = repo / "LICENSE"
45+
if lic.exists() and len(lic.read_text()) > 100:
46+
check("License", "A", "LICENSE file present")
47+
else:
48+
check("License", "F", "LICENSE file missing or too short")
49+
50+
# 3. CI/CD
51+
wf_dir = repo / ".github" / "workflows"
52+
wf_files = list(wf_dir.glob("*.yml")) + list(wf_dir.glob("*.yaml"))
53+
if len(wf_files) >= 1:
54+
check("CI/CD", "A", f"{len(wf_files)} workflow(s) found")
55+
else:
56+
check("CI/CD", "F", "No CI/CD workflows found")
57+
58+
# 4. Dependencies
59+
pyproj = repo / "pyproject.toml"
60+
if pyproj.exists():
61+
check("Dependencies", "A", "pyproject.toml found")
62+
else:
63+
check("Dependencies", "F", "pyproject.toml missing")
64+
65+
# 5. Tests
66+
tests = repo / "tests"
67+
test_files = list(tests.glob("test_*.py")) + list(tests.glob("*_test.py"))
68+
if len(test_files) >= 1:
69+
check("Tests", "A", f"{len(test_files)} test file(s) found")
70+
else:
71+
check("Tests", "F", "No test files found")
72+
73+
# 6. Versioning
74+
if pyproj.exists():
75+
import tomllib
76+
data = tomllib.loads(pyproj.read_text())
77+
ver = data.get("project", {}).get("version", "")
78+
if ver:
79+
check("Versioning", "A", f"Version {ver} set in pyproject.toml")
80+
else:
81+
check("Versioning", "F", "No version in pyproject.toml")
82+
else:
83+
check("Versioning", "F", "Cannot check version — pyproject.toml missing")
84+
85+
# 7. Changelog
86+
changelog = repo / "CHANGELOG.md"
87+
if changelog.exists() and len(changelog.read_text()) > 50:
88+
check("Changelog", "A", "CHANGELOG.md present")
89+
else:
90+
check("Changelog", "C", "CHANGELOG.md missing or too short")
91+
92+
# 8. Security
93+
sec = repo / "SECURITY.md"
94+
if sec.exists() and len(sec.read_text()) > 50:
95+
check("Security", "A", "SECURITY.md present")
96+
else:
97+
check("Security", "C", "SECURITY.md missing or too short")
98+
99+
# Compute overall grade
100+
if scorecard["blockers"] > 0:
101+
scorecard["overall_grade"] = "F"
102+
elif scorecard["angles_passing"] == scorecard["angles_total"]:
103+
scorecard["overall_grade"] = "A"
104+
elif scorecard["angles_passing"] >= scorecard["angles_total"] - 2:
105+
scorecard["overall_grade"] = "B"
106+
else:
107+
scorecard["overall_grade"] = "C"
108+
109+
out_dir = repo / "scorecard"
110+
out_dir.mkdir(exist_ok=True)
111+
(out_dir / f"{repo.name}.json").write_text(json.dumps(scorecard, indent=2))
112+
113+
print("## Release Audit (8 angles)")
114+
print()
115+
print(f"**Overall grade: {scorecard['overall_grade']}** ({scorecard['angles_passing']}/{scorecard['angles_total']} angles passing, {scorecard['blockers']} blocker(s))")
116+
print()
117+
print("| Angle | Grade | Detail |")
118+
print("|-------|-------|--------|")
119+
for a in scorecard["angles"]:
120+
print(f"| {a['angle']} | {a['grade']} | {a['detail']} |")
121+
122+
if scorecard["blockers"] > 0:
123+
print(f"\n::error::{scorecard['blockers']} release-blocker angle(s) — see audit output above")
124+
sys.exit(1)
125+
PY

.gitignore

Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,75 @@
1-
# Byte-compiled / optimized / compiled files
2-
__pycache__/
3-
*.py[cod]
4-
*$py.class
5-
6-
# C extensions
7-
*.so
8-
9-
# Distribution / packaging
10-
.Python
11-
build/
12-
develop-eggs/
13-
dist/
14-
downloads/
15-
eggs/
16-
.eggs/
17-
lib/
18-
lib64/
19-
parts/
20-
sdist/
21-
var/
22-
wheels/
23-
*.egg-info/
24-
*.egg
25-
26-
# PyInstaller
27-
*.manifest
28-
*.spec
29-
30-
# Installer logs
31-
pip-log.txt
32-
pip-delete-this-directory.txt
33-
34-
# Unit test / coverage
35-
htmlcov/
36-
.tox/
37-
.nox/
38-
.coverage
39-
.coverage.*
40-
.cache
41-
nosetests.xml
42-
coverage.xml
43-
*.cover
44-
*.py,cover
45-
.hypothesis/
46-
.pytest_cache/
47-
48-
# Translations
49-
*.mo
50-
*.pot
51-
52-
# Environments
53-
.env
54-
.venv
55-
env/
56-
venv/
57-
ENV/
58-
59-
# IDE
60-
.vscode/
61-
.idea/
62-
*.swp
63-
*.swo
64-
*~
65-
66-
# OS
67-
.DS_Store
68-
Thumbs.db
69-
70-
# Project specific
71-
research/
72-
fixtures/generated/
1+
# Byte-compiled / optimized / compiled files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
*.egg-info/
24+
*.egg
25+
26+
# PyInstaller
27+
*.manifest
28+
*.spec
29+
30+
# Installer logs
31+
pip-log.txt
32+
pip-delete-this-directory.txt
33+
34+
# Unit test / coverage
35+
htmlcov/
36+
.tox/
37+
.nox/
38+
.coverage
39+
.coverage.*
40+
.cache
41+
nosetests.xml
42+
coverage.xml
43+
*.cover
44+
*.py,cover
45+
.hypothesis/
46+
.pytest_cache/
47+
48+
# Translations
49+
*.mo
50+
*.pot
51+
52+
# Environments
53+
.env
54+
.venv
55+
env/
56+
venv/
57+
ENV/
58+
59+
# IDE
60+
.vscode/
61+
.idea/
62+
*.swp
63+
*.swo
64+
*~
65+
66+
# OS
67+
.DS_Store
68+
Thumbs.db
69+
70+
# Project specific
71+
research/
72+
fixtures/generated/
73+
74+
# Added by release-prep
75+
node_modules

AGENTS.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# devforge-cli
2+
3+
## Purpose
4+
DevForge CLI meta-package that installs all 11 developer tools in one command. Provides a unified `devforge` CLI entry point delegating to sub-tools: api-contract-guardian, json2sql, deploydiff, configdrift, apighost, apiauth, envault, schemaforge, click-to-mcp, and deadcode.
5+
6+
## Build & Test Commands
7+
- Install: `pip install -e .[all]` or `pip install devforge`
8+
- Install all tools: `pip install devforge[all]`
9+
- Test: `pytest tests/` (or `python -m pytest tests/ -v --tb=short`)
10+
- Lint: `ruff check .`
11+
- Build: `pip install build twine && python -m build && twine check dist/*`
12+
- CLI check: `devforge --help`
13+
14+
## Architecture
15+
Key directories:
16+
- `src/devforge/` — Main package (CLI dispatcher, version management)
17+
- `tests/` — Test suite
18+
- `.github/workflows/` — CI/CD pipelines
19+
20+
## Conventions
21+
- Language: Python 3.10+
22+
- Test framework: pytest
23+
- Linting: ruff
24+
- Build system: setuptools with src/ layout
25+
- CLI entry point: `devforge.cli:app`
26+
- Optional dependency groups: guard, sql, deploy, drift, ghost, auth, envault, schema, mcp, deadcode, all
27+
- Default branch: main

CHANGELOG.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
1-
## [0.4.0] - 2026-06-30
2-
3-
### Changed
4-
- Renamed PyPI package from `devforge` to `devforge-tools` (name `devforge` was squatted on PyPI)
5-
- Updated all URLs, badges, and references to point to `devforge-tools`
6-
71
# Changelog
82

93
All notable changes to Revenue Holdings CLI will be documented in this file.
104

115
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
126
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
137

8+
## [0.4.0] - 2026-06-30
9+
10+
### Changed
11+
- Renamed PyPI package from `devforge` to `devforge-tools` (name `devforge` was squatted on PyPI)
12+
- Updated all URLs, badges, and references to point to `devforge-tools`
13+
14+
## [0.3.0] - 2026-06-30
15+
16+
### Added
17+
- Python 3.13 to CI test matrix
18+
- Formatting check step in CI workflow
19+
- `format-check` Makefile target
20+
21+
### Changed
22+
- Makefile lint/format targets scoped to `src/ tests/` instead of entire repo
23+
1424
## [0.2.0] - 2026-05-17
1525

1626
### Added
@@ -29,4 +39,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2939
### Added
3040
- Initial release with 4 tools: guard, sql, deploy, drift
3141
- Unified `rh` CLI entry point
32-
- Tool dispatching via subprocess
42+
- Tool dispatching via subprocess

0 commit comments

Comments
 (0)