[HN Gopher] Using Radicle CI
       ___________________________________________________________________
        
       Using Radicle CI
        
       Author : aiw1nt3rs
       Score  : 81 points
       Date   : 2025-07-23 13:09 UTC (9 hours ago)
        
 (HTM) web link (radicle.xyz)
 (TXT) w3m dump (radicle.xyz)
        
       | kuehle wrote:
       | > I find the most frustrating part of using CI to be to wait for
       | a CI run to finish on a server and then try to deduce from the
       | run log what went wrong. I've alleviated this by writing an
       | extension to rad to run CI locally: rad-ci.
       | 
       | locally running CI should be more common
        
         | apwell23 wrote:
         | prbly have really bad code and tests if everything passes
         | locally but fails on CI reguarly.
        
           | goku12 wrote:
           | Not necessarily. For one, the local dev environment may be
           | different or less pristine than what's encountered in the CI.
           | I use bubblewrap (the sandboxing engine behind flatpak)
           | sometimes to isolate the dev environment from the base
           | system. Secondly, CI often does a lot more than what's
           | possible on the local system. For example, it may run a lot
           | more tests than what's practical on a local system. Or the
           | upstream Repo may have code that you don't have in your local
           | repo yet.
           | 
           | Besides all that, this is not at all what the author and your
           | parent commenter is discussing. They are saying that the
           | practice of triggering and running CI jobs entirely locally
           | should be more common, rather than having to rely on a
           | server. We do have CI runners that work locally. But the CI
           | job management is still done largely from servers.
        
             | apwell23 wrote:
             | > For example, it may run a lot more tests than what's
             | practical in a local system.
             | 
             | yes this is what i was taking about. If there are a lots of
             | tests that are not practical to run locally then they are
             | bad tests no matter how useful one might think they are.
             | only good tests are the ones that run fast. It is also a
             | sign that code itself is bad that you are forced to write
             | tests that interact with outside world.
             | 
             | For example, you can extract logic into a presention layer
             | and write unit test for that instead of mixing ui and
             | business logic and writing browser tests for it. there are
             | also well known patterns for this like 'model view
             | presenter'.
             | 
             | I would rather put my effort into this than trying to
             | figure out how to run tests that launch databases,
             | browsers, call apis , start containers ect. Everywhere i've
             | seen these kind of tests they've contributed to "it sucks
             | to work on this code" feeling, bad vibes is the worst thing
             | that can happen to code
        
               | NewJazz wrote:
               | It is a tradeoff, e.g. running tests with a real database
               | or other supporting service and taking longer vs. mocking
               | things and having a test environment that is less like
               | reality.
        
               | andrewaylett wrote:
               | https://testcontainers.com/ is not _quite_ the solution
               | to all your problems, but it makes working with real
               | databases and supporting services pretty much as easy as
               | mocking them would be.
               | 
               | I'd really recommend against mocking dependencies for
               | most tests though. Don't mock what you don't own, do make
               | sure you test each abstraction layer appropriately.
        
               | apwell23 wrote:
               | do you really need to test postgres api in your own code?
        
               | 8n4vidtmkvmk wrote:
               | It does suck when those large scale integration tests
               | fail but sometimes that's the only real way to test
               | something. E.g. I have to call a service owned by another
               | team. It has a schema and documentation so I can mock out
               | what I _think_ it will return, but how will I truly know
               | the API is going to do what it says or what I think it
               | says without _actually_ calling the API?
        
               | apwell23 wrote:
               | > I truly know the API is going to do what it says or
               | what I think it says without actually calling the API?
               | 
               | what if the API changes all of sudden in production? what
               | about cases where api stays the same but content of
               | response is all wrong? how do tests protect you from
               | that?
               | 
               | edit: they are not hypothetical scenarios. wrong
               | responses are way more common than schema breaking.
               | tooling upsteam is often pretty good at catching schema
               | breakages.
               | 
               | wrong responses often cause way more havoc than schema
               | breakages because you get an alert for schema failures in
               | app anyways.
        
               | chriswarbo wrote:
               | Tests can't catch everything; it's a question of
               | cost/benefit, and stopping when the diminishing returns
               | provided by further tests (or other QA work) isn't enough
               | to justify the cost of further investment in them
               | (including the opportunity cost of spending our time
               | improving QA elsewhere).
               | 
               | For your example, the best place to invest would be in
               | that API's own test suite (e.g. sending its devs examples
               | of usage that we rely on); but of course we can't rely on
               | others to make our lives easier. Contracts can help with
               | that, to make the API developers responsible for
               | following some particular change notification process.
               | 
               | Still, such situations are hypothetical; whereas the
               | sorts of integration tests that the parent is describing
               | are useful to avoid _our_ deployments from immediately
               | blowing up.
        
               | 8n4vidtmkvmk wrote:
               | That's exactly the point, isn't it? If the schema or
               | response format changes, we want to catch that quickly.
               | Canary, staging, or prod, take your pick but we need to
               | call the API and run some assertions against that to make
               | sure it's good.
        
               | girvo wrote:
               | Tbf that's what post-deployment verification tests sre
               | ideal for, instead of as integration/e2e tests blocking
               | your merges/deployments
        
               | 8n4vidtmkvmk wrote:
               | That's fine. If they're too slow, run them post
               | deployment. But do run them at some point so you can at
               | least catch it quickly without waiting for user
               | complaints.
        
         | andrewaylett wrote:
         | Hear, hear.
         | 
         | Although I'd slightly rephrase that to "if you don't change
         | anything, you should end up running pretty much the same code
         | locally as in CI".
         | 
         | GitHub Actions is really annoying for this, as it has no
         | supported local mode. Act is amazing, but insufficient: the
         | default runner images are _huge_ , so you can't use the same
         | environment, and it's not supported.
         | 
         | Pre-commit on the other hand is fantastic for this kind of
         | issue, as you can run it locally and it'll fairly trivially run
         | the same checks in CI as it does locally. You want it to be
         | fast, though, and in practice I normally wind up having pre-
         | commit run only cacheable tests locally and exclude any build
         | and test hooks from CI because I'll run them as separate CI
         | jobs.
         | 
         | I did release my own GHA action for pre-commit
         | (https://github.com/marketplace/actions/cached-pre-commit),
         | because the official one doesn't cache very heavily and the
         | author prefers folk to use his competing service.
        
         | maratc wrote:
         | This can be achieved by running in CI what commonly runs on
         | local.
         | 
         | E.g. if your build process is simply invoking `build.sh`, it
         | should be trivial to run exactly that in any CI.
        
           | ambicapter wrote:
           | This is fine until your run into differences between your
           | machine and the CI one (or you're writing code for a
           | different architecture than the one you're using), but I
           | agree, this is definitely the first step.
        
             | maratc wrote:
             | I agree, but if there's an architecture gap then _locally
             | running CI_ is not gonna help you to bridge it either.
        
             | 0x457 wrote:
             | Plot twist, my build.sh invokes nix build and all I have to
             | do on CI is to install nix and setup caching.
        
           | esafak wrote:
           | Be sure to run it in a container, so you have a semblance of
           | parity.
        
             | maratc wrote:
             | Where possible. (If your build process builds containers
             | and your tests get them up and make them talk, doing that
             | in a container is a challenge.)
             | 
             | However, there are stateless VMs and stateless BMs too.
        
               | BeeOnRope wrote:
               | What is a BM?
        
               | maratc wrote:
               | Baremetal (meaning: "the whole server" usually.)
        
         | esafak wrote:
         | dagger does this, at the expense of increased complexity.
        
         | __MatrixMan__ wrote:
         | Agreed. I've got a crazy idea that I think might help...
         | 
         | Most tests have a step where you collect some data, and another
         | step where you make assertions about that data. Normally, that
         | data only ever lived in a variable, so it is not kept around
         | for later analysis. All you get when you're viewing a failed
         | test is logs with either exception or a failed assertion. It's
         | not enough to tell a full story, and I think this contributes
         | to the frustration you're talking about.
         | 
         | I've been playing with the idea that all of the data generation
         | should happen first (since it's the slow part), it then gets
         | added to a commit (overwriting data from the previous CI run)
         | and then all of the assertions should run afterwards (this is
         | typically very fast).
         | 
         | So when CI fails, you can pull the updated branch and either:
         | 
         | - rerun the assertions without bothering to regenerate the data
         | (faster, and useful if the fix is changing an assertion)
         | 
         | - diff the new data against data from the previous run (often
         | instructive about the nature of the breakage)
         | 
         | - regenerate the data and diff it against whatever caused CI to
         | fail (useful for knowing that your change will indeed make CI
         | happy once more)
         | 
         | Most tools are uncomfortable with using git to transfer state
         | from the failed CI run to your local machine so you can just
         | rerun the relevant parts locally, so there's some hackery
         | involved, but when it works out it feels like a superpower.
        
         | Norfair wrote:
         | nix-ci.com is built with this as one of the two central
         | features. The other is that it figures out what to do by
         | itself; you don't have to write any YAML.
        
         | gsaslis wrote:
         | It should!
         | 
         | And yet, that's _technically_ not CI.
         | 
         | The whole point we started using automation servers as an
         | integration point was to avoid the "it works on my machine"
         | drama. (Have watched at least 5 seasons of it - they were all
         | painful!).
         | 
         | +1 on running the test harness locally though (where feasible)
         | before triggering the CI server.
        
         | popsticl3 wrote:
         | I've been using brisk to run my CI from my local machine (so it
         | runs in the cloud from my local terminal). The workflow is just
         | a drop in replacement for local running. They've recently
         | changed their backend and it seems to be working pretty
         | smoothly. It works very well with AI agents too that are
         | running in the terminal - they can run my tests for me if they
         | make a change and it doesn't kill my machine.
        
         | everforward wrote:
         | I've poked at this a few times, and I think it breaks down for
         | CI that needs/wants to run integration tests against other
         | services. Eg it wants to spin up a Postgres server to actually
         | execute queries against.
         | 
         | Managing those lifetimes is annoying, especially when it needs
         | to work on desktops too. On the server side, you can do things
         | like spin up a VM that CI runs in, use Docker in the VM to make
         | dependencies in containers, and then delete the whole VM.
         | 
         | That's a lot of tooling to do locally though, and even then
         | it's local but has so many abstractions that it might as well
         | be running in the cloud.
        
         | globular-toast wrote:
         | Yeah, and I will never understand why developers accept
         | anything less. GitHub CI is really bad for this. GitLab is a
         | lot better as you can just run the exact thing through Docker
         | locally. I like tools like tox too that automate your whole
         | test matrix and do it locally just as well.
        
       | tough wrote:
       | I use act to run github CI locally fwiw
       | https://github.com/nektos/act
        
       | dan_manges wrote:
       | There's a difference between small scale CI and large scale CI.
       | 
       | Small scale: a project is almost small enough to run the build
       | and tests locally, but you still want to have a consistent
       | environment and avoid "works on my machine" problems.
       | 
       | Large scale: a project is so large that you need to leverage
       | remote, distributed computing to run everything with a reasonable
       | feedback loop, ideally under 10 minutes.
       | 
       | The opposite ends of the spectrum warrant different solutions.
       | For small scale, actually being able to run the whole CI stack
       | locally is ideal. For large scale, it's not feasible.
       | 
       | > A CI system that's a joy to use, that sounds like a fantasy.
       | What would it even be like? What would make using a CI system
       | joyful to you?
       | 
       | I spent the past few years building RWX[1] to make a CI system
       | joyful to use for large scale projects.
       | 
       | - Local CLI to read the workflow definitions locally and then run
       | remotely. That way can you test changes to workflow definitions
       | without having to commit and push.
       | 
       | - Remote breakpoints to pause execution at any point and connect
       | via ssh, which is necessary when running on remote
       | infrastructure.
       | 
       | - Automatic content-based caching with sandboxed executions, so
       | that you can skip all of the duplicative steps that large scale
       | CI otherwise would. Sandboxing ensures that the cache never
       | produces false positives.
       | 
       | - Graph-based task definitions, rather than the 1 job : 1 VM
       | model. This results in automatic and maximum parallelization,
       | with no redundancy in setup for each job.
       | 
       | - The graph based model also provides an improved retry
       | experience, and more flexibility in resource allocation. For
       | example, one task in the DAG can crank up the CPU and memory
       | without having to run more resources for downstream tasks (steps
       | in other platforms).
       | 
       | We've made dozens of other improvements to the UX for projects
       | with large build and test workflows. Big engineering teams love
       | the experience.
       | 
       | [1] https://rwx.com
        
         | RGBCube wrote:
         | Sounds good, but it's still YAML and shell scripts. It's not
         | even close to ideal.
         | 
         | A custom lazy, typed functional language that doesn't
         | differentiate between expressions and "builds" would be much
         | better. Even better if you add "contexts", aka implicit tags
         | under values for automatic dependency inference. Also do
         | "serializable bytecode", and closing over dependencies of
         | thunks efficiently like Unison does for great distrubuted
         | builds.
         | 
         | And it would be pretty easy to add a debugger to this system,
         | same logic as doing "import"
         | 
         | Nix gets somewhat close, but it misses the mark by separating
         | the eval and build phases. It having terrible documentation,
         | 1332432 ways to do the same thing, not properly separating the
         | nixpkgs/nix divide, and nixpkgs being horribly, but still
         | insufficiently abstracted also doesn't help.
         | 
         | Also, I'm not sure why you posted this comment here, as there
         | is nothing that prevents you from writing a Radicle CI adapter
         | that can handle huge repositories. You can reference the bare
         | git repo stored in the Radicle home, so you just need to be
         | able to store the repo itself.
        
           | viraptor wrote:
           | Every time there's yaml, you can use dhall and compile to
           | json instead. You get typing and strictness that way -
           | regardless of whether the service allows it internally.
        
       | lbotos wrote:
       | Op, Radicle had a very glitchy style home page before it went
       | more 8-bit. Do you have an archive of that anywhere? I'd like to
       | use it as reference for a style period in design!
        
       ___________________________________________________________________
       (page generated 2025-07-23 23:01 UTC)