# Gitea Actions CI/CD Setup This document describes the CI/CD pipeline configuration for the GlyphDiff project using Gitea Actions (GitHub Actions compatible). ## Table of Contents - [Overview](#overview) - [Workflow Files](#workflow-files) - [Workflow Triggers](#workflow-triggers) - [Setup Instructions](#setup-instructions) - [Self-Hosted Runner Setup](#self-hosted-runner-setup) - [Caching Strategy](#caching-strategy) - [Environment Variables](#environment-variables) - [Troubleshooting](#troubleshooting) ## Overview The CI/CD pipeline consists of four main workflows: 1. **Lint** - Code quality checks (oxlint, dprint formatting) 2. **Test** - Type checking and E2E tests (Playwright) 3. **Build** - Production build verification 4. **Deploy** - Deployment automation (optional/template) All workflows are designed to run on both push and pull request events, with appropriate branch filtering and concurrency controls. ## Workflow Files ### `.gitea/workflows/lint.yml` **Purpose**: Run code quality checks to ensure code style and formatting standards. **Checks performed**: - `oxlint` - Fast JavaScript/TypeScript linter - `dprint check` - Code formatting verification **Triggers**: - Push to `main`, `develop`, `feature/*` branches - Pull requests to `main` or `develop` - Manual workflow dispatch **Cache**: Node modules and Yarn cache **Concurrency**: Cancels in-progress runs for the same branch when a new commit is pushed. --- ### `.gitea/workflows/test.yml` **Purpose**: Run type checking and end-to-end tests. **Jobs**: #### 1. `type-check` job - `tsc --noEmit` - TypeScript type checking - `svelte-check --threshold warning` - Svelte component type checking #### 2. `e2e-tests` job - Installs Playwright browsers with system dependencies - Runs E2E tests using Playwright - Uploads test report artifacts (retained for 7 days) - Uploads screenshots on test failure for debugging **Triggers**: Same as lint workflow **Cache**: Node modules and Yarn cache **Artifacts**: - `playwright-report` - Test execution report - `playwright-screenshots` - Screenshots from failed tests --- ### `.gitea/workflows/build.yml` **Purpose**: Verify that the production build completes successfully. **Steps**: 1. Checkout repository 2. Setup Node.js v20 with Yarn caching 3. Install dependencies with `--frozen-lockfile` 4. Run `svelte-kit sync` to prepare SvelteKit 5. Build the project with `NODE_ENV=production` 6. Upload build artifacts (`.svelte-kit/output`, `.svelte-kit/build`) 7. Run the preview server and verify it responds (health check) **Triggers**: - Push to `main` or `develop` branches - Pull requests to `main` or `develop` - Manual workflow dispatch **Cache**: Node modules and Yarn cache **Artifacts**: - `build-artifacts` - Compiled SvelteKit output (retained for 7 days) --- ### `.gitea/workflows/deploy.yml` **Purpose**: Automated deployment pipeline (template configuration). **Current state**: Placeholder configuration. Uncomment and customize one of the deployment examples. **Pre-deployment checks**: - Must pass linting workflow - Must pass testing workflow - Must pass build workflow **Deployment examples included**: 1. **Docker container registry** - Build and push Docker image 2. **SSH deployment** - Deploy to server via SSH 3. **Vercel** - Deploy to Vercel platform **Triggers**: - Push to `main` branch - Manual workflow dispatch with environment selection (staging/production) **Secrets required** (configure in Gitea): - For Docker: `REGISTRY_URL`, `REGISTRY_USERNAME`, `REGISTRY_PASSWORD` - For SSH: `DEPLOY_HOST`, `DEPLOY_USER`, `DEPLOY_SSH_KEY` - For Vercel: `VERCEL_TOKEN`, `VERCEL_ORG_ID`, `VERCEL_PROJECT_ID` ## Workflow Triggers ### Branch-Specific Behavior | Workflow | Push Triggers | PR Triggers | Runs on Merge | | -------- | ------------------------------ | -------------------- | ------------- | | Lint | `main`, `develop`, `feature/*` | To `main`, `develop` | Yes | | Test | `main`, `develop`, `feature/*` | To `main`, `develop` | Yes | | Build | `main`, `develop` | To `main`, `develop` | Yes | | Deploy | `main` only | None | Yes | ### Concurrency Strategy All workflows use concurrency groups based on the workflow name and branch reference: ```yaml concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true # or false for deploy workflow ``` This ensures: - For lint/test/build: New commits cancel in-progress runs (saves resources) - For deploy: Prevents concurrent deployments (ensures safety) ## Setup Instructions ### Step 1: Verify Gitea Actions is Enabled 1. Navigate to your Gitea instance 2. Go to **Site Administration** → **Actions** 3. Ensure Actions is enabled 4. Configure default runner settings if needed ### Step 2: Configure Repository Settings 1. Go to your repository in Gitea 2. Click **Settings** → **Actions** 3. Enable Actions for the repository if not already enabled 4. Set appropriate permissions for read/write access ### Step 3: Push Workflows to Repository The workflow files are already in `.gitea/workflows/`. Commit and push them: ```bash git add .gitea/workflows/ git commit -m "Add Gitea Actions CI/CD workflows" git push origin main ``` ### Step 4: Verify Workflows Run 1. Navigate to **Actions** tab in your repository 2. You should see the workflows trigger on the next push 3. Click into a workflow run to view logs and status ### Step 5: Configure Secrets (Optional - for deployment) 1. Go to repository **Settings** → **Secrets** → **Actions** 2. Click **Add New Secret** 3. Add secrets required for your deployment method Example secrets for SSH deployment: ``` DEPLOY_HOST=your-server.com DEPLOY_USER=deploy DEPLOY_SSH_KEY=-----BEGIN OPENSSH PRIVATE KEY----- ... -----END OPENSSH PRIVATE KEY----- ``` ## Self-Hosted Runner Setup ### Option 1: Using Gitea's Built-in Act Runner (Recommended) Gitea provides `act_runner` (compatible with GitHub Actions runner). #### Install act_runner On Linux (Debian/Ubuntu): ```bash wget -O /usr/local/bin/act_runner https://gitea.com/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64 chmod +x /usr/local/bin/act_runner ``` Verify installation: ```bash act_runner --version ``` #### Register the Runner 1. In Gitea, navigate to repository **Settings** → **Actions** → **Runners** 2. Click **New Runner** 3. Copy the registration token 4. Run the registration command: ```bash act_runner register \ --instance https://your-gitea-instance.com \ --token YOUR_REGISTRATION_TOKEN \ --name "linux-runner-1" \ --labels ubuntu-latest,linux,docker \ --no-interactive ``` #### Start the Runner as a Service Create a systemd service file at `/etc/systemd/system/gitea-runner.service`: ```ini [Unit] Description=Gitea Actions Runner After=network.target [Service] Type=simple User=git WorkingDirectory=/var/lib/gitea-runner ExecStart=/usr/local/bin/act_runner daemon Restart=always RestartSec=5s [Install] WantedBy=multi-user.target ``` Enable and start the service: ```bash sudo systemctl daemon-reload sudo systemctl enable gitea-runner sudo systemctl start gitea-runner ``` #### Check Runner Status ```bash sudo systemctl status gitea-runner ``` Verify in Gitea: The runner should appear as **Online** with the `ubuntu-latest` label. ### Option 2: Using Self-Hosted Runners with Docker If you prefer Docker-based execution: #### Install Docker ```bash curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $USER ``` #### Configure Runner to Use Docker Ensure the runner has access to the Docker socket: ```bash sudo usermod -aG docker act_runner_user ``` The workflows will now run containers inside the runner's Docker environment. ### Option 3: Using External Runners (GitHub Actions Runner Compatible) If you want to use standard GitHub Actions runners: ```bash # Download and configure GitHub Actions runner mkdir actions-runner && cd actions-runner curl -o actions-runner-linux-x64-2.311.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz tar xzf ./actions-runner-linux-x64-2.311.0.tar.gz # Configure to point to Gitea instance ./config.sh --url https://your-gitea-instance.com --token YOUR_TOKEN ``` ## Caching Strategy ### Node.js and Yarn Cache All workflows use `actions/setup-node@v4` with built-in caching: ```yaml - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'yarn' ``` This caches: - `node_modules` directory - Yarn cache directory (`~/.yarn/cache`) - Reduces installation time from minutes to seconds on subsequent runs ### Playwright Cache Playwright browsers are installed fresh each time. To cache Playwright (optional optimization): ```yaml - name: Cache Playwright binaries uses: actions/cache@v4 with: path: ~/.cache/ms-playwright key: ${{ runner.os }}-playwright-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-playwright- ``` ## Environment Variables ### Default Environment Variables The workflows use the following environment variables: ```bash NODE_ENV=production # For build workflow NODE_VERSION=20 # Node.js version used across all workflows ``` ### Custom Environment Variables To add custom environment variables: 1. Go to repository **Settings** → **Variables** → **Actions** 2. Click **Add New Variable** 3. Add variable name and value 4. Set scope (environment, repository, or organization) Example for feature flags: ``` ENABLE_ANALYTICS=false API_URL=https://api.example.com ``` Access in workflow: ```yaml env: API_URL: ${{ vars.API_URL }} ENABLE_ANALYTICS: ${{ vars.ENABLE_ANALYTICS }} ``` ## Troubleshooting ### Workflows Not Running **Symptoms**: Workflows don't appear or don't trigger **Solutions**: 1. Verify Actions is enabled in Gitea site administration 2. Check repository Settings → Actions is enabled 3. Verify workflow files are in `.gitea/workflows/` directory 4. Check workflow YAML syntax (no indentation errors) ### Runner Offline **Symptoms**: Runner shows as **Offline** or **Idle** **Solutions**: 1. Check runner service status: `sudo systemctl status gitea-runner` 2. Review runner logs: `journalctl -u gitea-runner -f` 3. Verify network connectivity to Gitea instance 4. Restart runner: `sudo systemctl restart gitea-runner` ### Linting Fails with Formatting Errors **Symptoms**: `dprint check` fails on CI but passes locally **Solutions**: 1. Ensure dprint configuration (`dprint.json`) is committed 2. Run `yarn dprint fmt` locally before committing 3. Consider adding auto-fix workflow (see below) ### Playwright Tests Timeout **Symptoms**: E2E tests fail with timeout errors **Solutions**: 1. Check `playwright.config.ts` timeout settings 2. Ensure preview server starts before tests run (built into config) 3. Increase timeout in workflow: ```yaml - name: Run Playwright tests run: yarn test:e2e env: PLAYWRIGHT_TIMEOUT: 60000 ``` ### Build Fails with Out of Memory **Symptoms**: Build fails with memory allocation errors **Solutions**: 1. Increase Node.js memory limit: ```yaml - name: Build project run: yarn build env: NODE_OPTIONS: --max-old-space-size=4096 ``` 2. Ensure runner has sufficient RAM (minimum 2GB recommended) ### Permission Denied on Runner **Symptoms**: Runner can't access repository or secrets **Solutions**: 1. Verify runner has read access to repository 2. Check secret names match exactly in workflow 3. Ensure runner user has file system permissions ### Yarn Install Fails with Lockfile Conflict **Symptoms**: `yarn install --frozen-lockfile` fails **Solutions**: 1. Ensure `yarn.lock` is up-to-date locally 2. Run `yarn install` and commit updated `yarn.lock` 3. Do not use `--frozen-lockfile` if using different platforms (arm64 vs amd64) ### Slow Workflow Execution **Symptoms**: Workflows take too long to complete **Solutions**: 1. Verify caching is working (check logs for "Cache restored") 2. Use `--frozen-lockfile` for faster dependency resolution 3. Consider matrix strategy for parallel execution (not currently used) 4. Optimize Playwright tests (reduce test count, increase timeouts only if needed) ## Best Practices ### 1. Keep Dependencies Updated Regularly update action versions: ```yaml - uses: actions/checkout@v4 # Update from v3 to v4 when available - uses: actions/setup-node@v4 ``` ### 2. Use Frozen Lockfile Always use `--frozen-lockfile` in CI to ensure reproducible builds: ```bash yarn install --frozen-lockfile ``` ### 3. Monitor Workflow Status Set up notifications for workflow failures: - Email notifications in Gitea user settings - Integrate with Slack/Mattermost for team alerts - Use status badges in README ### 4. Test Locally Before Pushing Run the same checks locally: ```bash yarn lint # oxlint yarn dprint check # Formatting check yarn tsc --noEmit # Type check yarn test:e2e # E2E tests yarn build # Build ``` ### 5. Leverage Git Hooks The project uses lefthook for pre-commit/pre-push checks. This catches issues before they reach CI: ```bash # Pre-commit: Format code, lint staged files # Pre-push: Full type check, format check, full lint ``` ## Additional Resources - [Gitea Actions Documentation](https://docs.gitea.com/usage/actions/overview) - [Gitea act_runner Documentation](https://docs.gitea.com/usage/actions/act-runner) - [GitHub Actions Documentation](https://docs.github.com/en/actions) - [SvelteKit Deployment Guide](https://kit.svelte.dev/docs/adapters) - [Playwright CI/CD Guide](https://playwright.dev/docs/ci) ## Status Badges Add status badges to your README.md: ```markdown ![Lint](https://your-gitea-instance.com/username/glyphdiff/actions/badges/workflow/lint.yml/badge.svg) ![Test](https://your-gitea-instance.com/username/glyphdiff/actions/badges/workflow/test.yml/badge.svg) ![Build](https://your-gitea-instance.com/username/glyphdiff/actions/badges/workflow/build.yml/badge.svg) ``` ## Next Steps 1. **Customize deployment**: Modify `deploy.yml` with your deployment strategy 2. **Add notifications**: Set up workflow failure notifications 3. **Optimize caching**: Add Playwright cache if needed 4. **Add badges**: Include status badges in README 5. **Schedule tasks**: Add periodic tests or dependency updates (optional) --- **Last Updated**: December 30, 2025 **Version**: 1.0.0