Personal blog finxol.io
blog

continue writing tangled setup post

finxol.io c929a7b9 635220b6

verified
+218 -8
+4
app/app.vue
··· 158 158 filter: invert(1); 159 159 } 160 160 161 + details.minor-callout summary { 162 + @apply text-stone-500 px-4 text-base; 163 + } 164 + 161 165 @media print { 162 166 @page { 163 167 size: A4 portrait;
+214 -8
content/posts/0-draft-embracing-atproto-pt-2-tangled-knot.md
··· 3 3 description: | 4 4 You thought Github was a social coding platform? Think again, get ready to tangle! 5 5 Built on atproto, tangled allows you to use your Bluesky identity on a (not quite yet) fully feldged git platform! 6 - date: 2025-09-09 6 + date: 2025-09-15 7 7 authors: 8 8 - name: finxol 9 9 tags: ··· 20 20 Embracing ATProto, part 1: Setting up a PDS 21 21 :: 22 22 23 - The PDS setup was an overall very smooth process. 24 - Bluesky and the AT Protocol are backed and built by a very competent team of well funded engineers for a few years already. 23 + The PDS setup and migration was an overall very smooth process. 24 + Bluesky and the AT Protocol are built by a very competent team of well funded engineers working on it for a few years already. 25 25 26 26 ## What's tangled? 27 27 28 - Tangled, on the other hand, was started only about 8 months ago, at the start of 2025 by [two](https://tangled.sh/@oppi.li) [brothers](https://tangled.sh/@icyphox.sh). 29 - It's a "social-enabled git collaboration platform" 28 + [Tangled](https://tangled.sh), on the other hand, was started only about 8 months ago, at the start of 2025 by [two](https://tangled.sh/@oppi.li) [brothers](https://tangled.sh/@icyphox.sh). 29 + It's a "social-enabled git collaboration platform" built for decentralisation, ownership, and social coding. 30 30 31 31 The platform has gained a lot of traction since, and the community is very much involved in the development, but for now tangled is still in alpha. 32 - That doesn't mean it's not usable yet. 33 - 32 + That doesn't mean it's not usable yet, just that some things may break. 34 33 35 34 ### What's a Knot? 36 35 ··· 39 38 In tangled, a knot is essentially a git server. 40 39 It's sort of like an atproto PDS in the sense that it's where your data—here your code—lives. 41 40 41 + That's the main tangled-specific decentralised part, and what makes tangled special. 42 + You can keep ownership of your code, without cutting it off from a popular git platform by running it on a private Gitea or Gitlab server. 43 + 42 44 ## Setting up a Knot 43 45 44 - ## Setting up a Spindle 46 + Setting up my own knot took a little bit more work than for the PDS. 47 + The [official docs](https://tangled.sh/@tangled.sh/core/blob/master/docs/knot-hosting.md) give instructions for installation on a NixOS system. 48 + 49 + ## Spindles & CI 50 + 51 + Another piece of lingo from the tangled world is "Spindle". 52 + 53 + A Spindle is a very simple CI runner for tangled. 54 + It runs one Docker container per run, and gives access to any Nixpkg. 55 + The syntax is very similar to Github Actions workflow files, with some slight differences. 56 + 57 + Since it's brand new, there isn't access to the thousands of pre-made reusable Github Actions, 58 + but access to the vast nixpkg catalog lets us do basically anything—with a couple extra steps from time to time. 59 + 60 + ### Self-hosting 61 + 62 + As with everything else here, Spindles are self-hostable. 63 + There is a little gotcha for the moment though. 64 + 65 + Since the Spindle runs a Docker container for each workflow run, it needs access to the Docker socket. 66 + They haven't got Docker-in-Docker working quite yet, so it means the Spindle needs to run natively outside a Docker container. 67 + 68 + Although I don't like the idea, it's not really a problem for me. 69 + I prefer to have everything containerised on my servers to keep things tidy, but it's fine as a temporary solution until they get DinD working. 70 + 71 + What's stopping me right now is rather that workflow runs would spin up a Docker container alongside all my other projects I'd rather not break. 72 + I'm aware it shouln't really be a problem, but it just bothers me. 73 + It is very much a me problem, so I'll figure out a way around it eventually. 74 + 75 + ## Migrating this blog 76 + 77 + Migrating the repo over is the simplest things ever. 78 + 79 + Just create a new repo on tangled—selecting your knot—set the remote on your local repo, and push to it! 80 + If you specified the knot correctly when creating your repo, it should now live directly on your Knot. 81 + 82 + <img src="/posts/embracing-atproto-pt2/new-repo.png" alt="Select your new knot when creating a repo" width="80%" style="margin: auto;" /> 83 + 84 + You can now use git just as you normally do! 85 + 86 + ### CI 87 + 88 + Migrating CI takes a tiny bit more work to migrate. 89 + I had a Github Action workflow to automatically deploy this blog to Deno Deploy on push. 90 + 91 + <details class="minor-callout"> 92 + 93 + <summary>Here's the full file if you're curious.</summary> 94 + 95 + ```yaml 96 + name: deno-deploy 97 + on: 98 + push: 99 + branches: 100 + - main 101 + jobs: 102 + deploy: 103 + runs-on: ubuntu-latest 104 + permissions: 105 + id-token: write # Needed for auth with Deno Deploy 106 + contents: read # Needed to clone the repository 107 + steps: 108 + - uses: actions/checkout@v3 109 + 110 + - uses: pnpm/action-setup@v4 111 + name: Install pnpm 112 + with: 113 + run_install: false 114 + 115 + - uses: actions/setup-node@v3 116 + with: 117 + node-version: 22 118 + cache: pnpm 119 + 120 + - run: pnpm install 121 + 122 + - run: pnpm generate 123 + 124 + - name: Deploy to Deno Deploy 125 + uses: denoland/deployctl@v1 126 + with: 127 + project: finxol-blog 128 + entrypoint: https://deno.land/std@0.140.0/http/file_server.ts 129 + root: .output/public 130 + ``` 131 + 132 + </details> 133 + 134 + Let's start off very easy by adapting the triggers. 135 + Just [follow the docs](https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/pipeline.md), and set the same trigger conditions. 136 + 137 + ```yaml 138 + when: 139 + - event: ["push"] 140 + branch: ["main"] 141 + ``` 142 + 143 + I'll have a look at branch deploys later. 144 + It needs a bit more manual work since the official GH Action doesn't do it for us. 145 + 146 + Since spindles work slightly differently to Github Actions runners, we need to give it a list of dependencies to install. 147 + It's similar to the setup steps in the GH workflow to install node and pnpm. 148 + 149 + ```yaml 150 + dependencies: 151 + nixpkgs: 152 + - deno 153 + - nodejs 154 + - pnpm 155 + - python3 156 + - gnused 157 + ``` 158 + 159 + This bit took a bit of trial and error, as you might notice from the `python3` and `gnused` dependencies. 160 + 161 + I'd initially set the dependencies to what I set up in the GH workflow, `nodejs` and `pnpm`, plus `deno` to be able to use the `deployctl` cli tool. 162 + But running that gave a few errors. 163 + This blog uses Nuxt Content to generate HTML from my Markdown files, and Nuxt Content itself uses `better-sqlite3`, which itself needs python and sed in its post-install script. 164 + Adding the corresponding nixpkgs in the dependencies array fixes this easily. 165 + 166 + Now we can get to the actual steps of the workflow. 167 + 168 + Since we don't have access to the existing Github Actions, there's a few sections that needed adapting or manual work. 169 + The install and generate steps are exactly the same, but the deploy step changes. 170 + 171 + To replace the official Deno Deploy GH Action, we can directly use their `deployctl` cli tool, and give it the appropriate parametres. 172 + 173 + I also used this as an excuse to using the `jsr:@std/http/file-server` entrypoint instead of the deno.land url style. 174 + 175 + ```yaml 176 + steps: 177 + - name: Install dependencies 178 + command: | 179 + pnpm install 180 + 181 + - name: Generate static site 182 + command: | 183 + pnpm generate 184 + 185 + - name: Install deployctl 186 + command: | 187 + deno install -gArf jsr:@deno/deployctl 188 + 189 + - name: Deploy to Deno Deploy 190 + command: | 191 + cd .output/public 192 + ~/.deno/bin/deployctl deploy --project finxol-blog --entrypoint jsr:@std/http/file-server --include=. --prod 193 + ``` 194 + 195 + Lastly, don't forget to give the workflow permission to deploy by giving it a `DENO_DEPLOY_TOKEN` in the secrets! 196 + Since Deno Deploy integrates only with Github, the permission won't be given automatically here. 197 + 198 + 199 + 200 + <details class="minor-callout"> 201 + 202 + <summary class="text-stone-500">Here is the full spindle workflow file.</summary> 203 + 204 + ```yaml 205 + when: 206 + - event: ["push", "pull_request"] 207 + branch: ["main"] 208 + 209 + dependencies: 210 + nixpkgs: 211 + - deno 212 + - nodejs 213 + - pnpm 214 + - python3 215 + - gnused 216 + 217 + engine: "nixery" 218 + 219 + steps: 220 + - name: Install dependencies 221 + command: | 222 + pnpm install 223 + 224 + - name: Generate static site 225 + command: | 226 + pnpm generate 227 + 228 + - name: Install deployctl 229 + command: | 230 + deno install -gArf jsr:@deno/deployctl 231 + 232 + - name: Deploy to Deno Deploy 233 + command: | 234 + cd .output/public 235 + ~/.deno/bin/deployctl deploy --project finxol-blog --entrypoint jsr:@std/http/file-server --include=. --prod 236 + ``` 237 + 238 + </details> 239 + 240 + It took me a little bit more time to get things working right. 241 + I found a little bug in the tangled UI regarding spindle runs. 242 + 243 + When pushing to the official knot, the workflow got picked up fine by the official spindle, and showed up in the UI. 244 + When I pushed to my knot however, the official spindle ran the workflow, but it didn't show in the UI. 245 + It took me a while to realise what was going on. 246 + 247 + I thought the spindle wasn't picking up the workflow, but the bug was simply with showing the info in the UI. 248 + [Anirudh](https://tangled.sh/@icyphox.sh) was very quick to find the cause and implement a fix. 249 + 250 + And just like that, this blog gets deployed automatically on push, using the tangled spindle!
public/posts/embracing-atproto-pt2/new-repo.png

This is a binary file and will not be displayed.