Skip to content

Commit 5ec5df8

Browse files
authored
docs: prepare public distribution path
Make GitHub Releases the documented supported public channel, keep PyPI publishing explicitly opt-in, and add public distribution policy checks.
1 parent f11cb50 commit 5ec5df8

9 files changed

Lines changed: 164 additions & 27 deletions

File tree

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ What actually happened. Include the full traceback if applicable.
2323
## Environment
2424
- OS: [e.g. macOS 15, Ubuntu 24.04]
2525
- Python version: [e.g. 3.11.8]
26-
- Commit: [run edb00ee chore: add Makefile, pyproject.toml, CONTRIBUTING, CHANGELOG, docs]
26+
- Install method: [audit.pyz, uv tool, pipx, local clone]
27+
- Version or commit: [run `audit --version` if available, or `git rev-parse --short HEAD` from a clone]

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
77

88
## [Unreleased]
99

10+
### Changed
11+
- Made PyPI publishing explicitly opt-in while keeping GitHub Releases as the supported public distribution path.
12+
- Added PyPI-ready package metadata and public distribution status documentation.
13+
1014
## [0.19.0] - 2026-05-11
1115
### Added
1216
- `audit serve` local web UI (FastAPI + HTMX): portfolio dashboard, per-repo drill-down, run history, approval queue, and SSE-streamed `audit run` trigger. Requires `pip install -e '.[serve]'` (Arc F S4.1).

Makefile

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: install install-dev doctor audit control-center demo benchmark workbook-gate workbook-signoff test lint format type-check run clean release-gate build shiv dist-check release
1+
.PHONY: install install-dev doctor audit control-center demo benchmark workbook-gate workbook-signoff test lint format type-check run clean release-gate build shiv dist-check release publish-pypi
22

33
PYTHON := python3
44
USERNAME ?= saagpatel
@@ -89,6 +89,10 @@ shiv:
8989
shiv -c audit -o dist/audit.pyz . --python "/usr/bin/env python3"
9090
@echo "=== dist/audit.pyz ready. Test: ./dist/audit.pyz --help ==="
9191

92-
release: build dist-check
93-
@echo "=== Uploading to PyPI via scripts/release.sh ==="
94-
bash scripts/release.sh
92+
release: build dist-check shiv
93+
@echo "=== Release artifacts are ready in dist/ ==="
94+
@echo "Tag a v* release to publish GitHub Release assets. Use make publish-pypi only after PyPI trusted publishing or credentials are configured."
95+
96+
publish-pypi:
97+
@echo "=== Publishing wheel + sdist to PyPI via scripts/release.sh ==="
98+
bash scripts/release.sh --publish-pypi

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ Treat campaign/writeback, GitHub Projects, Notion sync, catalog overrides, score
110110
- Workbook tour: [docs/workbook-tour.md](docs/workbook-tour.md)
111111
- Extending analyzers: [docs/extending-analyzers.md](docs/extending-analyzers.md)
112112
- Release gates: [docs/release-gates.md](docs/release-gates.md)
113+
- Distribution status: [docs/distribution.md](docs/distribution.md)
113114
- Project history: [docs/project-history.md](docs/project-history.md)
114115

115116
## Features
@@ -137,7 +138,7 @@ Treat campaign/writeback, GitHub Projects, Notion sync, catalog overrides, score
137138

138139
### Installation
139140

140-
The package is published as GitHub release artifacts today. PyPI/package-index publishing is not active yet, so registry commands like `pip install github-repo-auditor` are not the recommended public path.
141+
The package is published as GitHub release artifacts today. PyPI/package-index publishing is not active yet, so registry commands like `pip install github-repo-auditor` are not the recommended public path. See [docs/distribution.md](docs/distribution.md) for the current distribution policy.
141142

142143
Fastest no-clone path:
143144

docs/distribution.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Distribution
2+
3+
GitHub Repo Auditor is public and currently distributed through GitHub Releases.
4+
5+
## Current Public Path
6+
7+
Use the latest release binary when you want the fastest no-clone install:
8+
9+
```bash
10+
curl -LO https://github.com/saagpatel/GithubRepoAuditor/releases/latest/download/audit.pyz
11+
chmod +x audit.pyz
12+
./audit.pyz --help
13+
```
14+
15+
Use the public GitHub source when you want an isolated tool install:
16+
17+
```bash
18+
uv tool install 'git+https://github.com/saagpatel/GithubRepoAuditor.git'
19+
pipx install 'git+https://github.com/saagpatel/GithubRepoAuditor.git'
20+
```
21+
22+
## PyPI Status
23+
24+
PyPI publishing is not active yet. The package name `github-repo-auditor` was
25+
available when checked during the public-readiness pass on 2026-05-18, but that
26+
can change and should be rechecked immediately before first publication.
27+
28+
The repository is prepared for a future PyPI release:
29+
30+
- package metadata lives in `pyproject.toml`
31+
- `make build` creates the wheel and source distribution
32+
- `make dist-check` runs `twine check`
33+
- `scripts/release.sh` builds and checks artifacts by default
34+
- `scripts/release.sh --publish-pypi` is the only script path that uploads to PyPI
35+
36+
## Activation Checklist
37+
38+
Before the first PyPI release:
39+
40+
1. Recheck that the `github-repo-auditor` PyPI name is still available.
41+
2. Create the PyPI project through a first upload or configure Trusted Publishing.
42+
3. Prefer PyPI Trusted Publishing from GitHub Actions over long-lived API tokens.
43+
4. Run the standard and distribution gates from [release-gates.md](release-gates.md).
44+
5. Publish the same version that is tagged on GitHub.
45+
6. Smoke-test `pipx install github-repo-auditor` or `uv tool install github-repo-auditor`.
46+
47+
Until that checklist is complete, GitHub Releases remain the supported public
48+
distribution channel.

docs/release-gates.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,17 @@ All three must pass before tagging:
153153
and non-PEP 440 tag suffixes can break the release build.
154154
- Public hardening releases should use patch versions (`v0.1.x`). Feature releases
155155
should move the minor version (`v0.2.0`, `v0.3.0`, and so on).
156-
- TWINE upload to PyPI is manual-only and not part of the current public install
157-
story; CI only checks and uploads to GitHub Releases.
156+
- PyPI upload is explicit opt-in and not part of the current public install story.
157+
`scripts/release.sh` builds and checks artifacts by default; it uploads only when
158+
run as `scripts/release.sh --publish-pypi` with valid credentials. CI only checks
159+
and uploads to GitHub Releases.
158160
- The `[serve]` extra is not bundled in the shiv binary by default. Users who need the
159161
web UI should install from the GitHub source with the `[serve]` extra or use a local
160162
editable clone.
161163

164+
See [distribution.md](distribution.md) for the public distribution policy and the
165+
remaining PyPI activation checklist.
166+
162167
## Web UI Gate (scope: audit serve)
163168

164169
Run when any change touches `src/serve/` or `tests/test_serve.py`.

pyproject.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ description = "Automated GitHub portfolio auditor with 12 analysis dimensions"
99
readme = "README.md"
1010
requires-python = ">=3.11"
1111
license = "MIT"
12+
authors = [{ name = "Saag Patel" }]
13+
keywords = [
14+
"github",
15+
"portfolio",
16+
"audit",
17+
"repository-analysis",
18+
"developer-tools",
19+
]
20+
classifiers = [
21+
"Development Status :: 3 - Alpha",
22+
"Environment :: Console",
23+
"Intended Audience :: Developers",
24+
"Programming Language :: Python :: 3",
25+
"Programming Language :: Python :: 3.11",
26+
"Programming Language :: Python :: 3.12",
27+
"Topic :: Software Development :: Quality Assurance",
28+
"Topic :: Utilities",
29+
]
1230
dependencies = [
1331
"requests>=2.31.0",
1432
"python-dateutil>=2.8.0",
@@ -51,6 +69,8 @@ build = [
5169
Homepage = "https://github.com/saagpatel/GithubRepoAuditor"
5270
Repository = "https://github.com/saagpatel/GithubRepoAuditor"
5371
"Bug Tracker" = "https://github.com/saagpatel/GithubRepoAuditor/issues"
72+
Changelog = "https://github.com/saagpatel/GithubRepoAuditor/blob/main/CHANGELOG.md"
73+
Documentation = "https://github.com/saagpatel/GithubRepoAuditor#readme"
5474

5575
[project.scripts]
5676
audit = "src.cli:main"

scripts/release.sh

100755100644
Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
#!/usr/bin/env bash
2-
# scripts/release.sh — PyPI publish workflow for github-repo-auditor
2+
# scripts/release.sh — distribution artifact workflow for github-repo-auditor
33
#
44
# Prerequisites:
55
# pip install build twine shiv (or: pip install ".[build]")
66
#
7-
# Required env vars (one of):
7+
# Required env vars for --publish-pypi (one of):
88
# TWINE_API_TOKEN — PyPI API token (preferred)
99
# TWINE_USERNAME + TWINE_PASSWORD — legacy username/password
1010
#
1111
# Usage:
12-
# bash scripts/release.sh # build + check + upload to PyPI
13-
# bash scripts/release.sh --dry-run # build + check only, skip upload
12+
# bash scripts/release.sh # build + check only
13+
# bash scripts/release.sh --publish-pypi # build + check + upload to PyPI
14+
# bash scripts/release.sh --dry-run # compatibility alias for build + check only
1415
#
1516
set -euo pipefail
1617

17-
DRY_RUN=false
18+
PUBLISH_PYPI=false
19+
SKIP_CLEAN=false
1820
for arg in "$@"; do
1921
case "$arg" in
20-
--dry-run) DRY_RUN=true ;;
22+
--publish-pypi) PUBLISH_PYPI=true ;;
23+
--dry-run) PUBLISH_PYPI=false ;;
24+
--skip-clean) SKIP_CLEAN=true ;;
25+
*)
26+
echo "Unknown argument: $arg"
27+
echo "Usage: bash scripts/release.sh [--publish-pypi] [--dry-run] [--skip-clean]"
28+
exit 2
29+
;;
2130
esac
2231
done
2332

