Artifacts Repos Can Now Auto Build and Deploy on Every Push!
Hi, it's me! Cloudflare just dropped a really exciting update, and I couldn't wait to tell you about it: you can now build and deploy your Artifacts repos automatically, right on every push!
Cloudflare ChangelogWhat was announced?
According to the Cloudflare Changelog, you can now define a CI Workflow for your Artifacts repo. Using the CI SDK (@cloudflare/ci), you write your CI steps, and they get triggered automatically whenever a push event happens on your Artifacts repo.
Here's what this unlocks:
- Automatically build and deploy application code stored in Artifacts
- Run linting, type checking, tests, and other checks on every push
- Reuse dependencies when the lockfile (like
pnpm-lock.yaml) hasn't changed - Stop the deployment if a check or build fails
- Restrict API token access to just the deployment step
- Deploy the output to a Worker or a Workers for Platforms User Worker
Why it matters
Artifacts is Cloudflare's way of storing and managing your code, and Workflows lets you chain together multi-step processes. What's new here is that these two are now connected by a push event.
Before this, if you wanted to build and deploy code stored in Artifacts, you'd likely need to set up a separate trigger or run the pipeline by hand. Now, pushing to your repo is enough to kick off the whole CI/CD pipeline, so the place where your code lives and the place where deployment starts are finally the same thing.
What changes
As a developer, you can push to Artifacts and let Cloudflare handle linting, type checking, testing, building, and deploying for you. If even one check fails, the deployment stops automatically, so broken code has a much harder time reaching production.
On top of that, you can scope the API token used for deployment down to just the deploy step. That means your build and test stages don't need broad permissions, which is a nice security win.
Dive Deep
The CI SDK uses ci.runner() to spin up sandboxed steps. Here's the sample from the changelog:
const deps = await ci.runner({
name: "install",
command: "bun install --frozen-lockfile",
cache: { inputs: ["package.json", "bun.lock"] },
});
await Promise.all([
deps.runner({ name: "lint", command: "bun run lint" }),
deps.runner({ name: "test", command: "bun run test" }),
deps.runner({ name: "typecheck", command: "bun run typecheck" }),
deps.runner({ name: "build", command: "bun run build" }),
]);
await deps.runner({ name: "deploy", command: "bun wrangler deploy" });
By setting cache.inputs to package.json and bun.lock on the install step, the installed dependencies get reused as long as those files don't change. The lint, test, typecheck, and build steps called on deps.runner() run in parallel via Promise.all, each inside its own isolated sandbox.
To trigger the Workflow, you register a cf.artifacts.repo.pushed event in your Wrangler config:
{
"triggers": {
"events": [{
"type": "cf.artifacts.repo.pushed",
"filter": {
"namespace": "CI",
"repoName": "my-repo",
},
"target": {
"scriptName": "my-ci-worker",
"workflowName": "ci-workflow",
},
}],
},
}
The filter narrows down which namespace and repo to watch, and target points to which Worker and Workflow should run.
Wrap-up
- Pushing to an Artifacts repo can now automatically trigger a CI Workflow
@cloudflare/ci'sci.runner()lets you build sandboxed, composable steps- Dependency installs get cached and reused when the lockfile hasn't changed
- Deployment stops automatically if a check fails
- The deployment API token can be scoped to just the deploy step
- Output can go to a Worker or a Workers for Platforms User Worker
If you're managing code in Artifacts and have been building and deploying by hand after every push, this update is made for you!