Packages, continuous integration, and releases
What is built where
| Artifact | Built by | Target |
|---|---|---|
ck-git-hosting_V_arm64.deb, ck-git-hosting_V_amd64.deb | packaging/build-deb.sh in a Debian 13 container | Debian 13 servers, including Raspberry Pi 4/5 on arm64 |
ckgit_V_arm64.deb, ckgit_V_amd64.deb | same | Debian 13 clients |
ckdocs_V_arm64.deb, ckdocs_V_amd64.deb | same | the documentation-site generator, standalone (no file overlap with the other two, so it installs anywhere independently) |
ck-git-runner_V_arm64.deb, ck-git-runner_V_amd64.deb | same | a remote CI runner for another machine (its own binary path, account and unit; no file overlap with the server package) |
ck-git-hosting-V-linux-{arm64,amd64}.tar.gz | packaging/build-tarball.sh | other systemd distributions with glibc 2.41 or newer; carries bin/ckdocs too |
ckgit-V-macos-{arm64,x86_64}.tar.gz | same, --client-only | macOS clients; carries bin/ckdocs too |
ck-git-hosting-V-source.tar.gz | git archive | Homebrew formula source |
SHA256SUMS | release job | verification |
packages (a .tar bundling the arm64/amd64 .debs, a source tarball, and build-version) | this project's own self-hosted CI (.ckgit/ci.yml), stored as a release asset on the server | ck-git-hosting-deploy (the server package) and ckgit release download / packaging/update-cli.sh (the source tarball) |
this repository's documentation site (ckdocs.yml, README.md, docs/) | ckdocs build in both CI channels: .ckgit/ci.yml's docs step (self-hosted) and .github/workflows/pages.yml (GitHub) | ck-git Pages on the server (the dashboard's Docs button) and https://cklukas.github.io/ck-git-hosting/ |
The version comes from the VERSION file. A release is created by pushing a
tag vMAJOR.MINOR.PATCH that matches it; the workflow refuses a mismatch.
Pushing the same tag to both the GitHub origin remote and this project's
own hosted ckgit remote produces the two channels side by side -- see
Releases and the
self-hosted release and deploy guide.
Continuous integration
.github/workflows/ci.yml runs on every push and pull request:
- Linux amd64 and arm64 with GCC and Clang: strict
-Werrorbuild plus the unit and integration suites (make all check). - macOS Apple silicon and Intel: the same.
- Debian 13 container on both architectures: builds all four packages, runs
lintianfor information, installs them withapt, confirms the daemon, CI runner, Pages, and ckdocs binaries and units are in place, creates a device key line and a project, removes the packages while verifying thatserver.iniand the repository survive, then purges and verifies that the repository still survives.
Every job passes BUILD_ROOT=$RUNNER_TEMP, overriding the Makefile's own
portable default (TMPDIR, or /tmp; a checkout's own local.mk can pin a
different one — see local.mk.example), and the Makefile only accepts build
directories beneath the selected root either way. The arm64 jobs use the
ubuntu-24.04-arm runner label and the Intel macOS job uses macos-15-intel;
both are hosted labels that GitHub may rename in future, in which case only
the matrix entries change.
Debian and Raspberry Pi
sudo apt install ./ck-git-hosting_0.1.0_arm64.deb
sudo ckgit-admin authorized-key --client-id mac-studio --public-key mac-studio.pub \
| sudo tee -a /etc/ck-git-hosting/authorized_keys
The package installs the same tree as packaging/install.sh, with two
package-specific choices: the units live in /usr/lib/systemd/system, and
authorized_keys is created by the maintainer script rather than shipped, so
neither an upgrade nor a purge touches device keys by accident.
server.ini and the sshd drop-in are conffiles. apt remove keeps
configuration, state, repositories, and the account; apt purge removes
configuration and state and still keeps every bare repository and the
account, printing what was left behind.
The maintainer scripts skip systemctl when systemd is not running and skip
the sshd reload when sshd is absent, which is how the container test runs.
If sshd -t rejects the drop-in, it is renamed to .disabled and sshd is not
reloaded.
Build packages locally on a Debian host:
make BUILD_ROOT=/tmp/ck BUILD_DIR=/tmp/ck/build all check
sh packaging/build-deb.sh --build-dir /tmp/ck/build --output /tmp/ck/dist
--stage-only writes the two package roots without dpkg-deb, which the
test suite uses on a workstation. CKGIT_MAINTAINER overrides the
Maintainer field.
Without --version, a local build is stamped 0.1.0~YYYYMMDD.HHMM.<commit>.
dpkg orders ~ below anything, including the empty string, so this snapshot
sorts below the plain release 0.1.0 and above every earlier snapshot of
the same VERSION — a real 0.1.0 release is never seen as a downgrade from
an earlier development build, and apt install ./ck-git-hosting_*.deb still
always upgrades from one snapshot to the next. A rebuilt package with an
unchanged version is "already installed" to apt and needs dpkg -i or
apt reinstall. Both the GitHub release workflow and this project's own
self-hosted CI (.ckgit/ci.yml) pass the tag version explicitly for a tag
matching VERSION, so a release published either way carries the identical
clean version, for example 0.1.0. Installing a snapshot of an
already-released VERSION over that release (for example testing a further
change to master before bumping VERSION again) needs apt --allow-downgrades or dpkg -i, which only warns; this is deliberate — bump
VERSION on master right after tagging a release, and a plain apt upgrade keeps working during the normal cycle.
Other Linux distributions
Unpack the Linux tarball and run the installer from inside it; the unpacked
directory is a valid --build-dir:
tar -xzf ck-git-hosting-0.1.0-linux-arm64.tar.gz
cd ck-git-hosting-0.1.0-linux-arm64
sudo sh packaging/install.sh --build-dir . --dry-run
sudo sh packaging/install.sh --build-dir . --yes
The archive is built against Debian 13's glibc. Older distributions build from source with only Make and a C++20 compiler:
make BUILD_ROOT=/tmp/ck BUILD_DIR=/tmp/ck/build all check
macOS client with Homebrew
This repository is also a Homebrew tap: Formula/ckgit.rb builds the client
from the released source archive with a verified checksum.
brew tap cklukas/ck-git-hosting https://github.com/cklukas/ck-git-hosting
brew install ckgit
brew install --HEAD ckgit
After every release the workflow's final job rewrites the formula's url,
sha256, homepage, and head for that release and commits the change to
the default branch, so brew upgrade ckgit follows releases. Until the first
release only --HEAD installs succeed, because the placeholder checksum
cannot match.
Without Homebrew, unpack ckgit-V-macos-arm64.tar.gz or the x86_64
archive and copy bin/ckgit to a directory on PATH.
Cutting a release
- Update
VERSIONand land the change on the default branch with CI green. - Tag and push:
git tag v0.1.0 && git push origin v0.1.0. - The release workflow builds and tests every artifact, publishes the
release with
SHA256SUMS, and updates the Homebrew formula.
Release notes are generated from a fixed template; edit the release on GitHub afterwards for anything version-specific.