Skip to content

Commit 8c8aee9

Browse files
feat(docs): enhance documentation with new guides and examples for CPython Patch PR Action
1 parent 67ce94a commit 8c8aee9

File tree

10 files changed

+722
-3
lines changed

10 files changed

+722
-3
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ Each accepts inline data or a file path. Missing snapshots fail fast with a clea
204204

205205
## Example consumer repositories
206206

207-
See templates in [`examples/`](examples):
207+
See templates in [`examples/`](https://github.com/CasperKristiansson/python-version-patch-pr/tree/main/examples):
208208

209-
- [`examples/minimal`](examples/minimal): single-job workflow scheduled weekly.
210-
- [`examples/guarded`](examples/guarded): dry-run preview with release-note gating and concurrency controls.
209+
- [`examples/minimal`](https://github.com/CasperKristiansson/python-version-patch-pr/tree/main/examples/minimal): single-job workflow scheduled weekly.
210+
- [`examples/guarded`](https://github.com/CasperKristiansson/python-version-patch-pr/tree/main/examples/guarded): dry-run preview with release-note gating and concurrency controls.
211211

212212
## Permissions
213213

docs/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Documentation Portal
2+
3+
Welcome to the extended documentation for the **CPython Patch PR Action**. The root `README.md` stays focused on onboarding. Everything else you need to operate, configure, and develop the action lives in this `/docs` tree.
4+
5+
## Contents
6+
7+
- [Architecture](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/architecture.md) – data flow, modules, and decision points inside the action.
8+
- [Configuration Guide](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/configuration.md) – exhaustive reference for inputs, outputs, environment variables, and permissions.
9+
- [Workflow Recipes](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/workflows.md) – ready-to-adapt GitHub Actions layouts for different rollout strategies.
10+
- [Examples & Outputs](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/examples.md) – before/after snippets, log excerpts, and output payloads.
11+
- [Development Handbook](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/development.md) – local environment setup, scripts, and release hygiene for contributors.
12+
- [Testing Strategy](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/testing.md) – what we test, how to extend coverage, and how to run suites.
13+
- [Troubleshooting](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/troubleshooting.md) – decode every skip reason and common runtime failure.
14+
15+
## How to Use These Docs
16+
17+
1. **New adopters** start with the README quick start, then read [Workflow Recipes](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/workflows.md) to choose a deployment pattern.
18+
2. **Platform teams** should combine [Configuration](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/configuration.md) with [Troubleshooting](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/troubleshooting.md) to wire secrets and alerts.
19+
3. **Maintainers and contributors** should review [Architecture](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/architecture.md), [Development](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/development.md), [Examples](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/examples.md), and [Testing](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/docs/testing.md) before opening pull requests.
20+
21+
Complementary references:
22+
23+
- [`CHANGELOG.md`](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/CHANGELOG.md) – release notes.
24+
- [`ROADMAP.md`](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/ROADMAP.md) – future work.
25+
- [`CONTRIBUTING.md`](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/CONTRIBUTING.md) – contribution standards.
26+
- [`SECURITY.md`](https://github.com/CasperKristiansson/python-version-patch-pr/blob/main/SECURITY.md) – coordinated disclosure process.

docs/architecture.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Architecture
2+
3+
The CPython Patch PR Action is implemented as a TypeScript GitHub Action (CommonJS build) whose runtime entry point is `src/index.ts`. The codebase follows a dependency-injected architecture so core logic can be exercised in isolation via Vitest.
4+
5+
## High-Level Flow
6+
7+
1. **Input + environment normalization**`src/index.ts` resolves action inputs, environment variables, and offline snapshots, then constructs the `ExecuteOptions` bag.
8+
2. **Orchestration**`executeAction` in `src/action-execution.ts` coordinates scanning, version discovery, gating, rewriting, and (optionally) git + PR operations. External services are passed in through the `ExecuteDependencies` interface.
9+
3. **Scanning**`scanForPythonVersions` (`src/scanning/scanner.ts`) expands glob patterns, reads files, and applies pattern detectors to collect every pinned `X.Y.Z` reference along with file/line/column metadata.
10+
4. **Decision gates**`determineSingleTrack`, `resolveLatestPatch`, `fetchLatestFromPythonOrg`, `enforcePreReleaseGuard`, `fetchRunnerAvailability`, and the optional `security_keywords` check determine whether an update should proceed and which version to target.
11+
5. **Rewrite + dry-run** – Version matches are grouped per file and rewritten in-memory (`applyVersionUpdates`) using the same pattern logic from `src/rewriter`. When `dry_run` or `use_external_pr_action` is enabled, the action exits before touching the workspace after emitting the change summary.
12+
6. **Git + PR automation** – When allowed, `src/git/branch.ts` creates (or fast-forwards) `chore/bump-python-<track>`, stages targeted files, commits, pushes with `--force-with-lease`, and `src/git/pull-request.ts` uses Octokit + throttling to create or update the pull request. `src/pr-body.ts` renders the pull request template and embeds workflow permission warnings.
13+
14+
## Module Breakdown
15+
16+
### Input Surface
17+
18+
- `src/config.ts` validates the `track` input with zod to prevent misconfigured minors.
19+
- `resolvePathsInput`, `resolveSecurityKeywords`, and snapshot loaders inside `src/index.ts` normalize user-provided multiline inputs and optional offline fixtures (`CPYTHON_TAGS_SNAPSHOT`, `PYTHON_ORG_HTML_SNAPSHOT`, `RUNNER_MANIFEST_SNAPSHOT`, `RELEASE_NOTES_SNAPSHOT`).
20+
- `parseRepository` defends against malformed `GITHUB_REPOSITORY` values so the action can still run in forks/local contexts.
21+
22+
### Scanning + Pattern System
23+
24+
- `discoverFiles` (`src/scanning/glob-discovery.ts`) wraps `fast-glob` with default ignores (`node_modules`, `.git`, `dist`).
25+
- `pythonVersionPatterns` (`src/scanning/patterns/python-version.ts`) is a curated set of detectors for GitHub workflow YAML, Dockerfiles, `.python-version`, `.tool-versions`, `runtime.txt`, `pyproject.toml`, `tox.ini`, `Pipfile`, and Conda `environment.(yml|yaml)`. Each pattern defines `isFileSupported` to avoid unnecessary regex work.
26+
- `findPythonVersionMatches` enforces `X.Y.Z` shape, captures track metadata, guards against `X.Y.Z.W` false positives, and records a byte index used later for precise rewrites.
27+
- `determineSingleTrack` (`src/scanning/track-alignment.ts`) ensures all matches live on a single `X.Y` minor before proceeding. Conflicts bubble up as a skip reason.
28+
29+
### Version Resolution
30+
31+
- `resolveLatestPatch` (`src/versioning/latest-patch-resolver.ts`) prefers GitHub tags for accuracy and returns `{version, tagName, commitSha}`. It reuses `fetchStableCpythonTags` from `src/github/cpython-tags.ts`, which streams paginated tags and filters out pre-releases using semver.
32+
- `fetchLatestFromPythonOrg` (`src/versioning/python-org-fallback.ts`) scrapes python.org release listings as a backup when GitHub data is missing or offline snapshots are provided.
33+
- `enforcePreReleaseGuard` rejects `rc`, `a`, or `b` builds unless `include_prerelease` is true.
34+
- `fetchReleaseNotes` (`src/versioning/release-notes.ts`) pulls the GitHub release body for the resolved tag so `security_keywords` can gate the upgrade.
35+
- `fetchRunnerAvailability` (`src/versioning/runner-availability.ts`) loads the canonical `actions/python-versions` manifest (or a snapshot) and ensures Ubuntu, macOS, and Windows runners all publish the requested patch.
36+
37+
### Rewrite + Idempotence
38+
39+
- `applyVersionUpdates` in `src/action-execution.ts` performs in-place replacements by walking matches in reverse index order.
40+
- The `src/rewriter` module also exposes `computePatch`, `runDryRun`, and `evaluateIdempotence` for future CLI usage and is exercised directly in `tests/patch.test.ts`, `tests/dry-run.test.ts`, and `tests/idempotence.test.ts`.
41+
42+
### Git + Pull Requests
43+
44+
- Branch management is encapsulated in `src/git/branch.ts`. The helper stages only targeted files, reuses existing branches, and respects custom git author identity via environment overrides.
45+
- `src/git/pull-request.ts` centralizes Octokit usage with the throttling plugin to gracefully retry on rate limits. Both listing (idempotence) and create/update code paths share this client.
46+
- `generatePullRequestBody` (`src/pr-body.ts`) emits a deterministic Markdown body detailing files changed, workflow permission warnings, and rollback instructions.
47+
48+
### Dependency Injection Layer
49+
50+
`executeAction` receives a `dependencies` object so tests (and future alternative entry points) can replace any external integration (file IO, network calls, Octokit). Production runs build this via `buildDependencies()` in `src/index.ts`.
51+
52+
## Offline & Snapshot Mode
53+
54+
The action can operate without outbound network access by providing snapshots through environment variables:
55+
56+
- `CPYTHON_TAGS_SNAPSHOT` – JSON array of `{tagName, version, commitSha}` objects used by `resolveLatestPatch`.
57+
- `PYTHON_ORG_HTML_SNAPSHOT` – HTML blob fed to the python.org fallback parser.
58+
- `RUNNER_MANIFEST_SNAPSHOT` – JSON manifest mirroring `actions/python-versions`.
59+
- `RELEASE_NOTES_SNAPSHOT` – object mapping tag or version strings to release note text.
60+
- `NO_NETWORK_FALLBACK=true` – forces every dependency to rely solely on the snapshots and surfaces explicit errors when a required snapshot is missing.
61+
62+
## Skip Reasons & Guardrails
63+
64+
`executeAction` returns either `SuccessResult` or `SkipResult`. Skip reasons map 1:1 with user-facing log statements and the troubleshooting guide:
65+
66+
- `no_matches_found`, `multiple_tracks_detected`
67+
- `pre_release_guarded`, `security_gate_blocked`
68+
- `runners_missing`, `workflow_permission_required`
69+
- `already_latest`
70+
- `pr_exists`, `pr_creation_failed`
71+
72+
Each skip attaches structured `details` so downstream jobs can branch on `skipped_reason` or inspect JSON logs.
73+
74+
## External PR Mode Caveat
75+
76+
Setting `use_external_pr_action=true` currently short-circuits after the scan and returns a dry-run style response without touching the workspace. This is useful for inspection jobs but does **not** yet emit branch/title/body outputs. Do not enable it if you rely on this action to author commits.

0 commit comments

Comments
 (0)