- Shell 95.8%
- PHP 4.2%
| .forgejo | ||
| ISSUE_TEMPLATE | ||
| public | ||
| scripts | ||
| src | ||
| tests | ||
| .editorconfig | ||
| .gitignore | ||
| .php-cs-fixer.php | ||
| composer.json | ||
| pull_request_template.md | ||
| README.md | ||
| xegames.config.yml | ||
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
- Click Use this template on Forgejo
- Update
composer.json— setnameanddescription - Follow the setup checklist below
Setup checklist
- Set
RELEASE_TOKENsecret in Settings → Secrets - Update
nameanddescriptionincomposer.json - Set
SITE_NAMEinscripts/service-start.shandscripts/service-stop.sh - Set
healthcheck.endpointinxegames.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
cicduser - Add sudoers entry on hub for php-fpm and nginx reload
- Run
create-project.shfromXeplosionGames/.forgejoto seed project board - Push to
mainand verify CI passes - Enable
notify.zulip: trueonce 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_checkis currently disabled pending org-wide PHP style conventions being finalized. Tracked inXeplosionGames/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: