# MergeTB Debian packaging

**URL:** <https://forum.mergetb.net/t/mergetb-debian-packaging/165>\
**Category:** DevOps\
**Created:** [June 24, 2026, 11:00pm UTC](https://forum.mergetb.net/t/mergetb-debian-packaging/165 "2026-06-24T23:00:03Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bnguyen](https://forum.mergetb.net/letter_avatar_proxy/v4/letter/b/919ad9/32.png) [@bnguyen](https://forum.mergetb.net/u/bnguyen)\
**Post date:** [June 24, 2026, 11:00pm UTC](https://forum.mergetb.net/t/mergetb-debian-packaging/165/1 "2026-06-24T23:00:04Z")

</div>

This discussion topic is about how we chose to name and version our Debian packages and lay out the repo.

The work that was done was I investigated whether our .deb’s actually diverge per Debian version. Added an md5sum diagnostic to the build (hashes staged files + the final .deb in the  
job logs), built the same tag on deb12 and deb13, compared, and ran cross-distro  
install tests against the live repo.

What we found

- The binary is byte-identical across Debian versions (`ymk` md5 matched on deb12 vs deb13). This was expected as it’s a static Go binary, dependency chain resolved at build time, zero runtime deps.
- The only differences between the two .deb’s were the `+debNN` version string and the dch build timestamp, i.e. no real per-OS divergence in contents.
- `+debNN` only changes the filename, so identical bytes get stored twice in the pool (two inodes) instead of deduping to one.
- For full reproducibility: Pinning the changelog date to the tag commit time makes the whole .deb byte-identical across builds.
- Installs and runs cleanly on Debian 11/12/13 and Ubuntu 20.04/22.04/24.04 from a single suite, zero dependency closure on every target.

So for our decision, we name packages with bare versions and publish one shared `.deb` per package, served by a single suite (`mergetb`) from the shared pool. Codename suites are  
reserved only for a package _proven_ to diverge per-OS.

- Version scheme: plain tag `vX.Y.Z` → `X.Y.Z`; point release `vX.Y.Z-N` →  
`X.Y.Z-N`.
- Alternative considered: a per-OS `+debNN` suffix, i.e. per-suite rebuilds  
tagged `+debNNuM` (Debian’s default-for-safety convention). We passed on it as  
our static Go binaries are demonstrably identical across Debian versions, so  
the suffix would only duplicate pool storage with no correctness gain. It comes  
back only if a package is shown to actually diverge.

Template location & usage:

Canonical: **`mergetb/devops/pkg/debian/deb_build.bash`** (other repos, e.g.  
`ymk`, vendor a copy).

Copy the `debian/` directory into your project and run from the project root:

```bash
./debian/deb_build.bash

```

- Locally: run as root or in CI (installs build-deps). No tag → builds the  
version already in `debian/changelog`.
- In CI: stamps the version from `$CI_COMMIT_TAG`, derives `SOURCE_DATE_EPOCH`  
from `$CI_COMMIT_TIMESTAMP`, and pins the changelog date for a reproducible  
build. Requires GNU `date`/`sed`.

---

<div class="post-metadata">

**Author:** ![jdbarnes](https://forum.mergetb.net/user_avatar/forum.mergetb.net/jdbarnes/32/57_2.png) [@jdbarnes](https://forum.mergetb.net/u/jdbarnes)\
**Post date:** [July 30, 2026, 12:51pm UTC](https://forum.mergetb.net/t/mergetb-debian-packaging/165/2 "2026-07-30T12:51:21Z")

</div>

> [@bnguyen](#):
>
> Locally: run as root or in CI (installs build-deps). No tag → builds the  
> version already in `debian/changelog`

when you say “builds the version in changelog” do you mean it builds what’s in the local repo with a version from the changelog file?

---

<div class="post-metadata">

**Author:** ![bnguyen](https://forum.mergetb.net/letter_avatar_proxy/v4/letter/b/919ad9/32.png) [@bnguyen](https://forum.mergetb.net/u/bnguyen)\
**Post date:** [August 5, 2026, 9:33pm UTC](https://forum.mergetb.net/t/mergetb-debian-packaging/165/3 "2026-08-05T21:33:28Z")

</div>

yes. it builds the source that’s checked out not anything fetched. the version on the resulting .deb is whatever’s at the top of debian/changelog.

the changelog is only rewritten on a tag: deb\_build.bash gates the `dch --newversion` on `CI_COMMIT_TAG`, splitting the tag into upstream + point-release the same way auto\_tag\_on\_merge does (v0.0.25-6 → 0.0.25-6, v1.2.3 → 1.2.3). with no tag that whole block is skipped, so `dpkg-buildpackage` just reads the existing top entry. so “no tag” = build current source, stamp it with the version already in the file.

---

<div class="post-metadata">

**Author:** ![jdbarnes](https://forum.mergetb.net/user_avatar/forum.mergetb.net/jdbarnes/32/57_2.png) [@jdbarnes](https://forum.mergetb.net/u/jdbarnes)\
**Post date:** [August 5, 2026, 11:56pm UTC](https://forum.mergetb.net/t/mergetb-debian-packaging/165/4 "2026-08-05T23:56:30Z")

</div>

that’s interesting. should the deb\_build bash try to do a newversion based on the existing tags in the git repo or the git branch that it’s in instead of just using what’s in the file? or should it try to update the file using existing tags before build?

assuming not in CI that is.

---

<div class="post-metadata">

**Author:** ![bnguyen](https://forum.mergetb.net/letter_avatar_proxy/v4/letter/b/919ad9/32.png) [@bnguyen](https://forum.mergetb.net/u/bnguyen)\
**Post date:** [August 6, 2026, 9:57pm UTC](https://forum.mergetb.net/t/mergetb-debian-packaging/165/5 "2026-08-06T21:57:31Z")

</div>

could, via `git describe`, as it gives nearest tag + commits-since + sha, stamp that into the build as a snapshot version.i’d derive into the build only though, not rewrite the file.mutating debian/changelog as a build side effect dirties the tree. CI only gets away with dch because its checkout is throwaway.
