GitHub Actions without GitHub banner
8 min read
engineering

Stay in the loop

Get notified when we ship new posts.

GitHub Actions without GitHub

At Depot, we hate a slow iteration loop. We will go to any lengths necessary to optimize a build, and we frankly get a bit nerd-sniped with opportunities to shave seconds off our customers' CI pipelines. A growing population of our users have sophisticated GitHub Actions workflows, and to date we've shipped all sorts of improvements to that ecosystem.

Initially that work revolved around giving users better compute out of the box, optimized disk and network, and tightly integrated infrastructure like accelerated docker builds, a container registry, or a remote build cache. Over time, it's looked increasingly like hiding the instability of the GitHub Actions platform itself, however possible.

Today we have a system that can tolerate a number of GitHub's failure modes and remain operational during some of their incidents, whether published or unannounced. But in the end, GitHub still owns the control plane, and it's often on fire. What's the use of all this redundancy if jobs aren't dispatched in the first place?

Our customers have pipelines to run and software to ship. For the sake of their velocity, our own sanity, and apparently GitHub's scaling issues, we decided it was in everyone's best interest to cut GitHub entirely out of the picture.

Assuming control

We started down this road at the beginning of the year with our efforts culminating in Depot CI, our own engine that natively understands the GitHub Actions workflow syntax. We shipped it officially in March, and with it we assumed ownership over a significantly larger portion of the stack. GitHub still sends us webhooks notifying us of core git activity, and we propagate job status back to GitHub to satisfy your branch protection policies. But crucially, when GitHub Actions is down, we can still run your workflows.

A note on the numbers: The Missing GitHub Status Page estimates that in the last 3 months, GHA as a platform has had an uptime of 97.5%. Over 90 days, that's 54 hours of downtime, and it's almost all during working hours. That's over a week of interrupted velocity per quarter. This is derived from incidents they report, so this is a conservative estimate.

To make Depot CI a reality, we had to prototype and stabilize a whole host of new subsystems from scratch:

  • A workflow trigger registry to control which webhooks are qualified to initiate a run
  • A secrets enclave to securely store and selectively release sensitive values to requesting workflows
  • An identity provider to authoritatively characterize workflows and issue OIDC tokens to jobs with corresponding claims
  • A semaphore to manage workflow and job concurrency, as defined in the workflow itself
  • A disk snapshotter and corresponding storage, to support custom base images and advanced debugging scenarios
  • An SSH proxy, to allow for spontaneous inspection and troubleshooting of the runner environment
  • An orchestrator to coordinate the dance of a GitHub Actions run, turning webhooks into workflows and shepherding their jobs into VMs
  • And finally, the runner itself, duly executing those instructions and propagating feedback to the orchestrator so the run can progress

These were all interesting problems to solve (and a number of these components deserve their own blog posts). Taken together, they enable us to address previously intractable failure modes and significantly expand our ability to optimize customer workloads. In the past 5 months it's paid dividends: Depot CI hums along when GitHub Actions is hard-down.

So what work remains? We still get webhooks from GitHub, clone repos from GitHub, and send status checks to GitHub. We can just connect those to another forge instead, right?

The roots run deep

Well that's certainly a start, but to properly uproot GitHub from the hot path we need to go a bit deeper. GitHub Actions is not a standalone product, and it doesn't exist in a vacuum. It's been an industry standard for 7 years, and in that time an entire ecosystem has flourished around it. These days, I can accomplish most tasks of reasonable complexity in my workflows simply by reaching for a script from the Marketplace.

Myriad scripts for all sorts of scenarios:

  • Need to check out a repository? uses: actions/checkout@v4.
  • Need to log into AWS? uses: aws-actions/configure-aws-credentials@v6.2.3
  • Need to build a Docker image, stat? 😉 uses: depot/build-push-action@v1.18.0

Virtually every job references at least one of these scripts, and dropping GitHub as a dependency requires maintaining a mirror of the Marketplace. These scripts are all versioned git repos, so this isn’t difficult. The mirror just needs to be reliable, colocated with the runners, and kept up to date as the ecosystem moves forward. More importantly, however, these scripts were written to execute inside a GitHub Actions runner, and they sometimes make hard assumptions about the presence of the GitHub platform.

