ELASYN — Home
Products
Insights
About
Contact
Get in touch
HomeELASYN
    • Custom Software & SaaS
    • AI & Intelligent Systems
    • DevOps & Cloud
    • Automation & Workflows
    • API & Integrations
    • Performance
    • View all services
  • Products
  • Case Studies
  • Insights
  • About
  • Glossary
  • Support
  • Contact
Get in touch

“The best way to predict the future is to invent it.”

— Alan Kay

© 2026 ELASYN Pty Ltd. All rights reserved.

  1. Home
  2. /Insights
  3. /DevOps
DevOps

CI/CD Pipeline Setup for Beginners: A Practical Guide for Real Teams

ELASYN Engineering·1 April 2026·13 min read

A CI/CD pipeline is not there to make your repository look mature.

It exists to remove avoidable mistakes from software delivery.

If your team is still relying on manual test runs, ad hoc deploys, or SSH sessions directly into production, you do not have a release process. You have a sequence of personal habits that will eventually fail under pressure.

This guide covers how to set up CI/CD properly without turning it into a science project.

What CI/CD means in practice

The terminology is worth defining plainly before anything else.

  • Continuous Integration means every change is validated quickly and consistently. Automated checks run on every push and pull request.
  • Continuous Delivery means the software is always in a deployable state. Any passing build can be released at any time.
  • Continuous Deployment means deployment to production happens automatically once the required checks pass, without human sign-off.

Most Australian SMEs should aim for continuous delivery first. Full automatic production deployment can come later, once the application, tests, and rollback paths are trustworthy.

GitHub Actions operates on this model: YAML workflow files committed in .github/workflows define jobs triggered by repository events: pushes, pull requests, or scheduled intervals. Each job runs steps on a hosted runner.

OWASP defines CI/CD as "largely automated processes used to build and deliver software," noting that CI focuses on build and test automation, while delivery and deployment deal with promotion into higher environments.

Why small teams still need CI/CD

There is a common mistake in smaller businesses:

"We only have two developers, so we do not need a pipeline yet."

That reasoning is backwards.

Small teams benefit from CI/CD earlier because every manual step consumes a larger percentage of total engineering time. The fewer people you have, the more expensive rework becomes. One botched manual deploy in a two-person team takes out half the engineering capacity for an afternoon.

A working pipeline gives you:

  • Repeatable releases with no steps that only one person remembers
  • Earlier defect detection before code reaches production
  • Fewer "works on my machine" failures across environments
  • Visibility into exactly what changed between releases
  • Safer rollouts with defined rollback paths
  • Less operational stress during launch windows

DORA's research programme has spent more than a decade measuring high-performing technology teams. Its four key metrics (deployment frequency, lead time for changes, change failure rate, and time to restore) have become the standard reference for software delivery performance. The point is not ceremony. The point is control.

The minimum viable pipeline

For most web applications, the first useful pipeline is small.

You do not need twelve stages and five approval gates. You need the checks that prevent bad code from advancing.

A good starting pipeline does these things in order:

  1. Checkout code from the repository
  2. Install dependencies reproducibly
  3. Run static analysis and linting
  4. Run the test suite
  5. Build the application
  6. Publish artefacts if needed
  7. Deploy to a staging environment
  8. Deploy to production with appropriate controls

The pipeline shape ELASYN recommends

For an SME shipping line-of-business software, internal tools, or a SaaS product, this is the pattern that stays useful as the team grows.

Pull request checks

Run on every pull request:

  • Dependency installation
  • Linting and formatting
  • Type checking
  • Unit tests
  • Build verification

This stage answers one question: can this change be merged without breaking the application at a basic level?

Main branch integration

Run on merge to main:

  • Repeat critical checks
  • Package the build
  • Tag or version the artefact
  • Push the artefact to the deployment target or registry

This stage answers: do we have a reproducible build we can actually release?

Staging deployment

Deploy automatically to a staging environment that resembles production closely enough to be useful.

That means the same application configuration model, the same external dependencies where practical, the same build process, and the same infrastructure class, not a toy substitute that hides the exact failures you wanted it to catch.

This stage answers: does the system behave correctly outside the local machine?

Production deployment

Production should include controls appropriate to the business risk:

  • Manual approval for business-critical systems
  • Environment protection rules
  • Deployment concurrency control to avoid overlapping releases
  • Rollout visibility so someone can watch what is happening
  • A defined rollback procedure before deployment begins

GitHub explicitly documents environments, concurrency groups, protection rules, and deployment history as part of deployment control infrastructure.

A practical baseline with GitHub Actions

Below is a working baseline for a Node.js application. It is deliberately modest. That is the point.

name: ci-cd

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  quality:
    runs-on: ubuntu-latest

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

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Typecheck
        run: npm run typecheck --if-present

      - name: Test
        run: npm test -- --runInBand

      - name: Build
        run: npm run build

  deploy-staging:
    if: github.event_name == 'push'
    needs: quality
    runs-on: ubuntu-latest
    environment: staging

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

      - name: Deploy to staging
        run: ./scripts/deploy-staging.sh

  deploy-production:
    if: github.event_name == 'push'
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production

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

      - name: Deploy to production
        run: ./scripts/deploy-production.sh

This is not meant to be copied unchanged into every project. It shows the shape of a clean pipeline: quality gates before deployment, staging before production, and separate environment blocks with independent protection rules.

What beginners usually get wrong

1. Automating deployment before automating quality

If the pipeline can deploy broken code faster, that is not progress.

