Files
peptide-e2e/docs/gitea-pipeline.md
peptiderepo-ops bdfa23218a
Some checks failed
CI / Deploy / PHP Lint (8.1) (push) Has been cancelled
CI / Deploy / PHP Lint (8.2) (push) Has been cancelled
CI / Deploy / PHP Lint (8.3) (push) Has been cancelled
CI / Deploy / PHPCS (WordPress standards) (push) Has been cancelled
docs: Gitea pipeline operating notes; ci-image build publishes to registry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AqpXh3hQMMaC74pTjFq4it
2026-10-24 10:16:09 +00:00

3.7 KiB

Gitea Actions pipeline (peptide-repo)

Since 2026-10-24 every peptide-repo plugin/theme builds and deploys from git.protopeer.com/peptide-repo, not GitHub. GitHub's .github/workflows are left in the repos but Gitea ignores them (a repo with .gitea/workflows uses only that folder).

How it fits together

  • Shared logic lives once, as composite actions in this repo under .gitea/actions/: deploy, smoke, ci-lint-php, ci-phpcs, ci-file-size, ci-phpunit, ci-lint-js, audit-direct-push. Gitea 1.25 cannot run reusable workflows (workflow_call), which is why this is not a 1:1 copy of the GitHub deploy-app.yml / ci.yml.
  • Each repo's .gitea/workflows/pipeline.yml is generated by tools/gitea-pipeline/render.py from tools/gitea-pipeline/repos.json. Change a repo's settings in repos.json, re-render, commit the output. Do not hand-edit the generated files.
  • Job graph: lint-php / phpcs / file-size / phpunit / lint-js (+ repo extras) -> deploy-staging -> smoke (gate) -> deploy-production. Deploys run on pushes to main and on manual runs of main.
  • Runners: CI jobs run on the shared docker runner (ubuntu-latest) inside git.protopeer.com/peptide-repo/ci-php:2026-10 (PHP 8.1/8.2/8.3 + Composer, built from ci-image/). Deploy and smoke run on the host runner peptide-vps-gitea (systemd gitea-runner-peptide, user gtrunner, label peptide-vps) on the KVM8, one job at a time, like the old GitHub runner.
  • Secrets / variables are org-level on Gitea peptide-repo: SSH_PRIVATE_KEY (deploy key gitea-peptide-deploy-20261024 on Hostinger), SSH_HOST, SSH_PORT, SSH_USERNAME, STAGING_WP_ADMIN_USER (gitea-smoke, staging-only admin), STAGING_WP_ADMIN_PASSWORD; variable PROD_DEPLOY_ENABLED.

Switches and recovery

  • Kill switch: set org variable PROD_DEPLOY_ENABLED to anything but true -> production deploys (and peptide-news-plugin rollback) are skipped; staging + smoke still run.
  • Redeploy / retry: run the repo's CI / Deploy workflow on main manually.
  • Roll back news plugin: peptide-news-plugin -> Rollback Deployment (workflow_dispatch, optional commit SHA). Same deploy action as normal.
  • Drift: deploy-health.yml (daily 13:00 UTC / 21:00 SGT) compares the commit stamped in ~/.peptide-deploys/production/<target> on Hostinger with each repo's main, and opens one "Deploy drift detected" issue here.
  • Back to GitHub (emergency): systemctl enable --now actions.runner.peptide-repo.peptide-vps on the KVM8 and set PROD_DEPLOY_ENABLED=false here. Only works while GitHub's Hostinger deploy key is still authorised.

Differences from the GitHub pipeline (deliberate)

  • .gitea is also excluded from rsync.
  • JS lint uses Node 22 (GitHub used Node 20, now end-of-life).
  • Smoke login confirms WordPress's periodic "Administration email verification" screen instead of timing out on it (it had been blocking smoke since 2026-09-10, when staging's admin-email check expired).
  • Production stamps the deployed commit for deploy-health (replaces GitHub Deployments).
  • PHP matrices are literal lists (avoids Gitea's fromJson matrix bug).

Known gaps

  • pr-vision cto-review.yml (AI PR review via OpenRouter) is not ported: its OPENROUTER_API_KEY / CTO_ADMIN_TOKEN secrets only exist on GitHub and it calls GitHub's review API.
  • The LiteSpeed purge in the production deploy runs relative to $HOME, so it is effectively a no-op - same as on GitHub. Kept as-is, not fixed.
  • Issues / PR history of repos other than peptide-e2e stayed on GitHub (the migration hit GitHub's anonymous API rate limit); GitHub repos are to be archived, not deleted.