GitHub Actionsdevops

Why GitHub & GitHub Actions

Code hosting and CI/CD in one platform

v1.1·9 min read·Kenneth Pernyér
githubci-cdautomationdevopsgit

The Problem

Software development requires multiple services: code hosting, CI/CD, issue tracking, code review, artifact storage. Traditionally, these were separate tools:

  • GitHub/GitLab/Bitbucket for code
  • Jenkins/CircleCI/TravisCI for CI/CD
  • Jira/Linear for issues
  • Artifactory/S3 for artifacts

Each integration is a potential failure point. Each service is another login, another bill, another thing to maintain.

Platform consolidation reduces operational overhead.

We needed a platform that:

  • Hosts code with excellent collaboration tools
  • Runs CI/CD natively, no external service
  • Integrates with the tools we already use
  • Has the ecosystem and community we need

Current Options

OptionProsCons
GitHub + External CIGitHub for code, Jenkins/CircleCI for CI.
  • Best-of-breed for each function
  • CI tool flexibility
  • GitHub collaboration features
  • Multiple services to manage
  • Integration complexity
  • Context switching between tools
  • More potential failure points
GitLabAll-in-one platform: code, CI, issues, registry.
  • Everything in one place
  • Self-hosting option
  • Built-in container registry
  • Comprehensive DevOps features
  • Smaller ecosystem than GitHub
  • UI can feel cluttered
  • Community is smaller
  • Enterprise pricing is steep
GitHub + GitHub ActionsNative CI/CD in the largest code hosting platform.
  • Largest developer community
  • Actions marketplace (reusable workflows)
  • Tight integration with code
  • Free for public repos, generous free tier
  • Actions YAML can get complex
  • Runner minutes cost money at scale
  • Microsoft ownership concerns some
  • Less self-hosting flexibility

Future Outlook

GitHub has won code hosting. The question is whether to use their native CI/CD or bolt on something else.

Actions is good enough—and getting better.

GitHub Actions started rough but has matured significantly. Reusable workflows, composite actions, and the marketplace make it genuinely powerful. For most projects, there's no reason to add Jenkins complexity.

The trend is toward platform consolidation. Fewer tools, fewer integrations, fewer things to break. GitHub + Actions + Packages + Issues covers 90% of needs.

AI is accelerating this. GitHub Copilot, Copilot for PRs, and AI-powered code review are all GitHub-native. The platform advantage compounds.

Our Decision

Why we chose this

  • Native integrationWorkflows trigger on any GitHub event. No webhooks to configure.
  • Actions marketplaceThousands of reusable actions. Most integrations are one line.
  • Matrix buildsTest across OS, Node version, browser combinations easily.
  • Generous free tierPublic repos unlimited. Private repos get 2000 minutes/month free.

×Trade-offs we accept

  • YAML complexityComplex workflows become hard to maintain. Extract to composite actions.
  • Minutes costHeavy CI usage on private repos can get expensive. Cache aggressively.
  • DebuggingDebugging workflow failures is harder than local CI. Use act for local testing.

Motivation

We use GitHub for everything: code, issues, CI/CD, packages, project management. One platform, one login, one bill.

This isn't about GitHub being best at everything. It's about reducing integration overhead. When CI runs in the same platform as code review, context is preserved. When issues link to PRs automatically, tracking is effortless.

For AI-assisted development, GitHub's integrations are unmatched. Copilot suggestions during code review, automated PR descriptions, AI-powered security scanning—all native.

Recommendation

Repository setup:

  • Enable branch protection on main
  • Require PR reviews and status checks
  • Enable Dependabot for security updates
  • Use CODEOWNERS for automatic reviewers

CI/CD patterns:

  • Use caching aggressively (bun install is fast, but cached is faster)
  • Run lint/typecheck/test in parallel
  • Deploy on merge to main, not on PR
  • Use environments for staging/production separation

Cost optimization:

  • Cache dependencies between runs
  • Use larger runners for build-heavy jobs (faster = cheaper)
  • Self-hosted runners for very high volume

Examples

.github/workflows/ci.ymlyaml
name: CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: oven-sh/setup-bun@v1
        with:
          bun-version: latest

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Typecheck
        run: bun run typecheck

      - name: Lint
        run: bun run lint

      - name: Test
        run: bun test

  build:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v1
      - run: bun install --frozen-lockfile
      - run: bun run build
      - uses: actions/upload-artifact@v4
        with:
          name: build
          path: dist/

Complete CI workflow for a Bun project. Tests run on every PR, build artifacts are uploaded. Parallel jobs, caching, and proper dependency ordering.

.github/workflows/deploy.ymlyaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - uses: oven-sh/setup-bun@v1

      - run: bun install --frozen-lockfile
      - run: bun run build

      - name: Deploy to production
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
        run: |
          echo "Deploying to production..."
          # Your deployment script here

Deploy workflow with environment protection. Only runs on main branch. Secrets are scoped to the production environment.

Related Articles

Stockholm, Sweden

Version 1.1

Kenneth Pernyér signature