diff --git a/Makefile b/Makefile index 162d177..fdbec19 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ MANDIR ?= $(PREFIX)/share/man SYSTEMD_UNIT_DIR ?= $(PREFIX)/lib/systemd/system CI_TEST_PORT ?= $(if $(PORT),$(PORT),2222) -.PHONY: all clean install install-systemd uninstall uninstall-systemd debug release release-check release-check-strict asan valgrind check test test-advisory ci-test unit-test script-test integration-test anonymous-access-test connection-limit-test security-test stress-test soak-test slow-client-test user-lifecycle-test info +.PHONY: all clean install install-systemd uninstall uninstall-systemd debug release release-check release-check-strict debian-source-package asan valgrind check test test-advisory ci-test unit-test script-test integration-test anonymous-access-test connection-limit-test security-test stress-test soak-test slow-client-test user-lifecycle-test info all: $(TARGETS) @@ -94,6 +94,9 @@ release-check: release-check-strict: ./scripts/release_check.sh --strict +debian-source-package: + ./scripts/package_debian_source.sh $${OUT_DIR:-dist/debian-source} + asan: CFLAGS += -g -fsanitize=address -fno-omit-frame-pointer asan: LDFLAGS += -fsanitize=address asan: clean $(TARGETS) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 25ead24..d76e1c5 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -113,6 +113,9 @@ the packaged systemd unit, and release preflight checks that metadata. - The Homebrew formula draft now defines a `brew services` entry that runs the installed `tnt` binary with state under `var/tnt`. +- Added `scripts/package_debian_source.sh` and `make debian-source-package` + to assemble Debian/Ubuntu source-package trees from the current project + without publishing or uploading anything. - The i18n helper now supports language-keyed string initializers through `I18N_STRING_MAP`, so future languages can be added incrementally without changing every existing two-language string initializer. diff --git a/packaging/README.md b/packaging/README.md index d980509..45eeaf3 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -26,13 +26,22 @@ Package installs include both `tnt` and `tntctl`. `tnt` is the server process; make release-check ``` -6. Before submitting package recipes, replace checksum placeholders and run: +6. Assemble a Debian/PPA source tree when preparing Ubuntu packaging: + + ```sh + make debian-source-package + ``` + + Use `scripts/package_debian_source.sh --build` on a Debian/Ubuntu system + with `dpkg-buildpackage` installed to build the unsigned source package. + +7. Before submitting package recipes, replace checksum placeholders and run: ```sh make release-check-strict ``` -7. Submit packages manually: +8. Submit packages manually: - Arch: upload `PKGBUILD` and generated `.SRCINFO` to AUR. - Homebrew: open a PR to the project tap, or later Homebrew core if eligible. - Ubuntu: build Debian source packages and upload to a Launchpad PPA. diff --git a/packaging/debian/README.md b/packaging/debian/README.md index 0e4e82e..11c99b3 100644 --- a/packaging/debian/README.md +++ b/packaging/debian/README.md @@ -6,18 +6,17 @@ the project has a stable release cadence. ## Draft metadata -The `debian/` directory in this folder is a packaging draft. To test it against -an upstream release tree, copy it to the root of a clean source checkout: +The `debian/` directory in this folder is a packaging draft. To assemble it +against a clean source tree: ```sh -cp -a packaging/debian/debian ./debian -dpkg-buildpackage -us -uc +make debian-source-package ``` -For PPA uploads, build a signed source package instead: +For PPA uploads, build a source package on Debian/Ubuntu: ```sh -debuild -S +scripts/package_debian_source.sh --build ``` ## Recommended path diff --git a/scripts/package_debian_source.sh b/scripts/package_debian_source.sh new file mode 100755 index 0000000..3e6af8b --- /dev/null +++ b/scripts/package_debian_source.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# Assemble a Debian/Ubuntu source-package tree. This script never uploads. + +set -eu + +usage() { + cat <<'USAGE' +Usage: scripts/package_debian_source.sh [--build] [OUT_DIR] + +Create OUT_DIR/tnt-chat-$TNT_VERSION from tracked source files and copy the +draft Debian metadata to OUT_DIR/tnt-chat-$TNT_VERSION/debian. + +Options: + --build run dpkg-buildpackage -S -us -uc after assembly + +Default OUT_DIR: dist/debian-source +USAGE +} + +fail() { + echo "package-debian-source: $*" >&2 + exit 1 +} + +BUILD=0 +OUT_DIR=${TNT_DEBIAN_SOURCE_OUT:-dist/debian-source} +OUT_SET=0 + +while [ "$#" -gt 0 ]; do + case "$1" in + --build) + BUILD=1 + ;; + -h|--help) + usage + exit 0 + ;; + -*) + fail "unknown option: $1" + ;; + *) + [ "$OUT_SET" -eq 0 ] || fail "multiple output directories" + OUT_DIR=$1 + OUT_SET=1 + ;; + esac + shift +done + +ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) +cd "$ROOT" + +VERSION=$(sed -n 's/^#define TNT_VERSION "\([^"]*\)".*/\1/p' include/common.h) +[ -n "$VERSION" ] || fail "could not read TNT_VERSION" + +SOURCE_NAME="tnt-chat-$VERSION" +SOURCE_ROOT="$OUT_DIR/$SOURCE_NAME" + +[ ! -e "$SOURCE_ROOT" ] || fail "$SOURCE_ROOT already exists" +mkdir -p "$OUT_DIR" +mkdir -p "$SOURCE_ROOT" + +git ls-files -z | cpio -0 -pdm "$SOURCE_ROOT" >/dev/null 2>&1 +cp -R "$ROOT/packaging/debian/debian" "$SOURCE_ROOT/debian" + +[ -f "$SOURCE_ROOT/debian/control" ] || fail "missing debian/control" +[ -x "$SOURCE_ROOT/debian/rules" ] || fail "missing executable debian/rules" +[ -x "$SOURCE_ROOT/debian/postinst" ] || fail "missing executable debian/postinst" + +echo "Debian source tree assembled: $SOURCE_ROOT" + +if [ "$BUILD" -eq 1 ]; then + command -v dpkg-buildpackage >/dev/null 2>&1 || + fail "dpkg-buildpackage not found" + ( + cd "$SOURCE_ROOT" + dpkg-buildpackage -S -us -uc + ) +fi diff --git a/scripts/release_check.sh b/scripts/release_check.sh index 090382c..9139f9f 100755 --- a/scripts/release_check.sh +++ b/scripts/release_check.sh @@ -173,6 +173,16 @@ grep -q "adduser .* tnt" packaging/debian/debian/postinst || grep -q " adduser" packaging/debian/debian/control || fail "Debian package must depend on adduser for postinst user creation" +step "checking Debian source assembly" +sh -n scripts/package_debian_source.sh +scripts/package_debian_source.sh "$tmpdir/debian-source" +[ -f "$tmpdir/debian-source/tnt-chat-$version/debian/control" ] || + fail "assembled Debian source tree is missing debian/control" +[ -x "$tmpdir/debian-source/tnt-chat-$version/debian/rules" ] || + fail "assembled Debian source tree is missing executable debian/rules" +[ -x "$tmpdir/debian-source/tnt-chat-$version/debian/postinst" ] || + fail "assembled Debian source tree is missing executable debian/postinst" + step "checking packaged system user metadata" grep -q '^u tnt ' packaging/arch/tnt-chat.sysusers || fail "Arch sysusers file must create the tnt system user"