Внимание!
Сайт Jurik-Phys.Net сменил адрес: Jurik-Phys.Net.Ru
Для автоматического формирования файла debian/changelog используется скрипт scripts/generate-changelog.sh.
Скрипт предназначен для подготовки Debian-пакета и формирует changelog на основании истории Git. Версия пакета берётся из CMakeLists.txt, а список изменений — из коммитов ветки develop, отсутствующих в ветке main.
▸ Исходный код
▾ Исходный код скрипта
#!/bin/bash set -euo pipefail PROJECT_NAME="pingfinder-msgd" DEBIAN_REVISION="1" # Get the repository root REPO_ROOT=$(git rev-parse --show-toplevel) CMAKE_FILE="${REPO_ROOT}/CMakeLists.txt" CHANGELOG_FILE="${REPO_ROOT}/debian/changelog" # Check current branch CURRENT_BRANCH=$(git branch --show-current) if [[ "$CURRENT_BRANCH" != "develop" ]]; then echo "Error: script must be run on the develop branch." >&2 exit 1 fi # Extract project version from CMakeLists.txt VERSION=$(sed -nE \ "s/^project\(${PROJECT_NAME}[[:space:]]+VERSION[[:space:]]+([0-9]+\.[0-9]+\.[0-9]+).*/\1/p" \ "$CMAKE_FILE") if [[ -z "$VERSION" ]]; then echo "Error: project version not found in $CMAKE_FILE." >&2 exit 1 fi echo "Project version: $VERSION" # Find the latest release tag LATEST_TAG=$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-version:refname | head -n 1) if [[ -n "$LATEST_TAG" ]]; then LATEST_VERSION="${LATEST_TAG#v}" echo "Latest release: $LATEST_TAG" if dpkg --compare-versions "$VERSION" lt "$LATEST_VERSION"; then echo "Error: project version $VERSION is older than latest release $LATEST_VERSION." >&2 exit 1 elif dpkg --compare-versions "$VERSION" eq "$LATEST_VERSION"; then echo "Version status: current release version." else echo "Version status: new release version." fi else LATEST_VERSION="" echo "Latest release: none" fi # Find the latest Debian changelog update commit. # This commit is the release point in develop. RELEASE_POINT=$(git log -1 \ --format='%H' \ --grep='^Update Debian changelog for ') if [[ -n "$RELEASE_POINT" ]]; then echo "Latest release point: $(git show -s --format='%s' "$RELEASE_POINT")" else echo "Latest release point: none" fi # Get commits accumulated since the latest release point. if [[ -n "$RELEASE_POINT" ]]; then LOG_RANGE="${RELEASE_POINT}..develop" else LOG_RANGE="develop" fi COMMITS=$(git log "$LOG_RANGE" \ --pretty=format:'%s' \ --reverse \ --grep='^Update Debian changelog for' \ --invert-grep) # Find the latest release preparation commit for the current version. # It determines the date used in the Debian changelog. RELEASE_COMMIT=$(git log -1 \ --format='%H' \ --grep="^Prepare release ${VERSION}$") if [[ -z "$RELEASE_COMMIT" ]]; then echo "Error: release preparation commit not found for version $VERSION." >&2 exit 1 fi CHANGELOG_DATE=$(git show -s --format=%aD "$RELEASE_COMMIT") # Handle absence of new commits if [[ -z "$COMMITS" ]]; then if [[ -n "$LATEST_TAG" ]] && \ dpkg --compare-versions "$VERSION" eq "$LATEST_VERSION"; then echo "No changes since the latest release." else echo "Error: no changes found since the previous release." >&2 exit 1 fi fi # Get maintainer information from Git configuration MAINTAINER_NAME=$(git config user.name) MAINTAINER_EMAIL=$(git config user.email) if [[ -z "$MAINTAINER_NAME" || -z "$MAINTAINER_EMAIL" ]]; then echo "Error: Git user.name or user.email is not configured." >&2 exit 1 fi # Generate Debian changelog { echo "$PROJECT_NAME (${VERSION}-${DEBIAN_REVISION}) unstable; urgency=medium" echo if [[ -n "$COMMITS" ]]; then while IFS= read -r commit; do echo " * $commit" done <<< "$COMMITS" fi echo printf ' -- %s <%s> %s\n' \ "$MAINTAINER_NAME" \ "$MAINTAINER_EMAIL" \ "$CHANGELOG_DATE" } > "$CHANGELOG_FILE" echo "Generated $CHANGELOG_FILE:" echo cat "$CHANGELOG_FILE"
Скрипт необходимо запускать из Git-репозитория проекта. Текущей веткой должна быть develop:
./generate-changelog.sh
Скрипт самостоятельно определяет корень репозитория, поэтому его можно запускать непосредственно из каталога scripts.
Для работы скрипта необходимы:
git;dpkg, предоставляющий утилиту dpkg –compare-versions;user.name и user.email.
Версия проекта определяется из строки project() файла CMakeLists.txt:
project(pingfinder-msgd VERSION 0.0.3)
Таким образом, CMakeLists.txt является единственным источником версии проекта. Версия в Debian-файлах отдельно не задаётся.
Скрипт также определяет последний release tag вида:
v<major>.<minor>.<patch>
и сравнивает его версию с версией из CMakeLists.txt.
Возможны три состояния:
Поэтому изменение версии в CMakeLists.txt выполняется непосредственно при подготовке нового релиза.
Во время обычной разработки версия может совпадать с версией последнего выпущенного релиза.
В changelog попадают коммиты, которые присутствуют в develop, после предыдущего коммита Update Debian changelog for X.Y.Z, который выступает в роли Release point в ветке develop.
Принята следующая модель ветвления:
Сообщения коммитов сохраняются в исходном порядке и преобразуются в записи Debian changelog:
Предполагается, что сообщения коммитов должны быть достаточно информативными и понятными без дополнительного пояснения.
На основании полученной информации создаётся файл: debian/changelog
Его заголовок имеет следующий вид:
pingfinder-msgd (0.0.3-1) unstable; urgency=medium
Здесь:
generate-changelog.sh в переменной DEBIAN_REVISION;В конце записи указываются имя и email разработчика из настроек Git:
git config user.namegit config user.email,а также текущая дата в формате RFC 2822.