CI/CD with GitHub Actions
Continuous integration builds and tests every push and pull request, so problems surface in minutes instead of on release day. Continuous delivery packages the tested build and releases it automatically, or with one approval.
A typical pipeline for a Spring Boot service:
- Check out the code and set up Java.
- Build and run the tests (
./mvnw verify), with Testcontainers for integration tests. - Run static analysis and dependency vulnerability checks.
- Build a Docker image tagged with the commit SHA and push it to a registry.
- Deploy to Railway, a VPS or Kubernetes, then run a quick smoke test.
Keep secrets such as registry tokens in the CI system's secret store, never in the repository. Protect the main branch so merges need a passing pipeline and a review.
Example
# .github/workflows/ci.yml
name: ci
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '25'
cache: maven
- run: ./mvnw -B verify # compile, unit and integration tests
- name: Build and push the image
if: github.ref == 'refs/heads/main'
run: |
echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}Common mistake
Deploying images tagged latest. You can't tell which code is running or roll back reliably; tag with the commit SHA.
Under the hood
Fast pipelines get used: cache dependencies, run unit tests first and slower integration tests in parallel, and fail early. Tag images with the commit SHA instead of latest, so you always know what's running and can roll back instantly. Database migrations (Flyway, Liquibase) should run during deployment and stay backward compatible for one release, so old and new versions can run side by side.
Check yourself
What should a production Docker image usually be tagged with?
How this connects
Know these first
Where this leads
You've reached the end of this thread. Try a learning path for what's next.
Part of Job-ready backend developer, Microservices and production.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.