Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Documentation

on:
push:
branches:
- main
paths:
- "README.md"
- "SECURITY.md"
- "docs/**"
- "mkdocs.yml"
- "pyproject.toml"
- "scripts/validate_docs.py"
- "tests/validate.sh"
- ".github/workflows/docs.yml"
pull_request:
paths:
- "README.md"
- "SECURITY.md"
- "docs/**"
- "mkdocs.yml"
- "pyproject.toml"
- "scripts/validate_docs.py"
- "tests/validate.sh"
- ".github/workflows/docs.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build and validate documentation
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check out source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.13"

- name: Install documentation tools
run: python -m pip install ".[docs]"

- name: Validate repository links and examples
run: python scripts/validate_docs.py

- name: Build documentation with strict warnings
run: python -m mkdocs build --strict --site-dir site

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
with:
path: site

deploy:
name: Deploy documentation site
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
permissions:
pages: write
id-token: write
steps:
- name: Configure GitHub Pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@f33f41b675f0ab2dc5a6863c9a170fe83af3571e # v4.0.0
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ the API stability policy and migration guide before upgrading from `0.3.x`.

## [Unreleased]

### Added

- Add the MkDocs documentation site configuration, strict documentation checks,
and GitHub Pages deployment workflow.

### Changed

- Reclassify the project as Beta in package metadata to reflect its documented
Expand Down
33 changes: 18 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Install it with:
python -m pip install base-cli
```

Read the complete documentation at
<https://basefoundry.github.io/base-cli/>.

## Quick start

Create a small command with a consistent context, logging, and cleanup
Expand Down Expand Up @@ -47,7 +50,7 @@ Run it with `python hello.py --name Ada`. The full lifecycle and configuration
options are documented below.

Release builds, TestPyPI rehearsals, and protected PyPI publication are
documented in [`docs/releasing.md`](docs/releasing.md). The package exposes
documented in [`docs/releasing.md`](https://basefoundry.github.io/base-cli/releasing/). The package exposes
`base_cli.__version__`, which matches the distribution version.

The package is distributed under the Apache License 2.0. Base itself remains
Expand All @@ -71,33 +74,33 @@ execution, while `base_cli` provides reusable lifecycle behavior:
- test helpers built on Click's `CliRunner`

Typer applications can opt into the same lifecycle with the optional
`base-cli[typer]` extra. See [`docs/typer-adapter.md`](docs/typer-adapter.md)
`base-cli[typer]` extra. See [`docs/typer-adapter.md`](https://basefoundry.github.io/base-cli/typer-adapter/)
for the migration path; Typer remains optional and is never imported by the
core Click integration.

Automation-facing JSON output, errors, and logs are opt-in through the
versioned contracts documented in [`docs/json-contracts.md`](docs/json-contracts.md).
versioned contracts documented in [`docs/json-contracts.md`](https://basefoundry.github.io/base-cli/json-contracts/).
Human output and Click error behavior remain the default.

The supported public facade, compatibility promises, deprecation warning
mechanism, and migration requirements are documented in
[`docs/api-stability.md`](docs/api-stability.md) and
[`docs/migrations.md`](docs/migrations.md).
[`docs/api-stability.md`](https://basefoundry.github.io/base-cli/api-stability/) and
[`docs/migrations.md`](https://basefoundry.github.io/base-cli/migrations/).

Security reporting, runtime trust boundaries, threat assumptions, and the
release security checklist are documented in [`SECURITY.md`](SECURITY.md),
[`docs/security-threat-model.md`](docs/security-threat-model.md), and
[`docs/security-review.md`](docs/security-review.md).
[`docs/security-threat-model.md`](https://basefoundry.github.io/base-cli/security-threat-model/), and
[`docs/security-review.md`](https://basefoundry.github.io/base-cli/security-review/).

Shared record renderers keep machine output stable: CSV and TSV stream
one-pass iterables without headers or footers, while terminal tables account
for Unicode display width and safely truncate oversized cells. See
[`docs/output-contracts.md`](docs/output-contracts.md) for the output rules and
[`docs/output-contracts.md`](https://basefoundry.github.io/base-cli/output-contracts/) for the output rules and
deterministic width controls.

Optional Rich tables and OpenTelemetry lifecycle spans are available through
separate extras; they are never imported or required by the default install.
See [`docs/integrations.md`](docs/integrations.md) for opt-in configuration and
See [`docs/integrations.md`](https://basefoundry.github.io/base-cli/integrations/) for opt-in configuration and
graceful-degradation behavior.

## Design Goals
Expand Down Expand Up @@ -141,7 +144,7 @@ The generic profile has no manifest filename convention, no product-owned
configuration directory, and no implicit history writer. Applications can
provide those policies through callbacks or build their own profile. The
consumer-owned adapters should supply any product-specific policies. See
[`docs/consumer-profiles.md`](docs/consumer-profiles.md) for the boundary and
[`docs/consumer-profiles.md`](https://basefoundry.github.io/base-cli/consumer-profiles/) for the boundary and
migration guidance.

### Typed extension contracts
Expand Down Expand Up @@ -190,7 +193,7 @@ can opt into `base_cli.ExtensionDiscovery`. It recognizes the documented
`base_cli.commands`, `base_cli.profiles`, and `base_cli.plugins` entry-point
groups. Discovery is lazy and cached, duplicate names fail explicitly, broken
extensions are isolated by `load_all()`, and consumers can disable discovery or
provide an allowlist. See [`docs/extensions.md`](docs/extensions.md) for the
provide an allowlist. See [`docs/extensions.md`](https://basefoundry.github.io/base-cli/extensions/) for the
entry-point contracts and deterministic ordering rules.

## Public API
Expand All @@ -199,7 +202,7 @@ The supported facade is `import base_cli`. It exports the command lifecycle
(`App`, `Context`, `run_app`, decorators, and logging helpers), command filters,
and the structured command protocol helpers. Consumer-owned user configuration
is passed through `Context.user_config`; the library does not impose a schema.
See [`docs/user-config-typing.md`](docs/user-config-typing.md) for the
See [`docs/user-config-typing.md`](https://basefoundry.github.io/base-cli/user-config-typing/) for the
intentional opaque boundary and the recommended typed accessor pattern.
The corresponding modules are also available as
`base_cli.command_filters`, `base_cli.command_protocol`, and
Expand Down Expand Up @@ -230,7 +233,7 @@ Typer, and automation/observability flows; each example has its own packaging,
tests, completion, release, and troubleshooting guidance.

Teams evaluating adoption can follow the [adopter readiness and migration
guide](docs/adopter-readiness.md) and run the three independent
guide](https://basefoundry.github.io/base-cli/adopter-readiness/) and run the three independent
[downstream compatibility consumers](compatibility/README.md).

## Minimal Command
Expand Down Expand Up @@ -538,7 +541,7 @@ Every `base_cli.App` command gets these options:
- `--log-file <path>`: write the persistent log to a specific file.
- `--version`: shown when the `App` was created with a version.
- `--json`: opt-in machine output, when `LifecycleOptions.json` is enabled;
emits the versioned envelopes described in [`docs/json-contracts.md`](docs/json-contracts.md).
emits the versioned envelopes described in [`docs/json-contracts.md`](https://basefoundry.github.io/base-cli/json-contracts/).

`LifecycleOptions()` preserves this default set. Its `debug`, `quiet`,
`environment`, `config`, `keep_temp`, `log_file`, and `version` fields are
Expand Down Expand Up @@ -986,7 +989,7 @@ On POSIX, base-cli enforces owner-only `0600`/`0700` modes. On Windows, the
default user-local cache root relies on inherited user-profile ACLs; consumers
using a custom cache root must provide the appropriate ACL themselves.

See [Platform support](docs/platform-support.md) for the supported Linux,
See [Platform support](https://basefoundry.github.io/base-cli/platform-support/) for the supported Linux,
WSL2, macOS, and native Windows boundaries. Native Windows support covers the
generic `base-cli` framework; it does not imply native Windows support for
Base or `basectl`.
Expand Down
8 changes: 4 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

`base-cli` is a library for embedding a lifecycle into Python command-line
applications. We take reports about the framework, its release artifacts, and
the security controls documented in the [runtime threat model](docs/security-threat-model.md)
the security controls documented in the [runtime threat model](https://basefoundry.github.io/base-cli/security-threat-model/)
seriously.

## Reporting a vulnerability
Expand Down Expand Up @@ -40,7 +40,7 @@ changes the supported window will update this table and the changelog.
| `main` | Supported for fixes merged before the next release |
| `<0.3` | Upgrade strongly recommended; best effort only |

The [API stability policy](docs/api-stability.md) explains the pre-1.0
The [API stability policy](https://basefoundry.github.io/base-cli/api-stability/) explains the pre-1.0
compatibility boundary. A security fix may require an emergency breaking
change when leaving a vulnerable behavior in place would expose users.

Expand Down Expand Up @@ -68,6 +68,6 @@ The framework protects the lifecycle data it owns: argv redaction, private
runtime files, fail-closed temporary cleanup, bounded JSON contracts, and
opt-in telemetry with a safe attribute set. It does not sandbox consumer
callbacks, third-party plugins, Python dependencies, shell commands, or the
operating system. Consumers must review the [threat model](docs/security-threat-model.md)
and complete the [security review checklist](docs/security-review.md) for their
operating system. Consumers must review the [threat model](https://basefoundry.github.io/base-cli/security-threat-model/)
and complete the [security review checklist](https://basefoundry.github.io/base-cli/security-review/) for their
own profile, plugins, paths, history writer, and telemetry exporter.
8 changes: 4 additions & 4 deletions docs/adopter-readiness.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ box below:
- [ ] Publish an owner, escalation path, and a redacted support bundle format.

The maintainable downstream fixtures in
[`compatibility/consumers`](../compatibility/README.md) are the executable
[compatibility consumers](https://github.com/basefoundry/base-cli/tree/main/compatibility/consumers) are the executable
version of this checklist.

## Migration path
Expand Down Expand Up @@ -58,13 +58,13 @@ version of this checklist.

For public API and deprecation rules, see [`api-stability.md`](api-stability.md)
and [`migrations.md`](migrations.md). The four framework reference applications
show copy-pasteable packaging patterns in [`examples/README.md`](../examples/README.md).
show copy-pasteable packaging patterns in the [reference application catalog](https://github.com/basefoundry/base-cli/blob/main/examples/README.md).

## Support channel

Use the repository's [Adoption support issue template](../.github/ISSUE_TEMPLATE/support.md)
Use the repository's [Adoption support issue template](https://github.com/basefoundry/base-cli/blob/main/.github/ISSUE_TEMPLATE/support.md)
for migration questions, compatibility failures, and redacted reproductions.
Security reports must follow [`SECURITY.md`](../SECURITY.md), not a public issue.
Security reports must follow [`SECURITY.md`](https://github.com/basefoundry/base-cli/blob/main/SECURITY.md), not a public issue.
Include the framework version, Python/platform, installed dependency versions,
command shape (with secrets removed), exit code, and a support bundle path.
Maintainers triage adoption issues during normal project work and link any
Expand Down
71 changes: 71 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# base-cli

`base-cli` is a small, consumer-neutral Python framework for writing
professional command-line applications. It gives commands a consistent
lifecycle, context, logging, cleanup, configuration, and test boundary while
leaving application policy in the consuming project.

## Quick start

Install the package:

```bash
python -m pip install base-cli
```

Create a command:

```python
from __future__ import annotations

