So here’s what happened: I was fixing a simple UI bug on my website when I made one of those classic developer mistakes. I pushed a commit without double-checking my changes, and somehow convinced myself that Vercel’s built-in pipeline would catch any issues. Spoiler alert - it didn’t.
The site went down, and I spent the next hour frantically rolling back changes while my perfectionist brain screamed at me. That’s when I realized I needed to stop relying on Vercel’s basic checks and build something more robust.
Basic CI/CD pipeline flow.
What I Actually Wanted to Achieve
My personal website is pretty straightforward - it’s an Astro project stored on GitHub and deployed through Vercel. After my embarrassing deployment failure, I had some clear goals:
- Catch stupid mistakes before they break production (obviously)
- Build and test the Astro project properly
- Check that dependencies aren’t completely broken
- Set up a foundation for more advanced testing later
I’m keeping it simple for now. End-to-end testing and performance monitoring are definitely on my list, but I wanted to start with the basics and actually ship something that works.
The Basics of CI/CD (Without the Buzzwords)
Look, CI/CD sounds fancy, but it’s really just automation that saves you from yourself. Continuous Integration means your code gets tested every time you make changes. Continuous Deployment means those changes go live automatically once they pass all checks.
The whole point is catching problems early instead of discovering them when your site is down and you’re stress-eating cereal at 2 AM.
💡 Real Talk
Setting This Thing Up
Let me walk you through exactly how I built this pipeline. I’ll skip the theoretical stuff and jump straight into what actually works.
Getting GitHub Actions Running
First, you need to create the workflow structure in your repo:
.github/
└── workflows/
└── ci.yml
The workflow file is where the magic happens. Here’s what I ended up with after some trial and error:
name: CI
on:
push:
branches:
- '*'
pull_request:
branches:
- 'main'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
- name: Build
run: npm run build
This runs on every push to any branch and every pull request to main. Probably overkill, but I’d rather be safe than sorry at this point.
⚠️ Heads Up
Branch Protection Rules (AKA Saving Yourself from Yourself)
GitHub’s branch protection is honestly a lifesaver. Here’s how to set it up:
- Go to your repo’s Settings → Branches
- Click “Add rule”
- Type in your main branch name
- Check “Require pull request reviews before merging”
- Check “Require status checks to pass before merging”
- Select your CI workflow from the list
Now you literally can’t push broken code to main, even if you try. Past me would have found this annoying, but current me appreciates the guardrails.
🛡️ Pro Tip
How This Actually Works in Practice
Here’s what happens when I push code now:
My CI/CD Pipeline in Action
What actually happens when I commit code now.
Breaking Down Each Step
- I push code - Same as always, but now I actually check what I’m pushing
- GitHub triggers the workflow - Happens automatically within seconds
- Dependencies get installed - npm install runs in a clean environment
- Tests run - Any automated tests I’ve written get executed
- Build happens - The Astro build process runs to make sure everything compiles
- Status gets reported - I get a green checkmark or a very red X
If anything fails, the deployment stops and I get notified. No more broken production sites.
The actual flow from my perspective.
The beauty of this setup is that it’s completely automated. I don’t have to remember to run tests or check if my build works - it just happens. And if I mess up, I know about it immediately instead of finding out when someone tells me my site is broken.
💡 Reality Check
What I Learned
Building this pipeline was honestly easier than I expected, but it’s already saved me from myself at least three times. No more late-night panic fixes, no more wondering if my latest changes broke something.
The next step is adding some actual end-to-end tests, probably with Playwright or Cypress. I also want to set up proper staging deployments and maybe some performance monitoring. But for now, this basic setup gives me the confidence to push code without holding my breath.
Useful Links I Actually Used
- GitHub Actions Documentation - surprisingly readable
- Vercel Documentation - for deployment integration
- GitHub Actions Marketplace - tons of pre-built actions
If you’re setting this up yourself and run into issues, feel free to reach out. I probably made the same mistake already.
Stay up to date
Get notified when I publish something new, and unsubscribe at any time.