
CI/CD Adventures: How We Almost Broke Everything (But Learned Stuff)

It all started on a bright Saturday morning, 8 AM. The mission: set up a fully automated CI/CD pipeline for a private client. Nothing could possibly go wrong… or so we thought.By 11 AM, after staring at GitHub Actions, yelling at YAML files, and mentally questioning life choices, we had a working pipeline. And yes, we lived to tell the tale.
Step 1: The Great .yml vs .yaml Saga
First rookie mistake: naming the workflow file main.yaml instead of main.yml. GitHub Actions only recognizes .yml in the .github/workflows/ folder.
Oh, and I didn’t even have the folder at first… so GitHub just ignored us silently. Classic.
Moral: Folders matter. File extensions matter. And yes, GitHub will silently ignore you if you mess this up.
Step 2: Secrets and Environment Variables Hell
We’re using:
Vercel for deployment (you might be on Netlify or Firebase, that’s cool too)
Supabase for backend services (you might use Firebase, PlanetScale, or Prisma)
Next.js for the frontend (but hey, React or Astro would work as well)
Everything was working perfectly on Vercel… until we ran the GitHub Actions build.
unhandledRejection Error: @supabase/ssr: Your project's URL and API key are required to create a Supabase client!
Turns out… our environment variables weren’t passed to GitHub Actions. They worked fine on Vercel because Vercel magically knows your secrets, but GitHub is brutally honest.
Fix: add them under the env: section in the build job:
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }}
And yes, always double-check they exist in your repository secrets. I had to do this three times before my sanity returned.
Step 3: Breaking Jobs into Chunks
We separated our pipeline into logical chunks:
Vulnerability check:
npm audit --audit-level=highLinting: ESLint (warnings allowed, because sometimes ESLint is dramatic)
Format check:
npm run format:checkTests: placeholder for now, because let’s be honest… no tests exist yet
Build: Next.js, with environment variables
Deploy: Vercel for main, preview deploys for PRs
We also used needs: so jobs run in the correct order. Without it, GitHub tries to be too clever, and your build fails for no reason.
Step 4: Deploying Like a Pro (Sort Of)
Deploying to Vercel finally worked once all the secrets were in place. For PRs, we let Vercel handle preview deploys automatically.
If you’re using Cloudflare Workers, Netlify, or any other deployment platform, the principle is the same: pass secrets correctly, otherwise mysterious “project not found” errors appear, and you cry for 20 minutes.
Step 5: Extra Sauce
We also added:
Linting warnings allowed so builds don’t fail unnecessarily
Separate job for format checking
Placeholder tests
Cache for
node_modulesand npm to speed up builds
The pipeline now looks like this:
Vulnerability → Lint → Format → Test → Build → Deploy
└─────────┘Everything runs sequentially for sanity, but you could parallelize some if you’re feeling adventurous.
Step 6: Google Login WTF Moment
Oh, and fun fact: our Google login was pointing to an old Cloudflare domain. Solution: the client needs to grant proper access in Google Cloud. No magic here, just bureaucracy.
Lessons Learned
YAML ≠ YAML – GitHub only accepts
.yml. Don’t fight it.Folders matter –
.github/workflows/is mandatory.Secrets are king – missing them breaks builds silently.
Separate jobs = sanity – vulnerability → lint → format → test → build → deploy.
Cache Node modules – Next.js complains if you don’t.
Deploy secrets properly – Vercel does it automatically, GitHub doesn’t.
Google login requires client cooperation – OAuth won’t magically fix itself.
TL;DR
CI/CD can be frustrating, but separating concerns saves your life.
Vercel + Supabase + Next.js works beautifully once configured correctly.
Don’t panic when GitHub Actions errors look like the apocalypse; it’s usually a missing secret or a tiny typo.
We did all of this from 8 AM to 11 AM, so don’t be alarmed - yes, it can be fixed quickly.