What GitHub Actions is and why you don’t need a separate CI server anymore

Previously, to automate code testing, you had to:

GitHub Actions solves this differently: you just add a YAML file to your repository — and GitHub runs tests, builds, and deploys on its own servers. Nothing to install, nothing to administer.

Simply put: you describe what needs to be done. GitHub does it for you.

The problem / context: why lack of automation is a risk

Without CI (Continuous Integration), everything works manually: someone makes a commit, someone else locally runs tests, and it ends with “seems to work.” But when:

the manual process becomes a bottleneck. Someone forgets to run tests, someone skips checking dependencies, and broken code goes to production at the worst possible moment.

GitHub Actions ensures every commit is automatically tested. It’s not up to a person to decide whether to test — it happens every time.

How it works in simple terms

GitHub Actions follows this model:

1. Workflow — describing what needs to happen

This is a YAML file in the .github/workflows/ folder of your repository. For example, .github/workflows/test.yml:

name: Run tests
on:
  push:
    branches: [main, master]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
        node-version: '20'
      - run: npm ci
      - run: npm test

Breaking it down:

2. GitHub detects changes and starts running

When someone pushes code to main, GitHub finds the YAML file, reads it, and triggers the workflow. On the Actions tab in your repository, you’ll see the status: green ✓ (success) or red ✗ (failure).

3. The runner executes each step

GitHub provisions a virtual server (runner), clones your repository, runs each step in sequence, and reports success or failure.

4. Dependencies between jobs

If you need to build before testing:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build

  test:
    needs: build  # test waits for build to finish
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test

Most common scenarios

1. Automated code testing

The simplest and most useful starting point. Every commit — automatic tests. If tests fail, you find out immediately, not a month later.

2. Deploy to production after tests

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - run: ./deploy.sh
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Secrets (secrets.DEPLOY_TOKEN) are stored in repository settings and never end up in your code.

3. Deploy to staging on pull request

  deploy-staging:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - run: ./deploy-staging.sh

This way you can preview changes on a test server before merging into the main branch.

4. Scheduled tasks — cron

  nightly:
    runs-on: ubuntu-latest
    on:
      schedule:
        - cron: '0 2 * * *'  # daily at 02:00 UTC
    steps:
      - run: ./nightly-check.sh

Common mistakes

1. Hardcoding secrets in the workflow

Tokens, passwords, and keys should never be in YAML. Use secrets. — they are stored in repository settings and don’t appear in commit history.

2. Ignoring action versions

actions/checkout@v4 is a specific version. Don’t write actions/checkout@main or @latest — things can change and break your workflow. Pin your versions.

3. Running everything on one runner

If a workflow does the build, tests, and deploy all on one server — a failure in one step ruins everything. Split into separate jobs.

4. Not checking whether the workflow works at all

Created the file — make sure GitHub actually picked it up. The Actions tab should show a run. If it’s empty, check the file path and YAML syntax.

5. Using outdated images

ubuntu-latest updates over time, but specific versions like ubuntu-20.04 can become unavailable. Always check supported images on the GitHub docs.

Conclusion / action plan

GitHub Actions is the simplest way to add CI/CD to your project without a separate server. A single file in your repository — and everything works.

What to do next:

  1. Create .github/workflows/ in your repository.
  2. Add your first workflow with tests and push to any branch.
  3. Check the Actions tab — did the workflow start and pass?
  4. Add staging deployment when a pull request is created.
  5. Save secrets in Settings → Secrets — never hardcode them in YAML.

Automation isn’t a “when we grow up” thing. It’s a “from day one” thing, and GitHub Actions makes it practically free.