Front end CI/CD in the age of AI

Liriel1 pts0 comments

Frontend CI/CD in the age of AI -- Part 1 — Neciu Dan

Skip to content<br>🛡️ FREE · Master Frontend Security · All 7 modules live · 100% free · Start free →

Subscribe

Search blog posts

Discover more from The Neciu Dan Newsletter

A weekly column on Tech & Education, startup building and occasional hot takes.

Over 1,000 subscribers

Website

Company

Subscribe<br>Subscribing...<br>Skip for now

The Neciu Dan Newsletter

Once a week I share what I&rsquo;m learning from building products, teaching<br>engineers, and running a startup — tech & education, career<br>lessons, and the occasional hot take, plus community reads from the<br>frontend ecosystem. Free, and you can unsubscribe anytime.

By Neciu Dan &middot; Over 1,000 subscribers

Website

Company

Subscribe<br>Subscribing...

No thanks

Table of Contents<br>CI and CD are different problems<br>CI, part 1: stop running everythingFiltering by path<br>Step one: ask git what you changed<br>Step two: walk your imports backward<br>Step three: hand that list to your three tools<br>When you would rather not maintain a regex<br>Step four: problems

CI, part 2: let’s make it fastWhat cache: 'npm' actually caches<br>Extracting the setup<br>Caching what the tools already know<br>The snails<br>Four shards, four reports<br>Narrowing E2E tests

CI, part 3: fail before the PR existsWiring it into git<br>The base ref problem, in reverse<br>Agents will bypass this, so plan for it

The shape of the whole thing<br>References

Continuous Integration (CI) and Continuous Deployment(CD) are responsible for two things: making sure that when we merge our PR, it does not introduce any faults (bugs) into our main branch (Integration), and after every merge, our code gets released in some way to production in a timely manner (Deployment).

Then, everything changed when the Fire Nation attacked (and by that I mean the AI Revolution)

AI writes almost all the code now, and its particulary good at writing tests. It doesn’t always write good or useful tests, but it likes to write a lot of tests.

As a result, the time it takes our CI to run is growing exponentially, leaving developers waiting for PRs to build, run, and get feedback that everything is working or not.

It doesn’t have to work like this. Google claims the majority of its new code is now AI-generated and engineer-approved, and they got there by making verification cheap and rollout reversible.

Let’s dig in.

PS: You can find the whole demo and script files in this repo

CI and CD are different problems

The first thing we need to establish is a clear separation between CI and CD. People treat it as a single concept and a single flow, which causes a lot of problems and headaches.

Continuous Integration answers: is this change correct? It runs Lint, types, unit tests, e2e tests, builds. It runs before merging and slow CI compounds into batched PRs, stale branches, and agents idling.

Continuous Delivery answers: is this change safe in production? Deployment, rollout, rollback. It runs after the merge.

In this article (part 1) I want to focus on building a robust and FAST CI pipeline for Frontend projects. In part we will tackle the deployment part.

CI, part 1: stop running everything

Imagine your app has a Dashboard, a Settings page, a Billing page, and folders for shared components and shared utilities. Everything lives in a single app and repo, with no workspaces or internal packages.

You change one line in Button.tsx, push the PR, and your pipeline lints every file you own, typechecks the whole project, runs all 340 unit tests, and builds the app.

Which is fine, but with exponential growth and some apps having millions lines of code, this can get slow fast (pun intented)

# .github/workflows/ci.yml<br>name: CI<br>on: pull_request

jobs:<br>ci:<br>runs-on: ubuntu-latest<br>steps:<br>- uses: actions/checkout@v4<br>- uses: actions/setup-node@v4<br>with:<br>node-version: 22<br>cache: 'npm'<br>- run: npm ci<br>- run: npm run lint<br>- run: npm run typecheck<br>- run: npm run test<br>- run: npm run build<br>You wait twenty-five minutes, and so does everyone queued behind you.

What you actually want is narrow and specific.

Change Button, and you want Button’s tests to run, plus the tests of everything that imports Button, however deep the chain goes, to also run.

You want the same for lint and typecheck. The Billing feature never imports Button, so Billing should not be touched at all.

You want that list computed from your code every time, so it is never wrong, and you never have to maintain it.

That setup takes away the thing most tooling relies on. You have no package.json boundaries, so nothing in your repo declares that Billing and Settings are separate.

Every tool that solves this for monorepos is reading workspace manifests that we do not have.

We will derive the same information from our imports instead.

Filtering by path

The first thing you might try is filtering by path within GitHub Actions itself. You attach a paths filter to the trigger, and the workflow only runs when your PR touches files matching those...

tests part runs from code everything

Related Articles