NIXX/DEVv1.14.0
ArticlesFavorites
Sign In
Sign In
Articles

Welcome to our blog

A curated collection of insightful articles, practical guides, and expert tips designed to simplify your workflow

Cover image for: From Zero to CI/CD: Building Your First Pipeline with GitHub Actions
June 16, 20255 MIN READ min readBy ℵi✗✗

From Zero to CI/CD: Building Your First Pipeline with GitHub Actions

Step-by-step guide for developers who want to automate testing, building, and deployment.

webdevci cdautomationgithub actions
ℵi✗✗

ℵi✗✗

Full-Stack Developer

Passionate about building tools and sharing knowledge with the developer community.

Was this helpful?

Popular Posts

  • NixOS vs. Arch Linux: Which One Belongs in Your Dev Setup?

    NixOS vs. Arch Linux: Which One Belongs in Your Dev Setup?

    5 MIN READ min read

  • How to Enable HTTPS on Localhost in Under 2 Minutes

    How to Enable HTTPS on Localhost in Under 2 Minutes

    3 MIN READ min read

  • Migrating from Create React App (CRA) to Vite: A Step-by-Step Guide

    Migrating from Create React App (CRA) to Vite: A Step-by-Step Guide

    4 MIN READ min read

  • Array Destructuring in PHP: A Practical Guide for Modern Developers

    Array Destructuring in PHP: A Practical Guide for Modern Developers

    5 MIN READ min read

Recommended Products

  • Apple iPad (7th Gen)

    Apple iPad (7th Gen)

    4.3
  • Fitbit Versa 4

    Fitbit Versa 4

    4.3
  • JBL Flip 6

    JBL Flip 6

    4.8
  • Dell 24 Monitor — SE2425HM Full HD

    Dell 24 Monitor — SE2425HM Full HD

    4.7

May contain affiliate links

Topics

webdev33productivity16cybersecurity12javascript11automation9guide8react7typescript7php6tutorial6freelancing5github actions5privacy5how to4Node.js4
+111 more topics →
🇺🇸USD ACCOUNTOpen a free US-based USD accountReceive & save in USD — powered by ClevaSponsoredInterserver Hosting#1 VALUEAffordable, reliable hosting from $2.50/mo99.9% uptimeSponsored

Manually testing code, building the app, and deploying it by hand works until it doesn't. The process is slow, error-prone, and gets harder to maintain as a project grows. One missed step or a distracted moment during deployment can push a broken build to production.

CI/CD — Continuous Integration and Continuous Delivery — solves this by automating the sequence. Code gets pushed, tests run, the build is verified, and deployment happens without manual intervention. GitHub Actions brings this directly into GitHub, so there is no separate CI platform to set up or maintain.

This guide builds a working pipeline from scratch: a basic test workflow first, then an extended build-and-deploy workflow, then a set of additions worth knowing about once the foundation is in place.

What this covers:

  • Core CI/CD concepts and GitHub Actions terminology

  • Writing a basic test workflow

  • Extending it to build and deploy

  • Debugging and monitoring pipelines

  • Useful additions: caching, linting, conditional logic, notifications


Core Concepts Before Writing Code

GitHub Actions workflows are YAML files stored in the .github/workflows directory of a repository. Understanding five terms makes the rest of the guide easier to follow:

Term

What it means

Workflow

The full automated process, defined in a single .yml file

Job

A group of steps that run together on the same virtual machine

Step

A single task within a job — either a shell command or a reusable action

Action

A reusable unit of code that performs a specific function (e.g., checking out code)

Runner

The virtual machine that executes the job — GitHub-hosted or self-hosted

A workflow is analogous to a recipe. Jobs are the major stages (test, build, deploy). Steps are the individual instructions within each stage. The runner is the machine that carries them out.

GitHub Actions is free for public repositories and includes a generous monthly allocation of free minutes for private ones.


Step 1: Create the Workflow File

All workflows live in .github/workflows/ in the repository root. Create that directory if it does not already exist, then create a file called test.yml.

name: Run Tests

on:
  push:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Set Up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install Dependencies
        run: npm install

      - name: Run Tests
        run: npm test

What this workflow does:

  • Triggers on every push to the main branch

  • Spins up an Ubuntu runner

  • Checks out the repository code

  • Installs Node.js 18

  • Installs project dependencies

  • Runs the test suite

The npm test command can be replaced with whatever runs your tests: pytest, phpunit, bundle exec rspec, or a custom shell script. The structure stays the same regardless of language.

Commit this file and push it. GitHub will detect the workflow automatically and run it against the push.


Step 2: Extend the Workflow to Build and Deploy

Once tests pass reliably, the next step is automating the build and deployment. The following workflow extends the test steps and adds SSH-based deployment to a remote server:

name: Build and Deploy

on:
  push:
    branches:
      - main

jobs:
  build-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Set Up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install Dependencies
        run: npm install

      - name: Run Tests
        run: npm test

      - name: Build App
        run: npm run build

      - name: Deploy to Server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
          port: 22
          script: |
            cd /var/www/myapp
            git pull origin main
            npm install
            npm run build
            pm2 restart dist/index.js

