Continuous integration and continuous deployment have gone from nice-to-have to non-negotiable for professional software teams. Yet many organizations still resist adopting CI/CD because of the perceived complexity and cost of tools like Jenkins, CircleCI, or GitLab CI. GitHub Actions changes this equation entirely. It is built directly into GitHub, offers generous free tier minutes, and provides a workflow model that is both powerful and approachable.

At StrikingWeb, we have standardized on GitHub Actions for our client projects. The tight integration with GitHub repositories, the extensive marketplace of pre-built actions, and the YAML-based configuration make it our preferred choice for automating everything from linting to production deployments.

Understanding the GitHub Actions Model

GitHub Actions uses a hierarchy of concepts: workflows, jobs, steps, and actions. Understanding how these pieces fit together is essential before writing your first workflow file.

A workflow is a YAML file stored in .github/workflows/ in your repository. Each workflow responds to specific events — pushes, pull requests, scheduled times, or manual triggers. A workflow contains one or more jobs, which run in parallel by default on separate virtual machines. Each job consists of steps, which are individual commands or actions — reusable units of automation from the marketplace or your own repository.

Your First Workflow

A basic CI workflow that runs tests on every push and pull request looks like this:

name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: 'npm'
      - run: npm ci
      - run: npm test

This simple file accomplishes what would require a dedicated CI server, configuration management, and ongoing maintenance with traditional tools. It runs on GitHub's hosted runners, caches dependencies for fast builds, and reports results directly on pull requests.

Essential Workflow Patterns

Through our work across dozens of projects, we have identified several workflow patterns that we implement on nearly every repository.

Matrix Testing

Matrix builds let you test against multiple versions of languages, operating systems, or dependencies in parallel. This is invaluable for libraries and tools that need to support multiple environments:

strategy:
  matrix:
    node-version: [16, 18, 20]
    os: [ubuntu-latest, windows-latest]

Each combination runs as a separate job, giving you comprehensive compatibility testing without sequential execution. A 3x2 matrix runs six jobs simultaneously rather than taking six times as long.

Conditional Deployment

Production deployments should only happen when specific conditions are met — merges to the main branch, successful tests, and sometimes manual approval. GitHub Actions supports this through job dependencies, environment protection rules, and conditional expressions:

deploy:
  needs: [test, lint, build]
  if: github.ref == 'refs/heads/main'
  environment: production
  runs-on: ubuntu-latest

The needs keyword ensures the deploy job only runs after test, lint, and build jobs succeed. The if condition restricts it to the main branch. The environment keyword connects it to GitHub's environment protection rules, which can require manual approvals and restrict which branches can deploy.

Caching and Performance

Build times directly affect developer productivity. GitHub Actions provides several caching mechanisms to avoid redundant work:

The GitHub Actions Marketplace

The marketplace is one of GitHub Actions' strongest features. With thousands of pre-built actions, you can add capabilities to your workflows without writing custom scripts.

Actions We Use on Every Project

After evaluating hundreds of marketplace actions, our standard toolkit includes:

Building Custom Actions

When marketplace actions do not meet your needs, building custom actions is straightforward. Actions can be written in JavaScript (using the @actions/core and @actions/github packages), as Docker containers, or as composite actions that combine multiple steps into a reusable unit.

Composite actions are our preferred approach for team-specific automation. They live in a shared repository and can be referenced across all projects, ensuring consistency in how we run deployments, send notifications, or perform code quality checks.

Deployment Strategies

GitHub Actions supports any deployment target, from simple static site hosting to complex Kubernetes orchestrations. Here are the strategies we implement most frequently.

Static Site Deployment

For static sites built with Next.js, Gatsby, or plain HTML, we deploy directly to AWS S3 with CloudFront invalidation, Vercel, or Netlify. The workflow builds the site, uploads assets, and invalidates the CDN cache — all in under two minutes.

Container Deployment

For containerized applications, the workflow builds a Docker image, pushes it to Amazon ECR or GitHub Container Registry, and triggers a deployment to ECS, EKS, or a similar orchestration platform. We use environment-specific tags and rolling deployments to minimize downtime.

Multi-Environment Pipelines

Production applications need staging environments for testing before release. We structure workflows with separate jobs for each environment, using GitHub environments for approval gates:

A well-designed pipeline deploys to staging automatically on every merge to main, runs integration tests against staging, and then waits for manual approval before promoting to production. This gives your team confidence without sacrificing velocity.

Security Best Practices

CI/CD pipelines have access to your source code, deployment credentials, and production infrastructure. Securing them is critical.

Cost Optimization

GitHub Actions is free for public repositories and includes 2,000 minutes per month for private repositories on the free plan. For most teams, this is more than sufficient. However, as your usage grows, understanding the billing model helps optimize costs.

Linux runners are the cheapest option at 1x pricing. macOS runners cost 10x and Windows runners cost 2x. If you need macOS for iOS builds, consider running only the platform-specific steps on macOS and handling everything else on Linux. Self-hosted runners eliminate per-minute costs entirely and give you more control over the execution environment.

Getting Started

If your team is not yet using CI/CD, start with a simple test workflow. The immediate feedback loop — seeing test results on every pull request — changes how your team thinks about code quality. From there, add linting, security scanning, and automated deployments incrementally.

At StrikingWeb, we set up GitHub Actions workflows as part of every project engagement. Whether you need a basic CI pipeline or a complex multi-environment deployment strategy, we build pipelines that run reliably and scale with your team. Reach out if you would like us to automate your development workflow.

Share: