I want a better CI system. I’ve lived in GitHub Actions for years, tried Gitlab’s CI/CD, evaluated Google Cloud Build and poked about Jenkins. None of them do the basics right. And I want a CI that gets the basics right.

I want a CI that gets the basics right.

Let me write a script. Bash, Python, zsh, whatever language I want. Let me push a shebang at the top, and just run it.

Let me inject environment variables into wherever the script is running. I’d say it’s obvious that the system should store all of these encrypted at rest, and minimize access to them, but apparently not everyone thinks that’s obvious.

Let me rotate my environment variables via API. Why does GitHub make this difficult?

Let me see the logs. Capture stdout and stderr separately and let me view them.

Let my scripts use exit codes to communicate state. Use common sense. A 0 exit code means success, anything else means failure. Surface the exit code on CI failures for debugging.

Let me run it on an understandable platform. Like a common base docker image. An Ubuntu LTS is not be optimized for startup time, but it has what I need and I can run it locally when something breaks.

And finally, let me run this script locally and then run it in CI and have the exact same thing happen. Make it a one-liner to run the exact same thing locally. docker run -v /path/to/repo:/repo -w /repo ubuntu:24.04 python3 scripts/script-1.py. Show this to me on the CI page so I can run the same steps locally. Make this trivial.

Okay fine. Maybe I still need some configuration.

Realistically, I have a few scripts that should trigger in different circumstances. Give me a simple way to control that. Something like:

- name: CI Script (Python)
  script: scripts/script-1.py
  triggers: 
  - type: PR
    target-branch: main

That’s all I want for configuration.

That’s all I want for CI.

No CI-specific package manager. I promise pip, apt, gem, and an LLM can get me what I want with fewer supply chain issues.

No complex “data as code” configuration language to learn. What’s wrong with Python? Or Clojure?

No need to set up a test PR to see if the script works. I should be able to run it locally.