Back to Blog

Let's be honest — manually testing and building your app before every single deploy is a recipe for disaster. Here is how to automate it.
You've probably faced this exact scenario. You finish working on a feature, run it locally, and everything looks amazing. You push it to production, and boom — the build fails. You realize you forgot to run the linter, or maybe some tests broke because of a tiny change you made at the last second.
Worse yet, you have to manually SSH into your server, pull the changes, install dependencies, build, and restart the process. This manual approach is slow, prone to human error, and honestly, just plain stressful. You shouldn't have to hold your breath every time you push code.
GitHub Actions is GitHub's built-in platform for automation. It lets you automate your development workflows right where your code lives.
Instead of paying for external CI/CD tools or configuring complex servers, you can write a simple YAML file. This file tells GitHub: "Hey, whenever I push code to this branch, I want you to spin up a temporary clean machine, install my code, run my tests, and let me know if everything is green."
Everything in GitHub Actions revolves around a few core concepts:
Workflows: Automated procedures that you add to your repository. They are defined in YAML files inside the .github/workflows directory.
Events: Specific activities that trigger a workflow. For example, a push to the main branch or opening a pull_request.
Jobs: A set of steps that execute on the same runner (a virtual machine). By default, jobs run in parallel.
Steps: Individual tasks that run commands or actions.
Here is a real, working example of a GitHub Actions workflow that runs tests and builds a Next.js / TypeScript application:
# .github/workflows/ci.yml
name: Next.js CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Build application
run: npm run build
Writing that small configuration file changes your entire development loop. Here is why this thing is wild:
Consistency: Your code is tested on a clean machine every single time. If it works there, you know you don't have "works on my machine" syndrome.
Peace of mind: You can protect your production branch. You can configure GitHub to literally block any merge attempts if the actions run fails.
Automated deployment: Once your tests pass, you can add another job that automatically deploys your code to Vercel, AWS, or your own VPS. You push to main, and the rest is handled.
You should absolutely use GitHub Actions if you are working on a team, or if you are running a production app where downtime actually hurts. It saves time and ensures everyone on the team follows the same quality gates.
However, stay with me here — do not over-engineer this. If you are just starting a tiny pet project or trying out a new CSS library over the weekend, you don't need a heavy multi-stage pipeline. Keep it simple. Don't waste your free GitHub Action runner minutes on stuff you don't actually need yet.
Ready to set it up? It takes less than two minutes:
In the root of your project, create a folder named .github.
Inside it, create another folder named workflows.
Create a file called playbook.yml inside that folder.
Copy and paste the YAML code snippet from earlier in this article.
Commit and push your changes to GitHub. Go to the "Actions" tab in your repository and watch the magic happen!
Automating your workflow feels like hiring a virtual assistant who works 24/7 for free. Once you get a taste of pushing code and watching those green checkmarks light up, you will never want to go back to manual builds again.
What is your current deployment flow? Are you using GitHub Actions, or are you still relying on manual SSH commands? Let me know in the comments below!
Found this useful? Drop a reaction, share it with a dev who needs it and show some love by following me on Linkedin — More coming.