.agents/skills/self-hosted-release/SKILL.md
Use this skill as a release gate for Appwrite self-hosted RCs and final releases. Do not treat container health or metadata review as enough. A release is not ready until a fresh self-hosted stack works with realistic workflows and an upgrade from the previous stable self-hosted release preserves seeded data through migrations.
app/init/constants.php, release notes, Docker image tags, and the user's stated target.Useful commands:
git rev-parse --abbrev-ref HEAD
git rev-parse HEAD
rg -n "APP_VERSION_STABLE|APP_CACHE_BUSTER" app/init/constants.php
git ls-remote --tags origin "refs/tags/*"
Build and run the target release with the local Docker Compose stack, then test it like a real self-hosted install.
docker compose down -v
docker compose up -d --force-recreate --build --wait
docker compose exec -T appwrite vars
curl -fsS http://localhost/v1/health/version
Inspect runtime health before running tests:
docker compose ps and docker compose logs for crash loops, missing env vars, failed mounts, worker failures, executor/runtime failures, migration errors, queue errors, and warnings that indicate broken self-hosted wiring.Run the Appwrite test suite inside Docker:
docker compose exec -T appwrite test /usr/src/code/tests/unit
docker compose exec -T appwrite test /usr/src/code/tests/e2e/General
docker compose exec -T appwrite sh -lc 'vendor/bin/paratest --processes "$(nproc)" /usr/src/code/tests/e2e/Services --exclude-group abuseEnabled --exclude-group screenshots'
When validating a risky release, broaden the matrix with the same database adapters and modes CI uses. At minimum, cover the default self-hosted adapter and every adapter touched by migrations, storage, query behavior, relationships, or installer changes.
Block the release for any missing env var, broken container dependency, failing public route, unexpected 5xx, queue/worker failure, test failure, or workflow that only works with unrealistic empty data.
Validate upgrade from the previous stable self-hosted release to the target release using the same persisted volumes and configuration.
Install the previous stable baseline:
/v1/health/version reports the baseline version.Seed broad, realistic data on the baseline before upgrading:
Upgrade the baseline stack to the target release:
Verify migration behavior:
Verify seeded data after upgrade through public APIs:
Block the release for migration failure, non-idempotency, data loss, changed permissions, broken reads/writes on upgraded data, failed workers/queues after upgrade, or any behavior that only works on fresh installs.
Review release metadata after the runtime gates, not instead of them:
app/init/constants.php: APP_VERSION_STABLE is the target version and APP_CACHE_BUSTER is incremented.docker-compose.yml and app/views/install/compose.phtml: Appwrite and console image tags are correct for the target release.README.md and README-CN.md: self-hosted install snippets use the target release.src/Appwrite/Migration/Migration.php: the target version maps to the correct migration class.CHANGES.md: the target version has user-facing notes for notable changes, fixes, migrations, compatibility notes, and self-hosted operator impact.For public API changes, compare against the previous stable baseline:
src/Appwrite/Utopia/Request/Filters/V*.php.src/Appwrite/Utopia/Response/Filters/V*.php.app/controllers/general.php for the correct x-appwrite-response-format boundary.tests/unit/Utopia/Request/Filters or tests/unit/Utopia/Response/Filters.x-appwrite-response-format when behavior depends on routing, auth, persistence, validation, or serialization.Block the release when a public breaking change lacks a compatibility filter and tests, unless the release owner explicitly accepts the break and documents it in release notes.
Do not approve an RC or final self-hosted release until all gates pass:
For every RC/final validation, produce a short release evidence summary with: target version, commit SHA, previous stable baseline, tested database adapters and modes, fresh install scenarios, upgrade scenarios, seeded data categories, test commands and results, blockers found, fixes applied, and remaining owner-approved risks.