A deployment should be boring, and this is the machinery that makes it boring.
Ask a small team how a release happens and you usually get a name. One person, one laptop, one set of commands they half remember. It works until that person is on leave and something breaks on a Saturday.
GitHub Actions moves the release into the repository. A merge runs the checks, builds the application and puts it on the server, the same way every time, whoever is in the office.
GitHub Actions runs jobs on GitHub’s machines when something happens in your repository. Usually the trigger is a push or a merge, and the job is the sequence a developer would otherwise run by hand: install, test, build, deploy. It is written as a file beside the code, so the release process gets reviewed like the rest of the system.
Where it earns its place.
What we have it do
- Run the tests and type checks on every pull request
- Refuse a merge when they fail
- Build the application once, and deploy that same build onward
- Run database migrations as a separate, watched step
- Deploy to staging on merge, and to production when a person approves
- Tag each release, so you can tell what is actually running
It makes releases repeatable, not safe
This confusion is worth clearing up early. Automation removes the human error in the steps. It says nothing about whether the change was a good idea.
- Tests that check nothing still pass, cheerfully
- A pipeline deploys a bug faster than any person could
- The way back matters more than the way out
- A health check after deployment, or a customer tells you first
- Somebody watching the logs for the first few minutes after a production release
The first pipeline we write for a team usually goes no further than staging, until the tests are worth trusting.
Secrets, and the mistake everybody makes once
A pipeline needs passwords, keys and access to your server. That is a new place for them to leak from.
- Secrets in the encrypted store, never in the workflow file
- Separate credentials for staging and production
- Deployment keys limited to what the deployment actually touches
- Nothing secret printed into a build log, which is easier to do by accident than you would think
- A rotation plan for the day somebody leaves
What it costs to run
Public repositories run free. Private ones come with an allowance of build minutes and are billed past it, which is worth knowing before a test suite grows.
- Caching dependencies, so each build is not downloading the world again
- Running only what changed, where one repository holds several applications
- A self-hosted runner where builds are long or need your own network
- Skipping the full suite on draft branches, and running it before merge
Where we use it
- Next.js and React deployments
- Node and NestJS services shipped as Docker images
- Database migrations, as a reviewed step rather than a remembered one
- Mobile builds handed off to the Expo build service
- Scheduled jobs, such as a nightly export to an accounts team
When this is the right choice.
- Your code is already on GitHub and releases depend on one person
- More than one developer, where a broken main branch costs everybody an afternoon
- Tests worth running, or a team willing to write a few
- Staging and production that should be updated in exactly the same way
- A system deployed often enough that doing it by hand has become a chore
When it is not.
- Code hosted on GitLab or Bitbucket, where their own pipelines fit more neatly
- A project one person deploys every few months, where a shell script is less to maintain
- A codebase with no tests, where a pipeline buys repeatable deployment and nothing more
- Builds needing hardware or a private network the hosted runners cannot reach
- A release problem that is really about review habits, which automation will only speed up
Questions we are asked about it.
Do we need this with a small team?
The value starts at two developers, and it is real at one if that person is not the business owner. A repeatable deployment is a handover document that runs itself.
Can it deploy to our own server?
Yes. Most systems we run deploy over SSH to an Ubuntu server, usually as a Docker image. Nothing about Actions requires a particular cloud provider or a managed platform.
What happens if a deployment fails halfway?
That is the part worth designing. We start the new version alongside the old, switch traffic once it answers a health check, and keep the previous one ready to switch back. Migrations are written so the old code survives them.
GitHub Actions or Jenkins?
If your code is on GitHub, Actions is less to run, because there is no build server of your own to maintain. Jenkins earns its place where builds are long, hardware is involved, or policy keeps everything inside your network.
Can you set this up on a project we already run?
Usually inside the existing repository, without touching the application. The first pipeline runs tests, the second deploys to staging, and production follows once you are comfortable with both.
Who fixes it when the pipeline itself breaks?
Whoever maintains the application, which is why we keep the workflow files short and readable. A pipeline only one person understands has recreated the problem it was built to remove.
Services that use it.
What it sits with.
Not sure GitHub Actions is the right choice?
Tell us what the software has to do and who opens it. If something else fits better, we will say so, and say why.
- No obligation
- We reply the same working day
- Your details stay private