One illustrative case is actions/cache, whose code effectively underpins all caching in a GHA runner, even for things like actions/setup-node or Swatinem/rust-cache. This is a first-party script, so obviously it's written against a cache service hosted in the GitHub backend. That service isn’t hosted at a single static URL. The URL is dynamic and the script derives it from an environment variable set in the runner. Since we own the Depot CI runner, we can override it, redirect that traffic to our own cache binary, implement the protocol, and then optimize the heck out of it for our users. Similar story for other first-party scripts like actions/upload-artifact and actions/download-artifact.

A more interesting case is something like docker/metadata-action, which unconditionally fetches metadata about the current repo directly from the GitHub API. Some properties, like the repo name or URL, could in theory be derived locally after the runner clones the repo. But the forge itself is ultimately the source of truth for things like the repo's description or license. Other popular actions interrogate the remote git object store, interact with pull requests and comments, or request diffs to control whether a subsequent step should run.

For these scenarios, we built an adapter that intercepts this traffic. Whenever we can compile an answer from local context or inbound webhook data, we respond directly. Otherwise, we reshape and redirect that traffic to the backing forge, mapped to whatever functionality is available in their public API.

And with that cut, we've finally extricated the GitHub Actions machinery from the GitHub platform.

Origin has entered the building

On Aug 17, GitHub was busy nullifying everyone's velocity with a fresh new incident. Later that day, with impeccable timing, the Cursor team opened the floodgates on Origin, and a new forge landed on the market. See their stellar deep dive into the history of git hosting and the technical decisions that underpin their new platform.

In the preceding weeks, Depot was invited into the fold as a launch partner. After properly and completely excising GitHub from the system, it was extremely satisfying to be able to drop Origin into Depot CI and for most workflows to simply work. It was especially rewarding for me to see months of our work come to fruition as we brought our inaugural Origin app online.

We’re on track to cross 1000 Origin app installs in our first month, and we’ve seen strong adoption from Origin users cutting their workloads over. Of new Origin accounts that have run a substantial volume of workflows, nearly 80% are triggering them exclusively from their Origin repos, with the remainder running hybrid setups across GitHub and Origin. Where we can compare the same repo across both platforms, Origin thus far appears to deliver faster checkouts with lower variance. Sample sizes are admittedly still small, so a deeper comparison will have to wait until the next post.

Conclusion

Everything we do at Depot is about helping our customers deliver software faster and solving for bottlenecks in their day-to-day development. Depot CI is just one of a slew of endeavors; we’ve also been hard at work on things like Depot Metal and Depot Sandboxes. Struggling with a bottleneck in your development stack? We’d love to hear from you.

Finally, are you launching a new forge in 2026? Do you want GitHub Actions support out of the box? We should talk.

FAQ

Can Depot CI run GitHub Actions workflows when GitHub Actions is down?

Yes. Depot CI understands GitHub Actions workflow syntax but uses Depot's own control plane, orchestrator, and runners. For GitHub-hosted repositories, GitHub still provides repository webhooks and receives status checks.

How does Depot CI support actions/cache without GitHub's cache service?

Depot CI overrides the dynamic cache service URL in its runner and redirects the traffic to Depot's cache implementation. The same approach supports first-party artifact upload and download actions.

Do GitHub Marketplace actions work with a non-GitHub forge?

Many do, but compatibility takes more than mirroring their versioned JavaScript. Some actions assume GitHub services or APIs exist, so Depot CI replaces compatible service endpoints and adapts forge-specific API requests where needed.

What does a new git forge need to run GitHub Actions workflows through Depot CI?

The forge needs to send repository events, provide source and repository metadata, and accept job status updates. Depot CI handles workflow parsing, orchestration, secrets, OIDC, concurrency, compute, caching, artifacts, and runner feedback.

Luke Morris

Luke Morris

Staff Software Engineer at Depot

Start building with Depot
in minutes