PHP project template for XeplosionGames. Managed via .forgejo — do not push directly.
  • Shell 95.8%
  • PHP 4.2%
Find a file Use this template
XE Games CI 86da53c095
Some checks failed
CI / format (push) Failing after 1s
CI / test (push) Failing after 2s
Deploy to Production / deploy (push) Failing after 3s
chore: sync scripts/sync-implementers.sh from main.
2026-06-20 14:53:13 -06:00
.forgejo chore: sync SYNCED_CODEOWNERS from main. 2026-06-16 01:38:34 +00:00
ISSUE_TEMPLATE Revert "chore: add test comments to verify sync workflow." 2026-05-26 09:00:20 -06:00
public feat: add issue templates, PR template, and CI/CD workflows. 2026-05-26 09:21:08 -06:00
scripts chore: sync scripts/sync-implementers.sh from main. 2026-06-20 14:53:13 -06:00
src feat: add src/index.php web entry point. 2026-05-26 09:17:35 -06:00
tests fix: added placeholder tests folder. 2026-05-26 09:57:13 -06:00
.editorconfig feat: add .editorconfig for PHP and web projects. 2026-05-26 09:15:30 -06:00
.gitignore feat: add .gitignore for PHP projects. 2026-05-26 09:15:51 -06:00
.php-cs-fixer.php fix: supressed Undefined type 'PhpCsFixer\Finder' error. 2026-05-26 09:41:07 -06:00
composer.json feat: add composer.json with PHP 8.3 and dev dependencies. 2026-05-26 09:16:56 -06:00
pull_request_template.md Update pull_request_template.md 2026-05-24 12:32:32 +00:00
README.md init: intial commit. 2026-05-26 09:20:35 -06:00
xegames.config.yml fix: rename xegames.confi.yml to xegames.config.yml. 2026-05-30 04:40:25 -06:00

template-php

Template for XeplosionGames PHP web projects. Includes PSR-12 code style, PHPUnit testing, symlink-based release deployment to hub, and CI/CD workflows. Framework agnostic — add your framework of choice on top.


Creating a repo from this template

  1. Click Use this template on Forgejo
  2. Update composer.json — set name and description
  3. Follow the setup checklist below

Setup checklist

  • Set RELEASE_TOKEN secret in Settings → Secrets
  • Update name and description in composer.json
  • Set SITE_NAME in scripts/service-start.sh and scripts/service-stop.sh
  • Set healthcheck.endpoint in xegames.config.yml
  • Set up release directory structure on hub:
  sudo -u cicd mkdir -p /var/www/<site>/releases
  sudo -u cicd mkdir -p /var/www/<site>/shared
  • Add shared file symlinks to scripts/service-start.sh
  • Configure nginx on hub to serve from /var/www/<site>/current/public/
  • Clone repo on hub as cicd user
  • Add sudoers entry on hub for php-fpm and nginx reload
  • Run create-project.sh from XeplosionGames/.forgejo to seed project board
  • Push to main and verify CI passes
  • Enable notify.zulip: true once site is stable

Deployment strategy

This template uses a symlink-based release deployment strategy. Rather than overwriting files in place, each deploy creates a versioned release directory and atomically flips a symlink to point at it. Nginx always serves from the current symlink.

/var/www/<site>/
├── releases/
│   ├── 20240101120000/     ← old release
│   ├── 20240115083000/     ← previous release
│   └── 20240201094500/     ← current release
├── shared/                 ← persistent files (uploaded across releases)
│   ├── .env                ← environment config, never in git
│   └── storage/            ← user uploads, logs, cache
└── current -> releases/20240201094500/   ← symlink nginx points to

Nginx serves from: /var/www/<site>/current/public/

Benefits

  • Instant rollback — flip the symlink back to the previous release
  • Zero downtime — symlink flip is atomic
  • Release history — last 5 releases kept on disk by default
  • Shared files.env, uploads, and storage persist across releases

Rollback

rollback.yml can be triggered manually from the Forgejo Actions UI. For PHP repos, rollback flips the current symlink to the previous release rather than using git checkout. Update scripts/service-start.sh to implement this behavior.

Shared files

Any file that should persist across releases (.env, user uploads, logs) lives in shared/ and is symlinked into each new release by service-start.sh. Never commit .env to git — add it to shared/ on the server manually.


Code style

This repo uses php-cs-fixer for PHP formatting, configured via .php-cs-fixer.php, and Prettier for HTML/CSS/JS assets.

To check formatting locally:

composer format:check          # PHP
npx prettier --check .         # HTML/CSS/JS (if applicable)

To fix formatting locally:

composer format                # PHP
npx prettier --write .         # HTML/CSS/JS (if applicable)

Conventions

Rule Value
Standard PSR-12
Indentation 4 spaces (PHP), 2 spaces (HTML/CSS/JS)
Quotes Single quotes
Arrays Short syntax []
Imports Alphabetically ordered, unused removed
Strict types declare(strict_types=1) required in all files

Note: ci.format_check is currently disabled pending org-wide PHP style conventions being finalized. Tracked in XeplosionGames/org.


Testing

Tests live in tests/ and use PHPUnit. Add test classes following PSR-4 autoloading under the App\Tests namespace.

To run tests locally:

composer test

Directory structure

src/        Application code (autoloaded as App\)
public/     Web root — nginx points here, contains index.php only
tests/      PHPUnit test classes (autoloaded as App\Tests\)
shared/     Persistent server files — never committed to git

Workflows

Workflow Trigger Purpose
ci-php.yml Every push / PR Format check + validate + PHPUnit
deploy-production.yml Push to main Deploy to hub via symlink release
deploy-test.yml Push to dev Deploy to test environment (if enabled)
rollback.yml Manual / auto Roll back to previous release
healthcheck.yml Scheduled Periodic HTTP healthcheck
release.yml Tag push v* Generate release notes + attach artifacts

Branch structure

Branch Purpose
main Production-ready, auto-deploys to hub
dev Active development, auto-deploys to test (if enabled)
feature/* Short-lived feature branches, PR to dev
hotfix/* Urgent fixes off main, PR to both main and dev

Commit convention

All commits use Conventional Commits format with a trailing period: