CI/CD Pipeline Configuration in open-seo: Complete GitHub Actions Guide

The open-seo repository uses four GitHub Actions workflows—CI, Docker image build, sourcemap upload, and PR preview—to automate testing, building, and deploying on every push and pull request.

This guide walks through the complete CI/CD pipeline configuration in open-seo, an open-source SEO tool built by every-app. Every workflow lives in .github/workflows and runs on GitHub Actions, providing a fully automated path from code commit to production deployment. Whether you are extending the project or adapting these patterns for your own repository, understanding the workflow architecture is essential.

Core CI Workflow: Testing and Validation

The CI workflow (ci.yml) serves as the entry point for all code changes. It triggers on every push to main and every pull request, ensuring that no broken code reaches the default branch.

The workflow performs the following sequence:

  1. Install dependencies using pnpm with frozen lockfile enforcement
  2. Run lint and type-check via ci:check
  3. Execute unit tests with test:ci
  4. Build the Vite-based worker bundle for the core application
  5. Compile the website from the web/ directory

Each step mirrors commands you can run locally:

pnpm install --frozen-lockfile
pnpm run ci:check
pnpm run test:ci
pnpm vite build
pnpm --dir web install && pnpm --dir web run build

The workflow uses actions/setup-node@v4 with cache: pnpm to speed up dependency installation across runs.

Docker Image Build: Multi-Architecture Publishing

The Docker workflow (docker-image.yml) produces reproducible container images for self-hosting. It triggers on pushes to main or any v* tag, plus manual dispatch via workflow_dispatch.

Key technical characteristics:

  • Multi-architecture support using QEMU and Buildx for linux/amd64 and linux/arm64
  • GitHub Container Registry (GHCR) as the push target
  • Docker build cache via type=gha for faster rebuilds
  • Automatic metadata generation with docker/metadata-action@v5

The build uses Dockerfile.selfhost rather than the default Dockerfile, producing images tagged with both semantic versions and latest.

Trigger manually when needed:

gh workflow run docker-image.yml --ref main

Sourcemap Upload: Production Error Tracking

The sourcemaps workflow (sourcemaps.yml) runs exclusively on main branch pushes. It compiles JavaScript sourcemaps and uploads them to PostHog, enabling de-obfuscation of production stack traces.

This workflow requires the POSTHOG_CLI_TOKEN secret and executes after the main build completes. Sourcemaps bridge the gap between minified production code and readable source, making runtime error investigation practical.

PR Preview: On-Demand Staging Environments

The PR preview workflow (pr-preview.yml) deploys temporary staging environments on Cloudflare Workers for every pull request. It responds to opened, synchronize, reopened, and closed events.

Deployment lifecycle:

  1. Extract configuration from ENV_PREVIEW secret (contains .env.preview content including WORKERS_SUBDOMAIN)
  2. Deploy to Cloudflare Workers using Wrangler with a stage name derived from the PR number
  3. Verify Cloudflare Access protection is active on the preview URL
  4. Post PR comment with the preview URL for reviewer access
  5. Teardown on close when the PR is merged or abandoned

Access the preview from the comment:


# Posted comment format:

# **Preview deployed** (stage `pr-12`): https://open-seo-pr-12.example.workers.dev

curl -I https://open-seo-pr-12.example.workers.dev

Shared Workflow Architecture

All four workflows in open-seo share common architectural patterns that ensure reliability and performance.

Concurrency Control

Every workflow declares a concurrency block to prevent redundant runs:

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

This ensures only the latest run for any given branch or PR executes, automatically cancelling stale jobs.

Secrets and Environment Variables

Sensitive configuration flows through GitHub's secrets system:

  • POSTHOG_CLI_TOKEN: Sourcemap upload authentication
  • CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN: Workers deployment credentials
  • ENV_PREVIEW: Complete .env.preview file for staging configuration

Non-sensitive values use ${{ vars... }} where appropriate.

Caching Strategy

Two caching layers accelerate the pipeline:

Layer Implementation Benefit
Node dependencies actions/setup-node@v4 with cache: pnpm ~30-60s saved per run
Docker layers type=gha Buildx cache Faster multi-arch builds

Workflow File Reference

File Purpose Trigger Events
.github/workflows/ci.yml Install, lint, test, build push to main, all PRs
.github/workflows/docker-image.yml Multi-arch image build and push push to main or v* tags, workflow_dispatch
.github/workflows/sourcemaps.yml Build and upload PostHog sourcemaps push to main
.github/workflows/pr-preview.yml Deploy and manage PR staging environments PR opened, synchronize, reopened, closed

Summary

  • Four workflows handle the complete CI/CD lifecycle in open-seo: CI validation, Docker publishing, sourcemap upload, and PR preview deployment
  • Concurrency controls prevent redundant runs and race conditions across all workflows
  • Multi-architecture Docker builds ensure images run on both AMD64 and ARM64 infrastructure
  • Automated PR previews on Cloudflare Workers give reviewers live staging URLs without manual intervention
  • Secrets-based configuration keeps credentials out of source code while enabling Cloudflare and PostHog integrations

Frequently Asked Questions

How do I run the CI checks locally before pushing?

Execute the same commands defined in ci.yml: pnpm install --frozen-lockfile, pnpm run ci:check, pnpm run test:ci, and the build commands for both the worker and website. This validates your changes without waiting for GitHub Actions.

What triggers a new Docker image build?

The Docker workflow runs automatically on any push to main or a version tag matching v*. You can also trigger it manually with gh workflow run docker-image.yml --ref main for testing or emergency rebuilds.

Where are the PR preview URLs posted?

The pr-preview.yml workflow automatically posts a comment on each pull request containing the deployed preview URL. The URL follows the pattern https://open-seo-pr-{NUMBER}.{SUBDOMAIN}.workers.dev derived from your WORKERS_SUBDOMAIN configuration.

Why does sourcemap upload only run on main branch pushes?

Sourcemaps are only needed for production error tracking, and production deployments originate from main. Running this on every PR would create unnecessary uploads and consume PostHog quota without providing value, since preview deployments use separate build configurations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →