自用笔记,很多内容都还不清楚,仅供参考。
参考文档
Salsa
- 避免将官方 Debian 仓库作为源代码版本控制系统使用。改用 git 仓库进行频繁操作。
- 建议使用 git-buildpackage 作为维护 Debian 源码包的最广泛工具,且
gbp.conf 应当放置在 repo/debian 目录中。 - 使用 gbp pq 以便维护和测试上游补丁。
- 如果软件包有自定义工具或流程,请将其记录在
README.source(.md),以便于他人协作和维护。 - DEP-18 示例:
Entr repo
注意
debian/README.source.md 文件, - Salsa CI 详解
准备工作
以下默认使用 sbuild
1
| sudo apt update -q && sudo apt install -q --yes sbuild mmdebstrap uidmap piuparts git-buildpackage dpkg-dev dh-make apt-cacher-ng
|
设置变量 fish shell 用户, ~/.config/fish/conf.d/debian-dev.fish
1
2
3
4
5
6
7
8
9
10
| set -gx DEBEMAIL "sd44sd44@yeah.net"
set -gx DEBFULLNAME "Hoho Sd44"
function fish_command_not_found
/usr/bin/command-not-found $argv[1]
end
set -gx DEBUILD_DPKG_BUILDPACKAGE_OPTS "-i -I -us -uc"
set -gx DEBUILD_LINTIAN_OPTS "-i -I --show-overrides"
set -gx DEBSIGN_KEYID "DBBF53F41DF90D31A0C0D0134F4D76C33BA3B42D"
|
1
2
| mkdir -p ~/.cache/sbuild
mmdebstrap --skip=output/dev --variant=buildd --include=eatmydata unstable ~/.cache/sbuild/unstable-amd64.tar.zst http://ftp.cn.debian.org/debian --aptopt='Acquire::http { Proxy "http://127.0.0.1:3142"; }'
|
~/.gbp.conf 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| # Configuration file for gbp <command> gbp.conf
# https://salsa.debian.org/debian/entr/-/blob/debian/latest/debian/gbp.conf
[DEFAULT]
# Manage a "pristine-tar" branch:
pristine-tar = True
pristine-tar-commit = True
# Use Debian-style DEP-14 branch names:
upstream-branch=upstream/latest
debian-branch=debian/latest
# Lax requirement to use branch name 'debian/latest' so that git-buildpackage
# will always build using the currently checked out branch as the Debian branch.
# This makes it easier for contributors to work with feature and bugfix
# branches.
ignore-branch = True
# Build packages with pbuilder:
# pbuilder = True
# Or use sbuild:
builder = sbuild
# Sign tags (optional):
sign-tags = True
keyid = DBBF53F41DF90D31A0C0D0134F4D76C33BA3B42D
# Ease dropping / adding patches
patch-numbers = False
# Ensure a human always reviews all the debian/changelog entries.
spawn-editor = always
# No need to confirm package name or version at any time, git-buildpackage
# always gets it right.
interactive = False
# Ensure we always target Debian on Debian branches
dch-opt = --vendor=debian
# If this package ever needs to be maintained for Ubuntu, remember to override
# the branch, tag and commit messages
#debian-branch = ubuntu/24.04-noble
#debian-tag = ubuntu/%(version)s
#debian-tag-msg = %(pkg)s Ubuntu release %(version)s
#dch-opt = --vendor=ubuntu
|
我使用的是 sbuild,配置文件 ~/.config/sbuild/config.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| ##############################################################################
# PACKAGE BUILD RELATED (source-only-upload as default)
##############################################################################
#
# 使用 unshare 后端,无需 sudo
$chroot_mode = 'unshare';
# 失败时进入 Shell(非常有用,省去重新构建来排错的时间)
$external_commands = { "build-failed-commands" => [ [ '%SBUILD_SHELL' ] ] };
# -d
$distribution = 'unstable';
# -A
$build_arch_all = 1;
# -s
$build_source = 1;
# Produce a source.changes file suitable for a source-only upload;
# this is the same as passing `--source-only-changes` to sbuild.
$source_only_changes = 1;
# 自动清理生成的临时文件
$purge_build_deps = 'successful';
$purge_build_directory = 'successful';
# 统计构建时间
# $stats_dir = "$homedir/log/sbuild/stats";
# -v
#$verbose = 1;
##############################################################################
# POST-BUILD RELATED (turn off functionality by setting variables to 0)
##############################################################################
$run_lintian = 1;
$lintian_opts = ['--display-info', '--verbose', '--fail-on', 'error,warning', '--info'];
$run_autopkgtest = 1;
# Run piuparts after every build (in a new, temporary, chroot); use --no-run-piuparts to override.
# this does not work in bookworm
$run_piuparts = 1;
# Build a temporary chroot.
# $piuparts_opts = ['--no-eatmydata', '--distribution=%r', '--fake-essential-packages=systemd-sysv'];
# Build a temporary chroot that uses apt-cacher-ng as a proxy to save bandwidth and time and doesn't disable eatmydata to speed up processing.
$piuparts_opts = ['--distribution=%r', '--bootstrapcmd=mmdebstrap --skip=check/empty --variant=minbase --aptopt="Acquire::http { Proxy \\"http://127.0.0.1:3142\\"; }"'];
|
导入仓库
获取已在 Debian 仓库中的软件包源代码
1
2
3
4
| gbp clone vcs-git:some-project --add-upstream-vcs
# 或者,运行此程序来定义一个需要跟踪的上游分支:
gbp clone vcs-git:some-project \
--postclone="git remote add -t develop -f upstreamvcs https://github.com/eradman/entr.git"
|
Import from tarballs
如果上游有 tarballs, 推荐
1
2
3
| git init --initial-branch="$(gbp config DEFAULT.debian-branch)" some-project.git
cd some-project.git
gbp import-orig https://some-project.example.com/releases/some-project_1.0.tar.gz
|
这会把 tarball 拉到你在 ~/.gbp.conf 中指定的上游和 Debian 分支,创建新 upstream/1.0 标签,并更新分支 pristine-tar (如果你设置了这个选项)。
你还应该创建一个 debian/watch 文件来说明 git-buildpackage 如何拉新的 tarballs。详情请参见
debian/watch
。
Import from an upstream git repository
1
2
3
4
5
6
7
| # Clone the upstream repository and `cd` into it:
git clone https://forge.example.com/some-project.git
cd project.git
# Use DEP-14 branch names
git branch -m upstream/latest
git checkout -b debian/latest
|
同步上游代码: git pull upstream/latest .
If there is no upstream
有些项目没有上游。例如 Debian 原生专属包,或者上游已消失或无法获取。
无上游项目通常有一个单一仓库,一个分支是上游代码,另一个分支是 Debian 打包。
1
2
3
4
| # Set branch name when creating the repo:
git init --initial-branch="$(gbp config DEFAULT.upstream-branch)" some-project
# Or rename the branch when you start to Debianise:
git branch -m master "$(gbp config DEFAULT.upstream-branch)"
|
1
2
| git checkout -b "$(gbp config DEFAULT.debian-branch)" \
--track "$(gbp config DEFAULT.upstream-branch)"
|
初始化 debian 目录
如果还没有创建,或删除后重建 debian 目录:
1
| dh_make -c gpl3 -p some-project_version --createorig -sy
|
- -c
- 指定 license
- -e
- email-adress : 在 debian/control 文件的 Maintainer:字段中使用
email-address 作为电子邮件地址。
- –createorig
- 创建 orig.tar.xxx 文件
- -s
- 设置软件包类型为 single。主要分为 4 类:single、indep、library、python
- -y
对于创建过程中的需要确认的信息默认为 yes
生成的 .ex 文件均为示例模板,可修改后去除 .ex 后缀,修改后成为正式文件(注:gitignore.ex 应改名为 .gitignore)。
按需修改 gbp.conf, changelog, control, copyright, rules, .gitignore 等,可参照
debmake doc
,
deeplin 打包说明
.
修改后:
1
2
| git add debian/
git commit -a -m "Initial Debian packaging"
|
补丁和构建
如果你需要修改源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 1. 进入/重置补丁队列
gbp pq import --force
# --- 在这里进行你的修改、Cherry-pick 等操作 ---
# git add .
# git commit -m "fix something"
# 2. 导出补丁并自动提交到主分支
# --drop 保证主分支干净,--commit 自动 add debian/patches
gbp pq export --drop --commit
# 3. 润色提交信息 (可选)
# 这一步会打开编辑器,让你把 "Update patches" 改成更有意义的信息
git commit --amend
# 4. 正式构建
# 此时你已经回到了 debian/latest 分支,gbp 能找到所有需要的 treeish
gbp buildpackage
|
用 gbp dch 管理 debian/changelog
gbp dch 的核心理念是:Git Commit Message 即是 Changelog。
常用操作流程
1
2
3
4
5
6
7
8
9
| # 1. 根据上一个 tag 至今的所有 commit 自动生成临时 changelog
gbp dch --auto --snapshot
# 2. 如果准备发布新版本(例如 5.7-1)
# 这会移除 "snapshot" 标记,更新版本号,并标记为已释放(unreleased -> unstable)
gbp dch --auto --release --new-version=5.7-1
# 3. 检查并手动润色(如有必要)
git commit -m "Update changelog for 5.7-1" debian/changelog
|
完整操作实例:从上游拉取到发布新版本
以下记录将 mohanxlsx 从 0.1.0 更新到 0.1.2-1 的完整流程。
1. 拉取上游分支并打 tag
1
2
3
4
5
6
7
8
9
10
11
| # 确保在 debian/latest 分支上
git checkout debian/latest
# 拉取上游最新代码
git fetch origin upstream/latest
# 在上游最新提交上打上游版本 tag(需 GPG 签名)
git tag -s upstream/0.1.2 upstream/latest -m "Upstream release 0.1.2"
# 验证 tag
git tag -v upstream/0.1.2
|
2. 合并上游到 Debian 分支
1
2
3
4
| # 将上游最新代码合入 debian/latest
git merge upstream/latest --no-edit
# 如果有冲突,手动解决后 git commit
|
3. 使用 gbp pq 管理补丁
1
2
3
4
5
6
7
8
9
10
11
| # 导入补丁队列(切换到 patch-queue 分支)
gbp pq import --force
# 在 patch-queue 分支上进行修改
# 例如:更新 pyproject.toml 中的版本号
sed -i 's/version = "0.1.0"/version = "0.1.2"/' pyproject.toml
git add pyproject.toml
git commit -m "Update upstream version to 0.1.2"
# 导出补丁并切回 debian/latest,自动提交补丁文件
gbp pq export --drop --commit
|
4. 用 gbp dch 生成 changelog
1
2
3
4
5
6
7
| # 根据自上一个 tag 以来的 commit 自动生成 changelog
gbp dch --auto --release --new-version=0.1.2-1
# 注意:如果 spawn-editor = always 导致 EDITOR 阻塞,可用 EDITOR=true 前置
# 提交 changelog
git add debian/changelog
git commit -m "Update changelog for 0.1.2-1"
|
5. 构建前检查与避险
1
2
3
4
5
6
7
8
9
| # 确保 debian/source/options 排除本地开发文件
# 以下为示例 extend-diff-ignore 配置:
# extend-diff-ignore = "^[^/]*[.]egg-info/|^.venv/|^.claude/|^.pdm-python$|^pdm.lock$"
# 确保 .gitignore 包含虚拟环境和构建产物
# .venv/、.pc/、dist/ 等
# 删除本地虚拟环境和构建缓存
rm -rf .venv .pybuild/ dist/
|
6. 构建
1
2
| # 执行构建(--git-ignore-new 忽略补丁造成的未提交变更)
gbp buildpackage --git-ignore-new
|
构建产物位于上级目录:
mohanxlsx_0.1.2.orig.tar.xz — 上游源码 tarballmohanxlsx_0.1.2-1.debian.tar.xz — Debian 打包 tarballmohanxlsx_0.1.2-1.dsc — 源码控制文件python3-mohanxlsx_0.1.2-1_all.deb — 二进制包
常见问题
dpkg-source: error: cannot represent change to .venv/…
原因:工作目录中存在 Python 虚拟环境(.venv),其软链接无法被 dpkg-source 处理。
解决:删除 .venv/,并在 .gitignore 和 debian/source/options 中排除。
dpkg-source: error: aborting due to unexpected upstream changes
原因:quilt 补丁未在源码树中应用,dpkg-source(format 3.0 quilt)要求补丁在构建前已应用。
解决:执行 quilt push -a 或 gbp pq import --force 后确保补丁已应用。
gbp:error: You have uncommitted changes in your source tree
原因:quilt 补丁应用后修改了文件,但 git 未追踪这些修改。
解决:使用 gbp buildpackage --git-ignore-new 忽略未提交变更继续构建。