Repository navigation
Maintainer handbook
How the project is run: triage, labels, pull requests and releases. Contributors can read it to know what to expect.
Every new issue gets, within a few days:
- an issue type: Bug, Feature or Task;
- one or more area labels:
area: prep,area: audit,area: preconfig,area: docs,area: ci,area: agents,area: community,area: site,area: extras; - a priority (
priority: criticaltopriority: low) and a size (size: Sunder a day,Mone to three days,Lmore); - a panel label when it is panel-specific:
panel: coolify,panel: dokploy,panel: openship; - a milestone (the phase it belongs to, or Next patch release for fixes);
- a parent epic when it is part of one, as a sub-issue.
Use status: needs-repro when the report lacks the steps or the output, and status: blocked when it waits on something else. Add agent-ready only when the issue has acceptance criteria and verification commands. good first issue marks small, well-scoped tasks.
The release notes group merged pull requests by the security, enhancement, bug and documentation labels. skip-changelog leaves a pull request out.
- One topic per pull request, from a branch:
fix/…,feat/…ordocs/…. Nobody pushes tomain. - Title:
<script or area>: <what changes>. It becomes the release-note line. - Add a release-notes label and, for a user-visible change, a line under
## [Unreleased]inCHANGELOG.md. - CI must pass:
bash -n, ShellCheck at warning level,--helpfor each script,scripts/gen-data.sh --checkand the quick tests intests/. - The
e2eworkflow runs the scripts in a VM per system when a PR changes a script or the tests. It is not a required check yet: read its report (linked in a PR comment) before merging. A red system shows the failed assertion first. - A changed step, setting or audit check also updates
server-prep.conf.example, the README step table and an audit check. Then runscripts/gen-data.shso the setup console shows it. - Pull requests are squash-merged. GitHub signs the merge commit.
One button: Actions → release → Run workflow, then choose patch, minor or major. From a terminal:
gh workflow run release -f bump=patchThe workflow bumps PREP_VERSION, moves the [Unreleased] notes under the new version, regenerates the setup console data and puts that commit straight on main, then tags and publishes the release with the scripts, the Telegraf template and SHA256SUMS. Everything else reaches main through an approved pull request: the release GitHub App, used only by this workflow, is the one exception.
To rotate the release app's private key (for example when it may have leaked, or when a maintainer leaves):
-
On the app's settings page (GitHub Apps → the release app → General → Private keys), generate a new private key. GitHub downloads a
.pemfile. -
Put it in the
releaseenvironment, then delete the.pemfile from your computer:gh secret set RELEASE_APP_PRIVATE_KEY -R exceev-consulting/server-prep --env release < new-key.pem
-
Back on the app's settings page, delete the old key. The next release uses the new one.
A hotfix is a fix that cannot wait for the next patch release. The full decision is ADR 0003.
-
S1, blocking: a step fails with the default answers on a supported system, a release is unusable, the audit passes
a broken security setting, or
mainfails its checks. It is a public issue withpriority: critical. - S0, security: an exploitable defect. It stays a private advisory: see Security reports.
When you are told about a critical issue:
-
Read it and confirm it. If it is not blocking, lower its priority.
-
Add
agent-readywhen the issue says what to change and how to check it. The Claude routines develop it first, before every milestone, on aclaude/hotfix-<n>-...branch. Without the label nothing is developed: the label is your go-ahead. You can also fix it yourself on ahotfix/<topic>branch. -
Review the pull request. It goes first in the review, fix and conflict routines.
-
Merge it, then release:
gh workflow run release -f bump=patch
-
For a security fix, start the CHANGELOG line with
**Security fix:**and say which step to re-run. The audit checkupd.server_prepthen shows WARN on servers that still use an older version.
A release that breaks servers or opens a hole, found after it was published:
-
Stop the spread. Edit the release on GitHub: add a first line "Do not use: see #" and untick
Set as the latest release, so the badge and the download link point to the previous release. Never delete a
release or a tag: people check their download against its
SHA256SUMS. -
Tell users. Pin the issue, and post in Announcements
what breaks, who is affected (OS, panel, settings) and the workaround: the previous release, or the steps to skip
with
--skip <step>. -
Fix forward. Fix on
mainthrough the lane above and release a new patch. Never move or reuse a tag. - Close. Set the new release as the latest, unpin the issue, and say in the CHANGELOG line which version was bad.
- The setup console deploys from
site/on every push tomainthat touches it, the scripts or the README. - The site's domain,
server-prep.exceev.com, is set in Settings → Pages → Custom domain, with Enforce HTTPS on. The site deploys through GitHub Actions, so the domain lives only in the settings: the repository has noCNAMEfile. - The domain's DNS record is a CNAME to
exceev-consulting.github.iowith the DNS proxy off (DNS only in Cloudflare): a proxied record sends visitors to another server and keeps GitHub from getting its certificate. Oldexceev-consulting.github.io/server-prep/links redirect to the domain. - The wiki is published from the
wiki/folder by.github/workflows/wiki.yml. Edit pages through pull requests, not in the web editor. - The brand guidelines (
site/brand/) cover the logo, colours, type and voice. Whensite/social-preview.pngchanges, upload it again in Settings → General → Social preview: GitHub has no API for the repository's preview image.
Security problems arrive through private advisories (SECURITY.md): from reporters, and as drafts from the Claude routines. You are told about each new one. Acknowledge it quickly, then decide, one advisory at a time:
- Public fix: most lockouts and local exposures. Fix them through the hotfix lane, in a pull request with a neutral title that does not explain how to exploit the problem.
- Private fix: a problem someone could exploit from outside. Fix it in the advisory's temporary private fork (Start a temporary private fork on the advisory page), then merge it from there.
Publish the advisory with the release that fixes it, and credit the reporter unless they prefer not.
Setup console · Brand · Discussions · Issues · Roadmap · MIT licence · Edit these pages through a pull request on wiki/
Get started
Understand
Run it
Project