···1919consistently topped our feature request list. Today, CI is
2020no longer a wishlist item, but a fully-featured reality.
21212222-Meet **spindle**: Tangled's new CI runner that brings powerful automation
2323-directly to your repositories. In typical Tangled fashion we've been dogfooding
2424-spindle for a while now; this very blog post you're reading was [built and
2525-published using spindle](link to CI run here).
2222+Meet **spindle**: Tangled's new CI runner built atop Nix and
2323+AT Protocol. In typical Tangled fashion we've been
2424+dogfooding spindle for a while now; this very blog post
2525+you're reading was [built and published using spindle](link
2626+to CI run here).
26272728
28292930## how spindle works
30313131-Spindle is designed around simplicity and the decentralized nature of the AT
3232-Protocol. Here's the flow: when you push code or open a pull request, the knot
3333-hosting your repository emits a pipeline event (`sh.tangled.pipeline`). Running
3434-as a dedicated service, spindle subscribes to these events via websocket
3535-connections to your knot.
3232+Spindle is designed around simplicity and the decentralized
3333+nature of the AT Protocol. In ingests "pipeline" records and
3434+emits job status updates.
36353737-Once triggered, spindle reads your pipeline manifest, spins up the necessary
3838-execution environment (covered below), and runs your defined workflow steps.
3939-Throughout execution, it streams real-time logs and status updates
4040-(`sh.tangled.pipeline.status`) back through websockets, which the Tangled
4141-appview subscribes to for live updates.
3636+When you push code or open a pull request, the knot hosting
3737+your repository emits a pipeline event
3838+(`sh.tangled.pipeline`). Running as a dedicated service,
3939+spindle subscribes to these events via websocket connections
4040+to your knot.
42414343-This architecture keeps everything responsive and real-time while maintaining
4444-the distributed spirit that makes Tangled unique.
4242+Once triggered, spindle reads your pipeline manifest, spins
4343+up the necessary execution environment (covered below), and
4444+runs your defined workflow steps. Throughout execution, it
4545+streams real-time logs and status updates
4646+(`sh.tangled.pipeline.status`) back through websockets,
4747+which the Tangled appview subscribes to for live updates.
4848+4949+Over at the appview, these updates are ingested and stored,
5050+and logs are streamed live.
45514652## spindle pipelines
47534848-The pipeline manifest is defined in YAML, and should be relatively familiar to
4949-those that have used other CI solutions. Here's a minimal example:
5454+The pipeline manifest is defined in YAML, and should be
5555+relatively familiar to those that have used other CI
5656+solutions. Here's a minimal example:
50575158```yaml
5259# test.yaml
···83908491[^1]: I mean, if it isn't there, it's nowhere.
85928686-Finally, define your steps, necessary environment variables and commands.
8787-Commands can be multi-lined. Let's take a look at how spindle executes workflow
8888-steps.
9393+Workflow manifests are intentionally simple. We do not want
9494+to include a "marketplace" of workflows or complex job
9595+orchestration. The bulk of the work should be offloaded to a
9696+build system, and CI should be used simply for finishing
9797+touches. That being said, this is still the first revision
9898+for CI, there is a lot more on the roadmap!
9999+100100+Let's take a look at how spindle executes workflow steps.
8910190102## workflow execution
911039292-At present, the spindle "engine" supports just the Docker backend[^2]. Podman is
9393-known to work with the Docker socket feature enabled. Each step is run in a
9494-separate container, with the `/tangled/workspace` and `/nix` volumes persisted
104104+At present, the spindle "engine" supports just the Docker
105105+backend[^2]. Podman is known to work with the Docker socket
106106+feature enabled. Each step is run in a separate container,
107107+with the `/tangled/workspace` and `/nix` volumes persisted
95108across steps.
961099797-[^2]: Support for additional backends like Firecracker are planned.
9898-Contributions welcome!
110110+[^2]: Support for additional backends like Firecracker are
111111+ planned. Contributions welcome!
99112100100-The container image is built using [Nixery](https://nixery.dev). Nixery is a
101101-nifty little tool that takes a path-separated set of Nix packages and returns an
102102-OCI image with each package in a separate layer. Try this in your terminal if
103103-you've got Docker installed:
113113+The container image is built using
114114+[Nixery](https://nixery.dev). Nixery is a nifty little tool
115115+that takes a path-separated set of Nix packages and returns
116116+an OCI image with each package in a separate layer. Try this
117117+in your terminal if you've got Docker installed:
104118105119```
106120docker run nixery.dev/bash/hello-go hello
···160174161175## pipeline secrets
162176163163-Secrets are a bit tricky since atproto has no notion of private data. Secrets
164164-are instead written directly from the appview to the spindle instance using
165165-[service
166166-auth](https://docs.bsky.app/docs/api/com-atproto-server-get-service-auth). In
167167-essence, the appview makes a signed request using the logged-in user's DID key;
168168-spindle verifies this signature by fetching the public key from the DID
169169-document.
177177+Secrets are a bit tricky since atproto has no notion of
178178+private data. Secrets are instead written directly from the
179179+appview to the spindle instance using [service
180180+auth](https://docs.bsky.app/docs/api/com-atproto-server-get-service-auth).
181181+In essence, the appview makes a signed request using the
182182+logged-in user's DID key; spindle verifies this signature by
183183+fetching the public key from the DID document.
170184171185
172186···179193180194## get started now
181195182182-You can run your own spindle instance pretty easily: the [spindle self-hosting
196196+You can run your own spindle instance pretty easily: the
197197+[spindle self-hosting
183198guide](https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md)
184184-should have you covered. Once done, head to your repository's settings tab and
185185-set it up! Doesn't work? Feel free to pop into
186186-[Discord](https://chat.tangled.sh) to get help -- we have a nice little crew
187187-that's always around to help.
199199+should have you covered. Once done, head to your
200200+repository's settings tab and set it up! Doesn't work? Feel
201201+free to pop into [Discord](https://chat.tangled.sh) to get
202202+help -- we have a nice little crew that's always around to
203203+help.
188204189189-All Tangled users have access to our hosted spindle instance, free of
190190-charge[^3]. You don't have any more excuses to not migrate to Tangled now --
191191-[get started](https://tangled.sh/login) with your AT Protocol account today.
205205+All Tangled users have access to our hosted spindle
206206+instance, free of charge[^3]. You don't have any more
207207+excuses to not migrate to Tangled now -- [get
208208+started](https://tangled.sh/login) with your AT Protocol
209209+account today.
192210193193-[^3]: We can't promise we won't charge for it at some point but there will
194194- always be a free tier.
211211+[^3]: We can't promise we won't charge for it at some point
212212+ but there will always be a free tier.