GitHub Actions is probably the closest thing to good CI/CD we've seen in the market for a while. That's because, historically, there are two glaring problems with CI/CD startups – the problem is so generalized that the product ends up being a distributed job scheduler, and the margin over cloud storage and compute is thin and undifferentiated (compared to other SaaS).
Things GitHub Actions gets right
- Container-native. Container-native ones are slowly replacing systems like Jenkins. There are some issues – building docker-in-docker, caching, and dependencies, but GitHub Actions handles them reasonably well.
- Reusability, in theory. While the end implementation leaves much to be desired, the idea of composable actions and libraries for common CI/CD actions is an exciting one.
- DAG, in theory. There's been a variety of push and pull between event-based CI/CD workflows vs. graph-based workflows. After working with both extensively, DAGs are much easier to reason about.
- Limited access to the machine. It's tempting to let developers SSH into build machines to debug issues, install software, and perform other tasks. Cattle, not pets.
Where I think we could still improve
- Not easily self-hosted. Actions, as a business selling compute and storage, won't scale. Besides the improved UX and better distribution, it's not differentiated from TravisCI and similar products. Let it be a true on-ramp for selling cloud services (in my own VPC). I want AWS to build a similar type of library (open-source) that makes it dead simple to do self-hosted runners. Self-hosting a runner on GitHub Actions is clunky right now. I'd even do it on Azure as managed service.
- Native cloud IAM. CI/CD machines are notorious security holes. They usually have permission to deploy anywhere (including production!) and can be triggered by anyone who can push code. You can configure this through Actions, but why not have it baked into the framework (as an API, endpoint, or other configuration)? There's
permissionsbut I want to bring my existing IAM configurations.
- As an aside, caching Docker (or BuildKit) builds on a few self-hosted runners will be significantly more effective for the majority of teams than GitHub Action's caching mechanisms.
- Code, not YAML. Maybe contrarian, but I believe that TypeScript will become the lingua franca of configuration as code. Much simpler for developers to reason about a typed schema and injected variables than with custom YAML templating.
- Not easily ran locally. Like self-hosted runners, you can do this, but it wasn't built into the framework as a first-class design decision. CI/CD cycles are long (that's part of the problem!), and pushing job configuration just to test it creates long feedback cycles.