import base_cli


app = base_cli.App(name="hello", version="0.1.0")


@app.command()
@base_cli.option("--name", default="world", show_default=True)
def hello(ctx: base_cli.Context, name: str) -> int:
ctx.log.info("greeting %s", name)
print(f"Hello, {name}!")
return base_cli.ExitCode.SUCCESS


if __name__ == "__main__":
raise SystemExit(base_cli.run_app(app))
```

Run it with:

```bash
python hello.py --name Ada
```

The command receives a context with structured logging, per-run paths,
configuration, environment metadata, and deterministic cleanup. The same
lifecycle can be attached to an existing Click tree or an optional Typer
application.

## Choose a path

- Start with the [adopter readiness guide](adopter-readiness.md) for a
production evaluation.
- Read [API stability](api-stability.md) and the [migration guide](migrations.md)
before upgrading across a compatibility boundary.
- Follow [consumer profiles](consumer-profiles.md) when your application owns
project discovery or configuration policy.
- Use the [Typer adapter](typer-adapter.md) to bring an existing Typer command
tree under the same lifecycle.
- Review the [JSON contracts](json-contracts.md) and [output contracts](output-contracts.md)
before building automation around command output.

## Design principles

`base-cli` is intentionally thin: Click owns parsing and command execution,
while the framework supplies reusable lifecycle behavior. It avoids import-time
filesystem writes, keeps logs on stderr, preserves application-owned state,
and treats optional integrations as explicit extras.

See the [repository README](https://github.com/basefoundry/base-cli#readme) for
the full API overview, reference applications, and installation examples.
12 changes: 12 additions & 0 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ cleanup.
The publish job downloads that same reviewed artifact; it does not rebuild
during publication.

## Documentation site

The Documentation workflow builds this site with `mkdocs build --strict` and
publishes the reviewed site to GitHub Pages after changes land on `main`. The
canonical URL is <https://basefoundry.github.io/base-cli/> and is exposed in
the PyPI project metadata as the `Documentation` link.

Repository administrators should enable GitHub Pages for the repository using
the GitHub Actions source and approve the `github-pages` environment the first
time the workflow deploys. Pull requests run the strict build and repository
link checks without publishing.

## TestPyPI rehearsal

1. Dispatch **Package** from the branch or tag to be rehearsed and choose
Expand Down
Loading
Loading