mirror of
https://github.com/RubyMetric/chsrc
synced 2025-06-18 09:47:01 +08:00
feat(debian): 添加 DEB 包构建和发布工作流及相关文件
This commit is contained in:
parent
463f9092a6
commit
089fc77486
182
.github/workflows/pkg-deb.yml
vendored
Normal file
182
.github/workflows/pkg-deb.yml
vendored
Normal 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
.gitignore
vendored
9
.gitignore
vendored
@ -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
Makefile
21
Makefile
@ -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
debian/changelog
vendored
Normal file
5
debian/changelog
vendored
Normal 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
debian/chsrc.debhelper.log
vendored
Normal file
22
debian/chsrc.debhelper.log
vendored
Normal 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
debian/chsrc.substvars
vendored
Normal file
3
debian/chsrc.substvars
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
shlibs:Depends=libc6 (>= 2.34)
|
||||
misc:Depends=
|
||||
misc:Pre-Depends=
|
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@ -0,0 +1 @@
|
||||
9
|
18
debian/control
vendored
Normal file
18
debian/control
vendored
Normal 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
debian/copyright
vendored
Normal file
29
debian/copyright
vendored
Normal 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".
|
31
debian/postinst
vendored
Executable file
31
debian/postinst
vendored
Executable 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
|
22
debian/prerm
vendored
Executable file
22
debian/prerm
vendored
Executable 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
|
16
debian/rules
vendored
Executable file
16
debian/rules
vendored
Executable 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
pkg/DEB-CI.md
Normal file
103
pkg/DEB-CI.md
Normal 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
pkg/DEB-INSTALL.md
Normal file
77
pkg/DEB-INSTALL.md
Normal 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
test/deb-test.sh
Executable file
43
test/deb-test.sh
Executable 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!"
|
Loading…
x
Reference in New Issue
Block a user