Stitch any CI into Tangled
2

Configure Feed

Select the types of activity you want to include in your feed.

1# tack - Connect Tangled to your CI 2 3Tack is a custom [Tangled](https://tangled.org) spindle that runs 4CI on alternate providers and reports their results back 5to Tangled using standard ATProto records so they show up natively 6in Tangled's UI. 7 8> [!WARNING] 9> 10> **Project status:** Tack is early and experimental software. 11> This repo itself uses Tack and I (mitchellh) use Tack for my projects, 12> but it is still new and relatively unproven. 13 14## Example 15 16A Tangled workflow that fires a Buildkite pipeline on every push to 17`main` and every pull request targeting `main`: 18 19```yaml 20# .tangled/workflows/ci.yml 21when: 22 - event: ["push"] 23 branch: ["main"] 24 - event: ["pull_request"] 25 branch: ["main"] 26 27# this does nothing for Tack but is required by Tangled 28engine: nixery 29 30tack: 31 buildkite: 32 pipeline: my-app-ci 33``` 34 35The `when:` block is the standard Tangled trigger schema; the 36`tack:` block tells tack which Buildkite pipeline to fire and how. 37See [docs/buildkite.md](docs/buildkite.md) for the full set of 38options and end-to-end Buildkite setup. Tack can support multiple 39providers. 40 41## How it Works 42 43Tack is a drop-in alternative to the stock `spindle` runner. You run 44`tack` and [register it using the standard UI](https://tangled.org/settings/spindles). 45 46Instead of executing workflows in local containers, tack translates each 47Tangled pipeline trigger into a 3rd party CI build, and reports build state 48back to Tangled using the existing `sh.tangled.pipeline.status` wire format. 49 50This makes even 3rd party CIs integrate first class into Tangled so their 51status, counts, etc. can show up inline in things like pull requests. 52 53``` 54 Jetstream Knot /events (WebSocket) 55 sh.tangled.repo sh.tangled.pipeline triggers 56 sh.tangled.spindle.member 57 sh.tangled.repo.collaborator 58 │ │ 59 │ (discover knots │ 60 │ + membership) │ 61 ▼ ▼ 62 ╭────────────────────────────────╮ 63 │ tack │ 64 │ ╭──────────────────────────╮ │ 65 │ │ provider router │ │ selected per-workflow 66 │ │ (fake │ buildkite) │ │ via `tack: { … }` YAML 67 │ ╰──────────────────────────╯ │ 68 ╰────────────────────────────────╯ 69 70 │ Create Build (REST) 71 72 Buildkite 73 74 │ POST /webhooks/buildkite 75 76 tack ──── /events (WebSocket) ────▶ Tangled appview 77 sh.tangled.pipeline.status 78``` 79 80## Configuration 81 82Core configuration controls how tack talks to Tangled. Provider-specific 83configuration (e.g. Buildkite) lives in its own section below. 84 85### Required 86 87| Env var | Description | 88| ---------------- | ----------------------------------------------------------- | 89| `TACK_HOSTNAME` | This spindle's hostname (matches `sh.tangled.repo.spindle`) | 90| `TACK_OWNER_DID` | DID of the spindle operator | 91 92### Optional 93 94| Env var | Description | 95| -------------------- | -------------------------------------------------------- | 96| `TACK_LISTEN_ADDR` | HTTP listen address (default `:8080`) | 97| `TACK_DB_PATH` | Local SQLite path (default `tack.db`) | 98| `TACK_JETSTREAM_URL` | Tangled Jetstream WebSocket URL | 99| `TACK_DEV` | Use `ws://` for knot event-streams (any non-empty value) | 100 101All configured providers are active simultaneously. Each workflow 102chooses its provider via the first key under its top-level `tack:` 103block. e.g. `tack: { buildkite: { ... } }` runs on Buildkite, 104`tack: { fake: {} }` runs on the in-process fake provider. 105 106## Providers 107 108Provider-specific setup (Buildkite-side configuration, the 109provider's tack env vars, and the workflow YAML schema) lives in 110its own doc per provider: 111 112* [Buildkite](docs/buildkite.md)