Home / Blog / DevOps / Article

๐Ÿ”„

Introduction

Continuous Integration and Continuous Deployment (CI/CD) is the backbone of modern software delivery. GitHub Actions makes it easy to automate builds, tests, and deployments directly from your repository. In this guide, we'll build production-ready pipelines from scratch.

Prerequisites

Before starting, ensure you have: a GitHub repository with your project code, basic knowledge of YAML syntax, and a deployment target (we'll use SSH deployment but the same principles apply to AWS, GCP, or Docker registries).

Step 1: Basic Project Structure

Create a `.github/workflows/` directory in your repository root. This is where all your workflow files live. Let's start with a simple Node.js CI pipeline.

Code: Node.js CI Workflow

Here's a complete GitHub Actions workflow for a Node.js project that runs on every push and pull request: ```yaml name: Node.js CI on: push: branches: [ main, develop ] pull_request: branches: [ main ] jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [18.x, 20.x] steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - run: npm run build --if-present - run: npm test - run: npm run lint ```

Step 2: Docker Build & Push

For containerized applications, here's a workflow that builds a Docker image and pushes it to Docker Hub: ```yaml name: Docker Build & Push on: push: branches: [ main ] jobs: docker: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and Push uses: docker/build-push-action@v5 with: push: true tags: | ${{ secrets.DOCKER_USERNAME }}/myapp:latest ${{ secrets.DOCKER_USERNAME }}/myapp:${{ github.sha }} ```

Step 3: Automated Deployment

Here's how to deploy via SSH after a successful build: ```yaml deploy: needs: [test, docker] runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - name: Deploy via SSH uses: appleboy/ssh-action@v1.0.0 with: host: ${{ secrets.DEPLOY_HOST }} username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} script: | cd /var/www/myapp docker-compose pull docker-compose up -d --force-recreate docker system prune -f ```

Using GitHub Secrets

Never hardcode credentials in workflow files. Store all sensitive data โ€” API keys, passwords, SSH keys โ€” as GitHub Secrets in your repository settings (Settings > Secrets and variables > Actions).

Step 4: Testing Strategy

Configure your pipeline to run unit tests, integration tests, and linting. Use matrix builds to test across multiple versions. Fail the pipeline fast โ€” test in parallel where possible.

Common Pitfalls & Solutions

1. Long-running workflows: set timeouts using `timeout-minutes: 30`. 2. Cache dependencies to speed up builds. 3. Use `actions/cache` for npm, pip, and Docker layers. 4. Pin action versions with SHA hashes for security.

Conclusion

GitHub Actions provides a powerful, flexible CI/CD platform tightly integrated with your code. Start with the basic Node.js pipeline above, then add Docker builds and automated deployment as your needs grow.

Published on June 7, 2026 ยท Filed under DevOps

โ† Back to Blog