Skip to content
Open
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
48 changes: 29 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

watch a pipeline. rip it. ding when done.

works with **gitlab pipelines** and **gitea actions** (auto-detected).

```
$ bong
14:02:11 watching pipeline #987654 (root status: running)
Expand All @@ -19,15 +21,14 @@ $ bong
↑ second notification fires here
```

one bash file. zero deps beyond `glab`. mac + linux. caveman tier.
one bash file. zero deps beyond `glab` (gitlab) or `curl` (gitea). mac + linux. caveman tier.

## install

prereq — install [`glab`](https://gitlab.com/gitlab-org/cli) and log in once:
prereq:

```sh
glab auth login
```
- **gitlab** — install [`glab`](https://gitlab.com/gitlab-org/cli) and log in once: `glab auth login`
- **gitea** — `curl` (already there) plus `GITEA_TOKEN` for private repos. host is auto-detected from your `origin` remote.

then drop `bong` somewhere on your `$PATH`:

Expand All @@ -40,17 +41,20 @@ sudo install -m 0755 bong /usr/local/bin/bong
## use

```sh
bong # latest pipeline on current branch (run from inside the repo)
bong 1234567 # by pipeline id (uses current repo for project context)
bong https://gitlab.com/foo/bar/-/pipelines/1234567 # by url — works from anywhere, including cross-project
bong # latest pipeline / run on current branch
bong 1234567 # by id (uses current repo for context)
bong https://gitlab.com/foo/bar/-/pipelines/1234567 # gitlab url — works from anywhere
bong https://codeberg.org/foo/bar/actions/runs/77 # gitea url — host comes from the url
```

what it does, every `BONG_POLL` seconds:

1. polls the pipeline you pointed it at
2. discovers any downstream / triggered child pipelines via the `bridges` api and adds them to the watch
3. fires a desktop notification + bell on **any** pipeline hitting `manual` (it'll keep watching after you trigger it)
4. exits when the whole tree is done. **`0`** if every pipeline ended `success`/`skipped`. **`1`** if any ended `failed`/`canceled`. final desktop notification + bell on the way out.
1. polls the pipeline / workflow run you pointed it at
2. **gitlab only:** discovers any downstream / triggered child pipelines via the `bridges` api and adds them to the watch
3. **gitlab only:** fires a desktop notification + bell on **any** pipeline hitting `manual` (it'll keep watching after you trigger it)
4. exits when everything is done. **`0`** if all ended `success`/`skipped`. **`1`** if any ended `failed`/`canceled`. final desktop notification + bell on the way out.

gitea actions has no `bridges`-equivalent and no `manual` gate, so on gitea bong watches just the one run.

so you can chain:

Expand All @@ -64,11 +68,16 @@ ctrl-c to stop watching at any time.

env vars (also see `.env.example`):

| var | default | what |
|------------|---------|-----------------------|
| `BONG_POLL` | `10` | seconds between polls |
| var | default | what |
|-----------------|---------------------------|-----------------------------------------------------------------|
| `BONG_POLL` | `10` | seconds between polls |
| `BONG_PROVIDER` | _auto_ | force `gitlab` or `gitea` (else inferred from url / git remote) |
| `GITEA_HOST` | _from `origin` remote_ | gitea base url, e.g. `https://codeberg.org` |
| `GITEA_TOKEN` | _none_ | gitea api token; required for private repos |

provider is auto-detected: url shape wins (`/-/pipelines/` → gitlab, `/actions/runs/` → gitea), then your `origin` remote host (`gitlab*` / `codeberg.org` / `*gitea*`), else gitlab.

`glab` itself handles auth / token / instance host — `bong` doesn't need any of that.
`glab` handles auth for gitlab. for gitea, set `GITEA_TOKEN` (you can scope it to read-only access on the repo).

## notifications

Expand All @@ -82,7 +91,8 @@ if you're on a headless box, the bell is all you'll get — that's fine, exit co

## how it works (briefly)

- pipeline tree state lives in parallel bash arrays keyed by globally-unique pipeline id; we map id → project id so cross-project downstreams just work.
- json parsing is `grep`/`sed` — no `jq` dep. only the few fields we need (`id`, `project_id`, `status`, `web_url`).
- pipeline tree state lives in parallel bash arrays keyed by globally-unique run id; we map id → project (numeric for gitlab, `owner/repo` for gitea) so cross-project downstreams (gitlab) just work.
- json parsing is `grep`/`sed` — no `jq` dep. only the few fields we need (`id`, `project_id`, `status`, `web_url`/`html_url`).
- gitea statuses (`failure`/`cancelled`/`in_progress`/`waiting`/`queued`) are normalized to gitlab vocabulary (`failed`/`canceled`/`running`/`pending`) so the main loop stays provider-agnostic.
- `manual` is treated as "stuck waiting on a human" — notify once, keep polling. only `success`/`failed`/`canceled`/`skipped` are terminal for exit.
- the script polls `glab api` directly rather than `glab ci ...` text output, since the json shape is more stable than the cli's pretty-printing.
- gitlab path uses `glab api`; gitea path uses `curl` against `/api/v1/repos/{owner}/{repo}/actions/runs[/{id}]`. json shape is stabler than either cli's pretty-printing.
Loading