The ${{ secrets.HOST }}, ${{ secrets.USERNAME }}, and ${{ secrets.PASSWORD }} references pull from GitHub Secrets — encrypted values stored in the repository settings under Settings, Secrets and variables, Actions. Never hardcode credentials directly in a workflow file.

To add a secret: go to the repository settings, navigate to Secrets and variables, and click New repository secret. The value is encrypted and only exposed to workflow runs — it is never visible in logs.


Step 3: Monitor and Debug

Once the workflow file is pushed, every subsequent push to main triggers a run. The Actions tab in the repository shows the run history, status, and step-by-step logs.

Useful debugging approaches when a workflow fails:

  • Read the failed step's log output carefully — GitHub Actions logs are verbose and usually identify the exact line that failed

  • Add echo statements to print environment variable values during a run if something is behaving unexpectedly

  • Use the act CLI tool to run workflows locally before pushing, which speeds up the iteration cycle when debugging complex workflows

  • Check that secrets are set correctly — a missing or misspelled secret name causes authentication steps to fail silently


Step 4: Useful Additions Once the Foundation Works

With a working test-build-deploy pipeline in place, the following additions improve reliability and developer experience.

Caching Dependencies

Re-downloading node_modules on every run adds time. Caching stores the result of the install step and reuses it when the lockfile has not changed:

- name: Cache node modules
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

Place this step before the install step. On cache hits, the install step completes in seconds rather than minutes.

Linting and Formatting Checks

Running a linter before tests catches style and syntax issues early and prevents them from reaching review:

- name: Run Linter
  run: npx eslint .

This works with any linter. Replace the command with black --check . for Python, rubocop for Ruby, or phpcs for PHP.

Conditional Deployment

Deploying only when pushing to main (not feature branches) prevents unintended deployments during development:

if: github.ref == 'refs/heads/main'

Add this condition at the job level to skip the deployment job on pushes to other branches while still running tests.

Build Failure Notifications

Getting a notification when a build fails without checking the Actions tab manually is worth setting up early:

- name: Send Slack Notification
  uses: rtCamp/action-slack-notify@v2
  env:
    SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
    STATUS: ${{ job.status }}

Store the Slack webhook URL as a secret. The job.status variable reflects whether the preceding steps succeeded or failed.


Key Takeaways

  • CI/CD automates the test-build-deploy sequence, removing the manual steps where errors most commonly occur.

  • GitHub Actions workflows are YAML files in .github/workflows/ — no external CI platform is required.

  • Sensitive credentials belong in GitHub Secrets, never in the workflow file itself.

  • Caching dependencies reduces build time significantly for projects with large dependency trees.

  • Conditional jobs and branch filters prevent the deploy stage from running on pushes that should not trigger a deployment.

  • Linting as a workflow step enforces code quality standards automatically before code reaches review.


Conclusion

A CI/CD pipeline built with GitHub Actions does not require infrastructure expertize or external services. The core concepts are straightforward, the YAML syntax is readable once the structure is familiar, and the feedback loop it creates — push code, get results within minutes — improves the quality and predictability of every release.

The workflow in this guide is a starting point. As the project grows, the pipeline can grow with it: additional test stages, environment-specific deployments, scheduled jobs, and more — all defined in version-controlled YAML files alongside the code they automate.


Working with a different stack or deployment target? Share the details in the comments.

Topics
webdevci cdautomationgithub actions
Interserver Hosting#1 VALUEAffordable, reliable hosting from $2.50/mo99.9% uptimeSponsored

Discussion

Join the discussion

Sign in to share your thoughts and engage with the community.

Sign In
Loading comments…

Continue Reading

More Articles

View all
Cover image for: Array Destructuring in PHP: A Practical Guide for Modern Developers
Mar 12, 20255 MIN READ min read

Array Destructuring in PHP: A Practical Guide for Modern Developers

From PHP 7.1 to 8.1—learn how array destructuring simplifies variable assignment, reduces boilerplate, and improves readability in modern PHP development.

Cover image for: The 3-Device Rule: How to Simplify Your Digital Life and Stop Overbuying Tech
Aug 5, 20255 MIN READ min read

The 3-Device Rule: How to Simplify Your Digital Life and Stop Overbuying Tech

Tired of juggling too many devices? Learn the 3-device rule that helps you streamline your digital life, reduce clutter, and focus on what really matters.

Cover image for: Embedding Cybersecurity in Development: Best Practices for 2025
Jul 1, 20257 MIN READ min read

Embedding Cybersecurity in Development: Best Practices for 2025

A developer-focused guide to integrating security into your workflow—covering tools, practices, and mindset shifts for 2025.

Cover image for: AI for DevOps: Tools That Are Already Changing the Game
Jun 17, 20256 MIN READ min read

AI for DevOps: Tools That Are Already Changing the Game

How artificial intelligence is transforming CI/CD pipelines, monitoring, and incident response—today.

|Made with · © 2026|TermsPrivacy
AboutBlogContact

Free, open-source tools for developers and creators · Community driven