releases.sh

Artifacts repos get CI/CD pipelines with Workflows and CI SDK

1 featureThis release1 featureNew capabilitiesAI-tallied from the release notes
From the original release noteView original ↗

You can now run your CI/CD pipeline on your Artifacts repo by defining a CI Workflow with the CI SDK ↗, automatically triggered on Artifacts push events.

This allows you to:

  • 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 (i.e. pnpm-lock.yaml) has not changed.
  • Stop deployment when a check or build fails.
  • Restrict API token access to the deployment step.
  • Deploy the output to a Worker or a Workers for Platforms User Worker.

Define your CI steps with @cloudflare/ci. Each ci.runner() spins up an isolated sandbox, and the cache option reuses installed dependencies across each sandboxed step in your CI job.

Point cache.inputs at your lockfile (i.e. pnpm-lock.yaml, bun.lock), and the install step only runs again when that lockfile changes:

src/index.jsjs

<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> deps</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> await</span><span class="nb-shiki-140thh"> ci.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh">	name: </span><span class="nb-shiki-mdbnqw">"install"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	command: </span><span class="nb-shiki-mdbnqw">"bun install --frozen-lockfile"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	cache: { inputs: [</span><span class="nb-shiki-mdbnqw">"package.json"</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-mdbnqw">"bun.lock"</span><span class="nb-shiki-140thh">] },</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-dzsirb"> Promise</span><span class="nb-shiki-140thh">.</span><span class="nb-shiki-1t8gfj">all</span><span class="nb-shiki-140thh">([</span></span>
<span class="line"><span class="nb-shiki-140thh">	deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"lint"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun run lint"</span><span class="nb-shiki-140thh"> }),</span></span>
<span class="line"><span class="nb-shiki-140thh">	deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"test"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun run test"</span><span class="nb-shiki-140thh"> }),</span></span>
<span class="line"><span class="nb-shiki-140thh">	deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"typecheck"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun run typecheck"</span><span class="nb-shiki-140thh"> }),</span></span>
<span class="line"><span class="nb-shiki-140thh">	deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"build"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun run build"</span><span class="nb-shiki-140thh"> }),</span></span>
<span class="line"><span class="nb-shiki-140thh">]);</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-140thh"> deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"deploy"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun wrangler deploy"</span><span class="nb-shiki-140thh"> });</span></span>

src/index.tsts

<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> deps</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> await</span><span class="nb-shiki-140thh"> ci.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh">	name: </span><span class="nb-shiki-mdbnqw">"install"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	command: </span><span class="nb-shiki-mdbnqw">"bun install --frozen-lockfile"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">	cache: { inputs: [</span><span class="nb-shiki-mdbnqw">"package.json"</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-mdbnqw">"bun.lock"</span><span class="nb-shiki-140thh">] },</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-dzsirb"> Promise</span><span class="nb-shiki-140thh">.</span><span class="nb-shiki-1t8gfj">all</span><span class="nb-shiki-140thh">([</span></span>
<span class="line"><span class="nb-shiki-140thh">	deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"lint"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun run lint"</span><span class="nb-shiki-140thh"> }),</span></span>
<span class="line"><span class="nb-shiki-140thh">	deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"test"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun run test"</span><span class="nb-shiki-140thh"> }),</span></span>
<span class="line"><span class="nb-shiki-140thh">	deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"typecheck"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun run typecheck"</span><span class="nb-shiki-140thh"> }),</span></span>
<span class="line"><span class="nb-shiki-140thh">	deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"build"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun run build"</span><span class="nb-shiki-140thh"> }),</span></span>
<span class="line"><span class="nb-shiki-140thh">]);</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-140thh"> deps.</span><span class="nb-shiki-1t8gfj">runner</span><span class="nb-shiki-140thh">({ name: </span><span class="nb-shiki-mdbnqw">"deploy"</span><span class="nb-shiki-140thh">, command: </span><span class="nb-shiki-mdbnqw">"bun wrangler deploy"</span><span class="nb-shiki-140thh"> });</span></span>

To start the Workflow automatically after each push, add a cf.artifacts.repo.pushed trigger to your Wrangler configuration:

<span class="line"><span class="nb-shiki-140thh">{</span></span>
<span class="line"><span class="nb-shiki-dzsirb">	"triggers"</span><span class="nb-shiki-140thh">: {</span></span>
<span class="line"><span class="nb-shiki-dzsirb">		"events"</span><span class="nb-shiki-140thh">: [</span></span>
<span class="line"><span class="nb-shiki-140thh">			{</span></span>
<span class="line"><span class="nb-shiki-dzsirb">				"type"</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-mdbnqw">"cf.artifacts.repo.pushed"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-dzsirb">				"filter"</span><span class="nb-shiki-140thh">: {</span></span>
<span class="line"><span class="nb-shiki-dzsirb">					"namespace"</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-mdbnqw">"CI"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-dzsirb">					"repoName"</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-mdbnqw">"my-repo"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">				},</span></span>
<span class="line"><span class="nb-shiki-dzsirb">				"target"</span><span class="nb-shiki-140thh">: {</span></span>
<span class="line"><span class="nb-shiki-dzsirb">					"scriptName"</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-mdbnqw">"my-ci-worker"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-dzsirb">					"workflowName"</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-mdbnqw">"ci-workflow"</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh">				},</span></span>
<span class="line"><span class="nb-shiki-140thh">			},</span></span>
<span class="line"><span class="nb-shiki-140thh">		],</span></span>
<span class="line"><span class="nb-shiki-140thh">	},</span></span>
<span class="line"><span class="nb-shiki-140thh">}</span></span>
<span class="line"><span class="nb-shiki-140thh">[[</span><span class="nb-shiki-1t8gfj">triggers</span><span class="nb-shiki-140thh">.</span><span class="nb-shiki-1t8gfj">events</span><span class="nb-shiki-140thh">]]</span></span>
<span class="line"><span class="nb-shiki-140thh">type = </span><span class="nb-shiki-mdbnqw">"cf.artifacts.repo.pushed"</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-140thh">  [</span><span class="nb-shiki-1t8gfj">triggers</span><span class="nb-shiki-140thh">.</span><span class="nb-shiki-1t8gfj">events</span><span class="nb-shiki-140thh">.</span><span class="nb-shiki-1t8gfj">filter</span><span class="nb-shiki-140thh">]</span></span>
<span class="line"><span class="nb-shiki-140thh">  namespace = </span><span class="nb-shiki-mdbnqw">"CI"</span></span>
<span class="line"><span class="nb-shiki-140thh">  repoName = </span><span class="nb-shiki-mdbnqw">"my-repo"</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-140thh">  [</span><span class="nb-shiki-1t8gfj">triggers</span><span class="nb-shiki-140thh">.</span><span class="nb-shiki-1t8gfj">events</span><span class="nb-shiki-140thh">.</span><span class="nb-shiki-1t8gfj">target</span><span class="nb-shiki-140thh">]</span></span>
<span class="line"><span class="nb-shiki-140thh">  scriptName = </span><span class="nb-shiki-mdbnqw">"my-ci-worker"</span></span>
<span class="line"><span class="nb-shiki-140thh">  workflowName = </span><span class="nb-shiki-mdbnqw">"ci-workflow"</span></span>

To learn more, refer to Build and deploy Artifacts repos.

Fetched August 4, 2026