feat(debian): 添加 DEB 包构建和发布工作流及相关文件

This commit is contained in:
sanchuanhehe
2025-06-10 14:33:48 +08:00
parent 463f9092a6
commit 089fc77486
15 changed files with 582 additions and 0 deletions
+182
View File
@@ -0,0 +1,182 @@
# This workflow will build and publish DEB packages for chsrc
# when there is a new release event.
name: Build and Publish DEB Package
on:
release:
types: [ released ]
workflow_dispatch:
inputs:
version:
description: 'Version to build'
required: true
default: '1.0.0'
jobs:
build-deb:
runs-on: ubuntu-latest
strategy:
matrix:
arch: [amd64, arm64, armhf]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get version from tag or input
id: get_version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
version="${{ github.event.release.tag_name }}"
version=${version#v} # Remove 'v' prefix if present
else
version="${{ github.event.inputs.version }}"
fi
echo "version=$version" >> $GITHUB_OUTPUT
echo "Version: $version"
- name: Validate version tag
run: |
version="${{ steps.get_version.outputs.version }}"
if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Invalid version format: $version"
exit 1
fi
- name: Set up cross-compilation for ARM architectures
if: matrix.arch != 'amd64'
run: |
sudo dpkg --add-architecture ${{ matrix.arch }}
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf crossbuild-essential-${{ matrix.arch }}
- name: Update debian/changelog with version
run: |
version="${{ steps.get_version.outputs.version }}"
# Update changelog with new version
cat > debian/changelog << EOF
chsrc ($version-1) unstable; urgency=medium
* Release version $version
-- Aoran Zeng <ccmywish@qq.com> $(date -R)
EOF
- name: Set up build environment
run: |
sudo apt-get update
sudo apt-get install -y debhelper devscripts build-essential fakeroot
- name: Configure cross-compilation
if: matrix.arch == 'arm64'
run: |
echo "CC=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
echo "DEB_BUILD_OPTIONS=nocheck" >> $GITHUB_ENV
- name: Configure cross-compilation for armhf
if: matrix.arch == 'armhf'
run: |
echo "CC=arm-linux-gnueabihf-gcc" >> $GITHUB_ENV
echo "DEB_BUILD_OPTIONS=nocheck" >> $GITHUB_ENV
- name: Build DEB package
run: |
version="${{ steps.get_version.outputs.version }}"
# Build the package
if [ "${{ matrix.arch }}" = "amd64" ]; then
debuild -us -uc -b
else
# For cross-compilation, we need to use dpkg-buildpackage directly
DEB_BUILD_OPTIONS="nocheck" dpkg-buildpackage -us -uc -b -a${{ matrix.arch }}
fi
# Move the generated .deb file to a known location
mkdir -p dist
find .. -name "chsrc_${version}*.deb" -exec mv {} dist/ \;
# Rename to standardized format if needed
cd dist
for file in chsrc_${version}*.deb; do
if [ -f "$file" ]; then
new_name="chsrc_${version}-1_${{ matrix.arch }}.deb"
if [ "$file" != "$new_name" ]; then
mv "$file" "$new_name"
fi
break
fi
done
- name: Verify package
run: |
version="${{ steps.get_version.outputs.version }}"
ls -la dist/
dpkg-deb --info dist/chsrc_${version}-1_${{ matrix.arch }}.deb
dpkg-deb --contents dist/chsrc_${version}-1_${{ matrix.arch }}.deb
- name: Test package installation (amd64 only)
if: matrix.arch == 'amd64'
run: |
version="${{ steps.get_version.outputs.version }}"
# Install the package
sudo dpkg -i dist/chsrc_${version}-1_${{ matrix.arch }}.deb || true
sudo apt-get install -f -y || true
# Run basic tests
if [ -f "test/deb-test.sh" ]; then
sudo bash test/deb-test.sh
else
# Basic manual test
chsrc help
echo "Package installation test passed!"
fi
- name: Upload DEB artifact
uses: actions/upload-artifact@v4
with:
name: chsrc-deb-${{ matrix.arch }}
path: dist/chsrc_*.deb
retention-days: 30
- name: Upload to release
if: github.event_name == 'release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: dist/chsrc_${{ steps.get_version.outputs.version }}-1_${{ matrix.arch }}.deb
asset_name: chsrc_${{ steps.get_version.outputs.version }}-1_${{ matrix.arch }}.deb
asset_content_type: application/vnd.debian.binary-package
create-repository-metadata:
needs: build-deb
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
pattern: chsrc-deb-*
merge-multiple: true
path: ./debs
- name: Install repository tools
run: |
sudo apt-get update
sudo apt-get install -y dpkg-dev
- name: Create Packages file
run: |
cd debs
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
dpkg-scanpackages . /dev/null > Packages
- name: Upload repository metadata
uses: actions/upload-artifact@v4
with:
name: debian-repository-metadata
path: debs/Packages*
retention-days: 30
+9
View File
@@ -33,3 +33,12 @@ chsrc.log
chsrc.toc
*.info
*.pdf
# DEB package build artifacts
debian/chsrc/
debian/.debhelper/
debian/debhelper-build-stamp
debian/files
*.deb
*.changes
*.buildinfo
+21
View File
@@ -99,3 +99,24 @@ clean:
-@rm fw 2>/dev/null
-@rm chsrc 2>/dev/null
-@rm README.md.bak* 2>/dev/null
# DEB package targets
deb-prepare: $(Target-Name)
@echo "Preparing for DEB package build..."
deb-build: deb-prepare
@echo "Building DEB package..."
@debuild -us -uc -b
deb-clean:
@echo "Cleaning DEB build artifacts..."
-@rm -rf debian/chsrc/
-@rm -f ../chsrc_*.deb ../chsrc_*.changes ../chsrc_*.buildinfo
install: $(Target-Name)
@mkdir -p $(DESTDIR)/usr/bin
@mkdir -p $(DESTDIR)/usr/share/man/man1
@cp $(Target-Name) $(DESTDIR)/usr/bin/
@cp doc/chsrc.1 $(DESTDIR)/usr/share/man/man1/ 2>/dev/null || true
.PHONY: all CI debug test test-xy test-fw fastcheck test-cli clean deb-prepare deb-build deb-clean install
+5
View File
@@ -0,0 +1,5 @@
chsrc (1.0.0) unstable; urgency=medium
* Initial debian package release
-- Aoran Zeng <ccmywish@qq.com> Mon, 10 Jun 2025 00:00:00 +0000
+22
View File
@@ -0,0 +1,22 @@
dh_update_autotools_config
dh_auto_configure
dh_auto_build
dh_auto_test
dh_prep
dh_auto_install
dh_installdocs
dh_installchangelogs
dh_installman
dh_perl
dh_link
dh_strip_nondeterminism
dh_compress
dh_fixperms
dh_missing
dh_strip
dh_makeshlibs
dh_shlibdeps
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
+3
View File
@@ -0,0 +1,3 @@
shlibs:Depends=libc6 (>= 2.34)
misc:Depends=
misc:Pre-Depends=
+1
View File
@@ -0,0 +1 @@
9
+18
View File
@@ -0,0 +1,18 @@
Source: chsrc
Section: utils
Priority: optional
Maintainer: Aoran Zeng <ccmywish@qq.com>
Build-Depends: debhelper (>= 9), build-essential, libc6-dev
Standards-Version: 4.1.2
Homepage: https://github.com/RubyMetric/chsrc
Vcs-Git: https://github.com/RubyMetric/chsrc.git
Vcs-Browser: https://github.com/RubyMetric/chsrc
Package: chsrc
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Change Source - A tool for changing software sources
chsrc is a command-line tool for changing software sources (mirrors)
for various package managers and programming language ecosystems.
It supports automatic detection and switching of sources for better
download speeds in different regions.
+29
View File
@@ -0,0 +1,29 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: chsrc
Upstream-Contact: Aoran Zeng <ccmywish@qq.com>
Source: https://github.com/RubyMetric/chsrc
Files: *
Copyright: 2023-2025 Aoran Zeng <ccmywish@qq.com>
License: GPL-3.0-or-later
Files: debian/*
Copyright: 2025 Aoran Zeng <ccmywish@qq.com>
License: GPL-3.0-or-later
License: GPL-3.0-or-later
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
Vendored Executable
+31
View File
@@ -0,0 +1,31 @@
#!/bin/sh
# postinst script for chsrc
set -e
case "$1" in
configure)
# Update man database
if command -v mandb >/dev/null 2>&1; then
mandb -q /usr/share/man/man1/chsrc.1 2>/dev/null || true
fi
# Make sure chsrc is executable
chmod +x /usr/bin/chsrc
echo "chsrc has been successfully installed!"
echo "Run 'chsrc help' to get started."
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
exit 0
Vendored Executable
+22
View File
@@ -0,0 +1,22 @@
#!/bin/sh
# prerm script for chsrc
set -e
case "$1" in
remove|upgrade|deconfigure)
# Nothing special to do during removal
;;
failed-upgrade)
;;
*)
echo "prerm called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
exit 0
Vendored Executable
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_build:
$(MAKE) all
override_dh_auto_install:
mkdir -p debian/chsrc/usr/bin
mkdir -p debian/chsrc/usr/share/man/man1
cp chsrc debian/chsrc/usr/bin/
cp doc/chsrc.1 debian/chsrc/usr/share/man/man1/
override_dh_auto_clean:
$(MAKE) clean
+103
View File
@@ -0,0 +1,103 @@
# DEB Package CI/CD
本文档说明了 chsrc 项目的 DEB 包自动构建和发布流程。
## 自动触发
DEB 包构建 CI 会在以下情况下自动触发:
1. **Release 事件**: 当创建新的 release 时自动构建并上传 DEB 包到 release assets
2. **手动触发**: 可以在 GitHub Actions 页面手动触发构建
## 支持的架构
当前支持以下架构的 DEB 包构建:
- `amd64` (x86_64)
- `arm64` (aarch64)
- `armhf` (ARMv7)
## 构建产物
每次构建会生成:
1. **DEB 包文件**: `chsrc_<version>-1_<arch>.deb`
2. **仓库元数据**: `Packages``Packages.gz` 文件用于创建 APT 仓库
## 本地测试
### 构建 DEB 包
```bash
# 准备构建环境
sudo apt-get install build-essential debhelper devscripts fakeroot
# 构建包
make deb-build
# 清理构建产物
make deb-clean
```
### 测试安装
```bash
# 安装生成的包
sudo dpkg -i ../chsrc_*.deb
sudo apt-get install -f # 修复依赖问题
# 运行测试
./test/deb-test.sh
# 卸载
sudo apt-get remove chsrc
```
## 文件结构
```
debian/
├── changelog # 版本更新日志
├── compat # debhelper 兼容性版本
├── control # 包控制信息和依赖
├── copyright # 版权信息
├── postinst # 安装后脚本
├── prerm # 卸载前脚本
└── rules # 构建规则
```
## 手动发布流程
1. 确保所有代码已合并到主分支
2. 更新版本号和 changelog
3. 创建并推送 git tag: `git tag v1.2.3 && git push origin v1.2.3`
4. 在 GitHub 上创建 release
5. CI 将自动构建并上传 DEB 包
## 故障排查
### 常见问题
1. **构建失败**: 检查 debian/control 中的依赖是否正确
2. **交叉编译失败**: 确认目标架构的工具链已正确安装
3. **安装测试失败**: 检查 postinst 脚本是否有错误
### 调试构建
```bash
# 启用详细输出
DEB_BUILD_OPTIONS="nocheck" debuild -us -uc -b
# 检查构建日志
less ../chsrc_*.build
# 检查包内容
dpkg-deb --contents chsrc_*.deb
```
## 相关文件
- `.github/workflows/pkg-deb.yml` - CI 工作流配置
- `debian/` - Debian 包配置目录
- `test/deb-test.sh` - DEB 包功能测试脚本
- `pkg/DEB-INSTALL.md` - 用户安装指南
+77
View File
@@ -0,0 +1,77 @@
# DEB Package Installation
## Installing from Release
1. Download the appropriate DEB package from the [releases page](https://github.com/RubyMetric/chsrc/releases)
2. Install using dpkg:
```bash
sudo dpkg -i chsrc_*.deb
sudo apt-get install -f # Fix any dependency issues
```
## Building from Source
### Prerequisites
Install the required build dependencies:
```bash
sudo apt-get update
sudo apt-get install build-essential debhelper devscripts fakeroot
```
### Building the Package
1. Clone the repository:
```bash
git clone https://github.com/RubyMetric/chsrc.git
cd chsrc
```
2. Build the DEB package:
```bash
make deb-build
```
3. Install the generated package:
```bash
sudo dpkg -i ../chsrc_*.deb
```
### Cross-compilation
To build for different architectures:
```bash
# For ARM64
CC=aarch64-linux-gnu-gcc dpkg-buildpackage -us -uc -b -aarm64
# For ARMv7 (armhf)
CC=arm-linux-gnueabihf-gcc dpkg-buildpackage -us -uc -b -aarmhf
```
### Cleaning Build Artifacts
```bash
make deb-clean
```
## Package Information
- **Package Name**: chsrc
- **Architecture**: amd64, arm64, armhf
- **Dependencies**: Standard C library
- **Installation Path**: `/usr/bin/chsrc`
- **Manual Page**: `/usr/share/man/man1/chsrc.1`
## Uninstalling
```bash
sudo apt-get remove chsrc
```
Or completely remove including configuration:
```bash
sudo apt-get purge chsrc
```
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
# Test script for DEB package functionality
set -e
echo "Testing chsrc DEB package..."
# Test 1: Check if chsrc binary exists and is executable
if [ ! -f "/usr/bin/chsrc" ]; then
echo "ERROR: chsrc binary not found at /usr/bin/chsrc"
exit 1
fi
if [ ! -x "/usr/bin/chsrc" ]; then
echo "ERROR: chsrc binary is not executable"
exit 1
fi
echo "✓ chsrc binary exists and is executable"
# Test 2: Check if man page exists
if [ ! -f "/usr/share/man/man1/chsrc.1" ]; then
echo "WARNING: chsrc man page not found at /usr/share/man/man1/chsrc.1"
else
echo "✓ chsrc man page exists"
fi
# Test 3: Test basic functionality
echo "Testing basic chsrc functionality..."
if chsrc help >/dev/null 2>&1; then
echo "✓ chsrc help command works"
else
echo "ERROR: chsrc help command failed"
exit 1
fi
if chsrc list >/dev/null 2>&1; then
echo "✓ chsrc list command works"
else
echo "WARNING: chsrc list command failed"
fi
echo "All DEB package tests passed!"