mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:44:38 +08:00
270 lines
8.1 KiB
Markdown
270 lines
8.1 KiB
Markdown
# CI/CD and Release Governance
|
|
|
|
TNT is a C SSH terminal chat server. The CI/CD system is designed for a public
|
|
open-source project: fast feedback on pull requests, broader scheduled
|
|
validation across target environments, reproducible release artifacts, and a
|
|
manual production deployment boundary.
|
|
|
|
Production deployment is intentionally manual. Workflows must not SSH into
|
|
production, restart services, upload to OSS buckets, publish package-manager
|
|
recipes, or mutate running servers.
|
|
|
|
## Pipeline Layers
|
|
|
|
### PR Fast Gate
|
|
|
|
Workflow: `.github/workflows/ci.yml`
|
|
|
|
Runs on pull requests targeting `main` or `release/**`, and pushes to `main`
|
|
or `release/**`:
|
|
|
|
- Ubuntu 24.04 and macOS latest builds.
|
|
- Normal build with `make`.
|
|
- AddressSanitizer build with `make asan`.
|
|
- Integration/security gate with `make ci-test`.
|
|
- Local release/package preflight with `make release-check`.
|
|
|
|
Purpose:
|
|
|
|
- Keep contributor feedback fast enough for normal review.
|
|
- Catch build, integration, packaging metadata, and release-preflight regressions
|
|
before merge.
|
|
- Avoid slow soak, valgrind, and container matrix jobs on every PR.
|
|
|
|
### Extended and Nightly Validation
|
|
|
|
Workflow: `.github/workflows/ci.yml`
|
|
|
|
Runs on `main` or `release/**` pushes, manual dispatch, and the nightly
|
|
schedule:
|
|
|
|
- `extended-linux-runtime`
|
|
- Runs `RUN_INTEGRATION=1 RUN_SOAK=1 RUN_SLOW_CLIENT=1 make release-check`.
|
|
- Runs a valgrind smoke test against a temporary server.
|
|
- `portable-container-builds`
|
|
- Builds in Debian stable glibc.
|
|
- Builds in Ubuntu 24.04 glibc.
|
|
- Builds in Alpine musl.
|
|
- `package-recipe-gate`
|
|
- Syntax-checks shell scripts.
|
|
- Syntax-checks the Arch `PKGBUILD`.
|
|
- Syntax-checks the Homebrew formula.
|
|
- Assembles the Debian source tree.
|
|
|
|
Purpose:
|
|
|
|
- Broaden platform confidence without making every PR wait for the full matrix.
|
|
- Detect musl/glibc portability issues early.
|
|
- Keep package metadata reviewable before public registry submission.
|
|
|
|
### Release Artifact Gates
|
|
|
|
Workflow: `.github/workflows/release.yml`
|
|
|
|
Runs only for SemVer tags matching `vMAJOR.MINOR.PATCH`:
|
|
|
|
- Verifies the tag matches `TNT_VERSION` through `scripts/check_release_ref.sh`.
|
|
- Builds Linux glibc AMD64 and ARM64 binaries.
|
|
- Builds macOS Intel and Apple Silicon binaries.
|
|
- Verifies binary architecture labels.
|
|
- Builds an explicit source archive with `scripts/package_source_archive.sh`:
|
|
`tnt-chat-vX.Y.Z-source.tar.gz`.
|
|
- Runs `scripts/package_release_assets.sh` to collect release assets, verify
|
|
expected asset names, verify binary architecture labels again after artifact
|
|
download, verify source archive contents, generate `checksums.txt`, and verify
|
|
the checksum file.
|
|
- Creates a GitHub draft release only. Publishing stays manual.
|
|
|
|
The release workflow does not publish package-manager recipes or deploy
|
|
production servers.
|
|
|
|
## Platform Policy
|
|
|
|
Current release assets:
|
|
|
|
- Linux glibc AMD64: `tnt-linux-amd64`, `tntctl-linux-amd64`
|
|
- Linux glibc ARM64: `tnt-linux-arm64`, `tntctl-linux-arm64`
|
|
- macOS Intel: `tnt-darwin-amd64`, `tntctl-darwin-amd64`
|
|
- macOS Apple Silicon: `tnt-darwin-arm64`, `tntctl-darwin-arm64`
|
|
- Source archive: `tnt-chat-vX.Y.Z-source.tar.gz`
|
|
|
|
Current CI validation:
|
|
|
|
- Ubuntu 24.04
|
|
- macOS latest
|
|
- Debian stable glibc container build
|
|
- Ubuntu 24.04 glibc container build
|
|
- Alpine musl container build
|
|
|
|
Package-manager routes:
|
|
|
|
- Debian/Ubuntu: maintain draft Debian metadata and start with a Launchpad PPA.
|
|
- Arch/AUR: maintain `packaging/arch/PKGBUILD` and `.SRCINFO`; submit manually.
|
|
- Homebrew/macOS: maintain a tap formula first; Homebrew core can wait for a
|
|
stable release cadence and broader adoption.
|
|
- Source archive: every public package recipe must pin the final GitHub release
|
|
source archive checksum.
|
|
- Containers: first stage is Docker-based build validation in CI. Publishing
|
|
images should wait until image labels, SBOM, provenance, CVE scanning, and
|
|
registry ownership are defined.
|
|
|
|
## Release Policy
|
|
|
|
- Use SemVer-style tags: `vMAJOR.MINOR.PATCH`.
|
|
- Bump PATCH for compatible bug fixes and release hardening.
|
|
- Bump MINOR for new commands, new documented flags, JSON field additions, or
|
|
visible user-interface behavior changes.
|
|
- Bump MAJOR for incompatible command, config, storage, or package behavior.
|
|
- Keep GitHub release publishing manual by using draft releases.
|
|
- Keep production deployment manual.
|
|
|
|
Update version metadata before tagging:
|
|
|
|
- `include/common.h`
|
|
- `tnt.1`
|
|
- `tntctl.1`
|
|
- `docs/CHANGELOG.md`
|
|
- `packaging/arch/PKGBUILD`
|
|
- `packaging/arch/.SRCINFO`
|
|
- `packaging/homebrew/tnt-chat.rb`
|
|
- `packaging/debian/debian/changelog`
|
|
|
|
Local preflight:
|
|
|
|
```sh
|
|
make release-check
|
|
```
|
|
|
|
Longer local runtime gate:
|
|
|
|
```sh
|
|
RUN_INTEGRATION=1 RUN_SOAK=1 RUN_SLOW_CLIENT=1 make release-check
|
|
```
|
|
|
|
Strict local release gate before pushing a tag:
|
|
|
|
```sh
|
|
git tag vX.Y.Z
|
|
make release-check-strict
|
|
```
|
|
|
|
Strict mode requires the local `vX.Y.Z` tag to point at `HEAD` and builds from
|
|
the tagged source archive, so it catches files that were left untracked and
|
|
would be missing from the release source archive.
|
|
|
|
After strict checks pass:
|
|
|
|
```sh
|
|
git push origin vX.Y.Z
|
|
```
|
|
|
|
GitHub Actions then builds artifacts and opens a draft release. Review and
|
|
publish that draft manually.
|
|
|
|
## Release Review Checklist
|
|
|
|
Before publishing a draft release:
|
|
|
|
- Confirm the Git tag points at the intended commit.
|
|
- Confirm the release workflow passed.
|
|
- Download every release asset from GitHub, not from the local workspace.
|
|
- Verify downloaded assets against `checksums.txt`.
|
|
- Run downloaded `tnt --version` and `tntctl --version`.
|
|
- Start a temporary server and check:
|
|
|
|
```sh
|
|
ssh -p 2222 server health
|
|
ssh -p 2222 server stats --json
|
|
ssh -p 2222 server users --json
|
|
ssh -p 2222 operator@server post "release smoke"
|
|
ssh -p 2222 server "tail -n 1"
|
|
```
|
|
|
|
- Check runtime dynamic links with `ldd` on Linux or `otool -L` on macOS.
|
|
- Confirm `libssh` runtime installation is documented for the target install
|
|
path.
|
|
- Verify the explicit source archive checksum before updating Arch, Homebrew,
|
|
Debian, Ubuntu, or container package metadata.
|
|
- Run package publication preflight after package recipes pin final source
|
|
checksums:
|
|
|
|
```sh
|
|
SOURCE_TARBALL=dist/tnt-chat-vX.Y.Z-source.tar.gz make package-publish-check
|
|
```
|
|
|
|
## Checksums
|
|
|
|
Release assets include `checksums.txt`.
|
|
|
|
Linux:
|
|
|
|
```sh
|
|
sha256sum -c checksums.txt --ignore-missing
|
|
```
|
|
|
|
macOS:
|
|
|
|
```sh
|
|
for f in tnt-* tntctl-* tnt-chat-*-source.tar.gz; do
|
|
grep " $f$" checksums.txt | shasum -a 256 -c -
|
|
done
|
|
```
|
|
|
|
## Supply Chain Roadmap
|
|
|
|
Stage 1, implemented now:
|
|
|
|
- Tag/version gate.
|
|
- Draft release, manual publish.
|
|
- Binary architecture validation.
|
|
- Source archive validation.
|
|
- Local source-archive dry-run coverage.
|
|
- SHA-256 checksums for every release asset.
|
|
- Package recipe checksum preflight.
|
|
|
|
Stage 2, next:
|
|
|
|
- Generate an SBOM for release artifacts, preferably CycloneDX or SPDX.
|
|
- Attach SBOM files to draft releases.
|
|
- Add package lint jobs for Debian source packages, Arch packages, Homebrew
|
|
audit, and container image metadata.
|
|
|
|
Stage 3, later:
|
|
|
|
- Sign release checksums and/or artifacts with a documented maintainer key or
|
|
Sigstore flow.
|
|
- Add SLSA provenance for GitHub Actions builds.
|
|
- Define container image ownership, tag policy, vulnerability scan policy, and
|
|
rollback behavior before publishing images.
|
|
|
|
## Manual Production Deployment
|
|
|
|
Deployment remains operator-driven:
|
|
|
|
1. Build and test locally or in a temporary server directory.
|
|
2. Back up the installed binary.
|
|
3. Install the new binary.
|
|
4. Restart only the intended `tnt` service.
|
|
5. Run black-box checks: `health`, `stats --json`, `users --json`, and one
|
|
post/tail smoke test.
|
|
|
|
Manual binary replacement pattern:
|
|
|
|
```sh
|
|
backup=/usr/local/bin/tnt.bak-$(date +%Y%m%d%H%M%S)
|
|
sudo cp -a /usr/local/bin/tnt "$backup"
|
|
sudo install -m 755 ./tnt /usr/local/bin/tnt
|
|
sudo systemctl restart tnt
|
|
```
|
|
|
|
## Rollback
|
|
|
|
Production rollback stays manual:
|
|
|
|
1. Keep the previous binary before replacing it.
|
|
2. Stop or restart only the intended `tnt` service.
|
|
3. Restore the previous binary if smoke checks fail.
|
|
4. Re-run `health`, `stats --json`, and one post/tail smoke test.
|
|
|
|
Do not overwrite `TNT_STATE_DIR` during rollback. If a future release changes
|
|
the message log format, its release notes must include downgrade behavior.
|