Start with the checks that protect code quality. Deployment automation matters after the build is trustworthy. A pipeline that deploys an untested codebase in thirty seconds is worse than no pipeline at all. It gives false confidence.

2. Skipping build verification

A passing test suite is not enough. The application still needs to build successfully in a production-like environment. This matters especially for TypeScript applications with separate type and build steps, frontend builds with environment-specific behaviour, Docker-based deployments, and applications with generated assets or codegen steps.

3. Hardcoding secrets

Do not place credentials in workflow files, .env files committed to the repository, or shell scripts copied between team members.

Use platform-managed secrets, short-lived credentials where possible, and explicit environment separation. GitHub provides secrets, OIDC tokens, and environment-level access controls for exactly this purpose. OWASP also treats CI/CD infrastructure as an attack target in its own right. The pipeline itself needs protecting, not just the application being built.

4. Deploying from one branch without guardrails

Automation without controls is just faster failure. Use branch protection, required status checks, deployment approvals for sensitive environments, and concurrency rules to prevent overlapping production releases.

5. Building the pipeline too large too early

Do not start with full end-to-end test suites on every commit, multi-environment promotion across five stages, or heavy security scans on every change. A pipeline should reduce friction. If it becomes the bottleneck, teams start bypassing it, which defeats the purpose entirely.

Security is part of CI/CD, not an optional extra

OWASP's CI/CD Security Cheat Sheet is direct on this point: pipelines sit in the path between source code and production, which makes them an attractive target. Your pipeline can become part of the attack surface if it is not treated with the same care as the application it builds.

A practical baseline includes:

  • Least-privilege access for runners and tokens
  • Environment-scoped credentials that cannot cross environment boundaries
  • Dependency review for third-party packages
  • Supply chain awareness for external GitHub Actions
  • A clear audit trail for every production release

This matters more now that software supply chain risk is explicitly named among the major application security categories. Review what runs in your pipeline with the same scrutiny you would apply to production dependencies.

What a useful staging environment looks like

A staging environment is not just another server.

It should answer specific questions before production releases:

  • Does the deployment script actually work, or does it only work locally?
  • Do database migrations run safely against a real schema?
  • Does the application boot correctly with production-like configuration?
  • Do external integrations still behave as expected?
  • Can the team verify the release before customers see it?

If staging is too different from production, it will hide the exact failures you set it up to catch. A staging environment that runs on a different runtime, skips migrations, or uses a different configuration model is worse than no staging environment. It creates false confidence.

How to measure whether the pipeline is working

Do not measure success by line count in YAML files.

Measure these things:

  • How often can the team deploy safely?
  • How long does a change take from merge to production?
  • How often does a deployment cause an incident?
  • How quickly can the team recover from a bad release?

Those are the operational questions that matter to the business. A pipeline that scores well on all four is doing its job.

When to add more sophistication

Once the baseline works reliably, add depth where it solves a real problem:

  • Integration tests for critical user flows
  • Ephemeral preview environments for feature branches
  • Container image scanning
  • Database migration dry-runs
  • Infrastructure-as-Code validation (Terraform plan in CI)
  • Performance smoke tests against staging
  • Canary or blue-green deployment patterns
  • Release approvals tied to measured risk, not habit

The order matters. Do the next thing that removes the next real source of deployment risk. Do not add sophistication because it looks good in a job description.

The recommendation

If your current release process involves a person remembering a checklist from memory, your team needs CI/CD now.

Start with one repository, one workflow, one staging environment, and one production path that is visible, repeatable, and reversible.

That is enough to move software delivery from individual effort to system behaviour. And that is the real point.


References

  1. GitHub Docs. GitHub Actions documentation
  2. GitHub Docs. Building and testing Node.js
  3. GitHub Docs. Writing workflows
  4. GitHub Docs. Understanding GitHub Actions
  5. OWASP Cheat Sheet Series. CI/CD Security Cheat Sheet
  6. Google Cloud Blog. Announcing the 2024 DORA report
  7. GitHub Docs. Deploying with GitHub Actions

More from the engineering team

DevOps18 Feb 2026·12 min read

DevOps pipeline from zero to production in 2 weeks

A step-by-step guide to building a CI/CD pipeline with GitHub Actions, Docker, and AWS , from first commit to automated deployment.

Read article
DevOps19 Mar 2026·12 min read

Kubernetes: What It Is, When It Matters, and When It Is Too Much

Kubernetes is neither a badge of technical maturity nor something only enterprise teams should touch. It is an orchestration platform. The correct question is not whether modern teams use it: it is what operational problem your system actually has.

Read article
Engineering2 Apr 2026·12 min read

EmDash vs WordPress: what Cloudflare's new CMS means for Australian businesses

Cloudflare's EmDash is not just another WordPress clone with a fresh coat of paint. It is built around structured content, sandboxed plugins, and AI-native workflows. Here is what that actually means for your business.

Read article

Need engineering help?

We build the systems we write about. If your project needs the expertise behind these articles, let's talk.

Start a conversation
ELASYN

Software and cloud engineering for Australian businesses. Based in Brisbane, serving nationally.

Services

  • Custom Software
  • AI Systems
  • DevOps & Cloud
  • Automation
  • API & Integration
  • Performance

Resources

  • Insights
  • Case Studies
  • FAQ
  • Glossary

Company

  • Products
  • About
  • Contact
  • Support

Legal

  • Terms & Conditions
  • Privacy Policy

© 2026 ELASYN Pty Ltd. All rights reserved.

ELASYN