A celilo-hosted app should get full CI/CD for free: merge a pull request and the
change builds, publishes to the celilo registry, and reaches your fleet on its
own — no manual publish, no manual deploy. lunacycle will be the first app
wired all the way through, and it becomes the reference other apps copy.
The loop
The shape is a straight line from a merged PR to a running upgrade:
- On merge to
main, your repo’s CI runs end-to-end tests, versions the release, packages the module, and publishesyour-app@X.Y.Zto the celilo registry. celilo-mgrpolls the registry, sees the newer version, and runs the upgrade.- Deploy posture is derived automatically from the semver delta — a patch deploys fast, a minor or major deploys safe (backup first).
celilo never commits to your repo. You own your .forgejo/workflows; celilo
provisions the publish token and repo settings, holds the artifact, and polls.
Least privilege by construction
Your app ships as a celilo module that requires two capabilities —
source_forge (the forge configures your repo) and registry_publish (the
registry mints your token). A deploy hook mints a token scoped to a single
package, so this repo can only ever publish its own app and never another
module’s. The hook re-runs on every deploy and every step is idempotent, so the
deploy itself is the reconcile.
Opt-in, not automatic
Auto-upgrade is opt-in: a module sets auto_upgrade: true for the poll to pick
it up. A module can also floor its posture with an upgrade_policy, and any
single release can override posture per-publish through release metadata.