@@ -30,9 +39,20 @@ echo "Project root: $PROJECT_ROOT"
3039
echo ""
3140

3241
# 1. Clean previous artifacts
33-
echo "[1/4] Cleaning dist/"
34-
rm -rf dist/ build/ src/*.egg-info
35-
echo " Done."
42+
echo "[1/4] Cleaning build artifacts..."
43+
if [ "$SKIP_CLEAN" = "true" ]; then
44+
echo " Skipped."
45+
else
46+
python3 - <<'PY'
47+
from pathlib import Path
48+
import shutil
49+
50+
for path in [Path("dist"), Path("build"), *Path("src").glob("*.egg-info")]:
51+
if path.exists():
52+
shutil.rmtree(path)
53+
PY
54+
echo " Done."
55+
fi
3656

3757
# 2. Build wheel + sdist
3858
echo "[2/4] Building wheel + sdist..."
@@ -45,11 +65,11 @@ echo "[3/4] Running twine check..."
4565
python3 -m twine check dist/*
4666
echo " All checks passed."
4767

48-
# 4. Upload (unless --dry-run)
49-
if [ "$DRY_RUN" = "true" ]; then
50-
echo "[4/4] --dry-run set — skipping upload."
68+
# 4. Upload only when explicitly requested.
69+
if [ "$PUBLISH_PYPI" != "true" ]; then
70+
echo "[4/4] PyPI publish not requested — skipping upload."
5171
echo ""
52-
echo "=== Dry run complete. Artifacts in dist/ ==="
72+
echo "=== Distribution check complete. Artifacts in dist/ ==="
5373
exit 0
5474
fi
5575

@@ -70,9 +90,3 @@ fi
7090

7191
echo ""
7292
echo "=== Upload complete! ==="
73-
echo ""
74-
echo "Next steps:"
75-
echo " 1. Tag this release: git tag v$(python3 -c "import importlib.metadata; print(importlib.metadata.version('github-repo-auditor'))" 2>/dev/null || grep '^version' pyproject.toml | head -1 | cut -d'"' -f2)"
76-
echo " 2. Push the tag: git push origin --tags"
77-
echo " 3. Create GitHub Release and attach dist/audit.pyz (if built)"
78-
echo ""

tests/test_distribution_policy.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""Distribution policy checks for the public package surface."""
2+
3+
from __future__ import annotations
4+
5+
import tomllib
6+
from pathlib import Path
7+
8+
ROOT = Path(__file__).parent.parent
9+
10+
11+
def test_pyproject_has_public_package_metadata() -> None:
12+
with open(ROOT / "pyproject.toml", "rb") as fh:
13+
project = tomllib.load(fh)["project"]
14+
15+
assert project["name"] == "github-repo-auditor"
16+
assert project.get("authors"), "PyPI metadata should include an author entry."
17+
assert project.get("classifiers"), "PyPI metadata should include classifiers."
18+
assert project.get("keywords"), "PyPI metadata should include package keywords."
19+
assert "Documentation" in project.get("urls", {})
20+
assert "Changelog" in project.get("urls", {})
21+
22+
23+
def test_release_script_requires_explicit_pypi_publish_flag() -> None:
24+
release_script = (ROOT / "scripts" / "release.sh").read_text()
25+
26+
assert "PUBLISH_PYPI=false" in release_script
27+
assert "--publish-pypi" in release_script
28+
assert 'if [ "$PUBLISH_PYPI" != "true" ]' in release_script
29+
assert "PyPI publish not requested" in release_script
30+
31+
32+
def test_distribution_docs_name_supported_public_channel() -> None:
33+
distribution_doc = (ROOT / "docs" / "distribution.md").read_text()
34+
readme = (ROOT / "README.md").read_text()
35+
release_gates = (ROOT / "docs" / "release-gates.md").read_text()
36+
37+
assert "GitHub Releases remain the supported public" in distribution_doc
38+
assert "PyPI publishing is not active yet" in distribution_doc
39+
assert "docs/distribution.md" in readme
40+
assert "scripts/release.sh --publish-pypi" in release_gates

0 commit comments

Comments
 (0)