# Releasing Furoshiki to PyPI

Automated publishing runs on every push to **`main`**, but only uploads when the version in **`pyproject.toml`** is **not** already on PyPI.

## Maintainer checklist (each release)

1. Bump **`version`** in [`pyproject.toml`](../pyproject.toml) (single source of truth).
2. Open a PR → wait for **CI** (`.github/workflows/ci.yml`) to pass.
3. Merge to **`main`**.
4. **Release to PyPI** workflow runs:
   - runs tests
   - checks PyPI for that version
   - builds wheel + sdist and publishes if the version is new
5. Verify: `pip install -U furoshiki` and `furoshiki --help`.

Doc-only merges without a version bump do **not** republish (version check skips upload).

## One-time setup (repository owner)

### 1. PyPI Trusted Publishing (recommended)

On [pypi.org](https://pypi.org) → project **furoshiki** → **Publishing** → **Add a new pending publisher**:

| Field | Value |
|--------|--------|
| PyPI project name | `furoshiki` |
| Owner | `bvelasquez` |
| Repository name | `furoshiki` |
| Workflow name | `release.yml` |
| Environment name | `pypi` |

Save the publisher, then merge these workflow files to `main` so PyPI can verify the link.

**Alternative:** classic API token → GitHub repo secret `PYPI_API_TOKEN` and add to the publish step:

```yaml
with:
  password: ${{ secrets.PYPI_API_TOKEN }}
```

(OIDC is preferred; no long-lived token.)

### 2. GitHub Environment `pypi` (optional but recommended)

**Settings → Environments → New environment** → name: `pypi`

- Optional: **Required reviewers** so publishes need approval.
- The publish job in `.github/workflows/release.yml` uses `environment: pypi`.

If you skip creating the environment, either remove `environment: pypi` from the workflow or GitHub will create it on first run.

### 3. Branch protection (recommended)

On **`main`**:

- Require status check **CI / test** before merge.
- Optionally require **Release to PyPI** only after merge (it runs post-merge).

### 4. TestPyPI (optional dry run)

Duplicate trusted publisher on [test.pypi.org](https://test.pypi.org) and a separate workflow or manual `workflow_dispatch` job if you want pre-production uploads.

## Workflows

| File | Trigger | Purpose |
|------|---------|---------|
| `.github/workflows/ci.yml` | PR + push to `main` | Tests on Python 3.11 and 3.12; smoke `python -m build` on 3.12 |
| `.github/workflows/release.yml` | Push to `main`, manual | Test → version check → publish to PyPI |

## Manual publish (fallback)

```bash
python -m pip install build twine
python -m build
twine upload dist/*
```

## After publish (operators)

Installing the package does not restart a running instance:

```bash
pip install -U furoshiki
furoshiki restart brain
```
