# publish


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Building blocks

Three small helpers the loop is assembled from:
[`_run`](https://drscotthawley.github.io/slmn/publish.html#_run) (run an
argv list – never a shell string, so no quoting/injection surface),
[`_confirm`](https://drscotthawley.github.io/slmn/publish.html#_confirm)
(the proceed gate – see below), and
[`_wait_for_ci`](https://drscotthawley.github.io/slmn/publish.html#_wait_for_ci)
(block on the GitHub Actions run for a pushed commit, via `gh`).

[`_confirm`](https://drscotthawley.github.io/slmn/publish.html#_confirm)
is the interesting one: it prints `git status` and then, on an
interactive terminal, prompts `[Y/n]`; on a non-TTY (a background or
agent-driven call) it instead stops and returns without prompting, so
the caller reads the printed status and re-invokes with `yes=True`. The
one gate thus serves as both a human confirmation and an agent’s
read-and-authorize handoff.

## The publish loop

[`publish`](https://drscotthawley.github.io/slmn/publish.html#publish)
strings the pieces together: run `prebuild` (nbdev-clean + nbdev-export
by default), show status and gate on it, commit and push, wait for CI,
and – on a feature branch with a green run – open and merge a PR to
main, leaving you on an updated local main. Every step is blocking and
stop-on-error; run
[`publish`](https://drscotthawley.github.io/slmn/publish.html#publish)
itself in the background if you don’t want to wait on CI. It knows
nothing about nbdev specifically – that’s just the default `prebuild`,
so the same loop works for a plain Python project.

------------------------------------------------------------------------

<a
href="https://github.com/drscotthawley/slmn/blob/main/slmn/publish.py#L69"
target="_blank" style="float:right; font-size:smaller">source</a>

### publish

``` python
def publish(
    msg:str=None, # commit message; required only if there are changes to commit (prompted for on an interactive TTY if omitted). Ignored when the branch is already committed and just being shipped.
    prebuild:list=None, # shell commands to run before committing (regenerate build artifacts, run local checks, ...). Defaults to nbdev's ['nbdev-clean', 'nbdev-export', 'nbdev-readme'] (the last regenerates README.md from nbs/index.ipynb -- without it, index edits never reach the README); pass [] to skip, or e.g. ['ruff check .', 'pytest -q'] for a non-nbdev project. This venv's bin/ is prepended to PATH so bare tool names resolve to the project's own venv.
    dests:list=None, # publish destinations; only 'github' is implemented so far (pypi/conda later). Defaults to ['github'].
    merge:bool=True, # when on a non-main branch and CI passes, open a PR to main and merge it
    wait_ci:bool=True, # after pushing, wait for GitHub Actions to finish (forced on when a merge is needed -- a merge can't be gated without it)
    ci_timeout:int=120, # seconds to wait for the CI run to REGISTER after pushing before giving up (see _wait_for_ci); the run itself is then waited on for as long as it takes
    merge_method:str='merge', # how gh merges the PR: 'merge' | 'squash' | 'rebase'
    yes:bool=False, # skip the proceed prompt (the -y override); on a non-TTY without it, publish stops after showing git status so the caller can review and re-invoke
    cwd:str=None, # repo directory (default: current directory)
)->str:
```

\*Automate the edit-\>ship loop. In order: run `prebuild` (default
nbdev-clean + nbdev-export + nbdev-readme), show `git status` and gate
on it (see \_confirm – interactive prompt, or read-and-authorize for an
agent), git add -u, commit (skipped if nothing staged), push; then for a
‘github’ dest wait for CI (see \_wait_for_ci), and if it passes while
you’re on a non-main branch with merge=True, open a PR to main and merge
it (merge_method), then leave you on an updated local main. Everything
runs blocking/stop-on-error (don’t proceed if a step failed) – run
publish itself in the background if you don’t want to wait on CI.
Progress is printed live; the returned string is a short final outcome.
Only tracked files are staged (git add -u); new/untracked files show in
the status review but aren’t auto-added. If nothing is staged but the
branch already has commits to ship, the commit step is skipped and it
still pushes/CIs/merges. Knows nothing about nbdev specifically – that’s
just the default prebuild.\*
