Add GitHub Actions workflow for KVM-based testing of debi.sh#149
Add GitHub Actions workflow for KVM-based testing of debi.sh#149cha0sCat wants to merge 1 commit intobohanwood:masterfrom
Conversation
…antic matrix and caching (#3) * Initial plan * Add GitHub Actions workflow for KVM-based testing Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Improve error handling and add security note to workflow Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Add explicit permissions to workflow for security Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Fix QEMU daemonize incompatibility with nographic option Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Fix serial.log permissions and artifact naming conflicts Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Fix script execution with pseudo-TTY for stty commands Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Add full installation verification with reboot and new password check Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * fix: only add backports if has backports * Refactor workflow with semantic matrix, caching, and Debian 11 base image Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Fix APT cache warning by using user-owned cache directory Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> Co-authored-by: Anonymous <>
|
感谢,这周末看 |
There was a problem hiding this comment.
Pull request overview
This PR introduces a GitHub Actions workflow to automatically test debi.sh by booting a KVM VM on the runner, running debi.sh inside it, rebooting into the Debian installer, and validating that the newly installed system becomes reachable via SSH.
Changes:
- Add a KVM/QEMU-based CI workflow that runs
debi.shacross a matrix of Debian versions and flags, then verifies post-install SSH access. - Add workflow documentation describing the test strategy, matrix, artifacts, and troubleshooting steps.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| .github/workflows/test.yml | New CI workflow that provisions a VM, runs debi.sh, reboots into the installer, and validates the installed OS via SSH. |
| .github/workflows/README.md | Documentation for how the workflow operates, what it tests, and how to debug failures. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Enable network console for remote installation | ||
| network_console: [true] | ||
|
|
||
| # Exclude combinations to keep matrix manageable (~12 tests) |
There was a problem hiding this comment.
The matrix size note says "(~12 tests)", but with the current axes and excludes this expands to 15 jobs (1 for v10 + 8 for v11 + 6 for v12). Please update the comment (or exclusions) so the documented size matches actual CI load.
| # Exclude combinations to keep matrix manageable (~12 tests) | |
| # Exclude combinations to keep matrix manageable (~15 tests) |
| - name: Install dependencies | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y qemu-kvm qemu-utils cloud-image-utils genisoimage expect sshpass |
There was a problem hiding this comment.
expect and cloud-image-utils are installed but not used anywhere in this workflow. Removing unused packages will reduce apt time and cache size (or add the missing usage if intended).
| sudo apt-get install -y qemu-kvm qemu-utils cloud-image-utils genisoimage expect sshpass | |
| sudo apt-get install -y qemu-kvm qemu-utils genisoimage sshpass |
| key: debian-11-cloud-image-${{ hashFiles('.github/workflows/test.yml') }} | ||
| restore-keys: | | ||
| debian-11-cloud-image- | ||
|
|
||
| - name: Download Debian 11 cloud image | ||
| if: steps.cache-debian-image.outputs.cache-hit != 'true' | ||
| run: | | ||
| wget -O /tmp/debian-11-base.qcow2 "https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2" |
There was a problem hiding this comment.
The Debian 11 base image cache key is only tied to the workflow file hash, so it may stay pinned to an old bullseye/latest image indefinitely. Consider either pinning the download to a specific known-good build/checksum, or adding a periodic component (e.g., weekly) to the cache key so the base image refreshes over time.
| key: debian-11-cloud-image-${{ hashFiles('.github/workflows/test.yml') }} | |
| restore-keys: | | |
| debian-11-cloud-image- | |
| - name: Download Debian 11 cloud image | |
| if: steps.cache-debian-image.outputs.cache-hit != 'true' | |
| run: | | |
| wget -O /tmp/debian-11-base.qcow2 "https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2" | |
| key: debian-11-cloud-image-debian-11-generic-amd64-20250113-1734 | |
| restore-keys: | | |
| debian-11-cloud-image- | |
| - name: Download Debian 11 cloud image | |
| if: steps.cache-debian-image.outputs.cache-hit != 'true' | |
| run: | | |
| wget -O /tmp/debian-11-base.qcow2 "https://cloud.debian.org/images/cloud/bullseye/20250113-1734/debian-11-generic-amd64-20250113-1734.qcow2" |
|
|
||
| echo "=== Trying to connect with new credentials ===" | ||
| sshpass -p 'newpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -p 2222 ${{ matrix.user }}@localhost \ | ||
| 'journalctl -n 100' 2>/dev/null || echo "Could not connect with new credentials" |
There was a problem hiding this comment.
On failures, this runs journalctl as ${{ matrix.user }}. For the non-root user case, journalctl often requires root/journal group access and may exit non-zero, which would be misreported as an SSH failure. Prefer sudo journalctl ... here (the script installs a NOPASSWD sudoers entry for the created user) or explicitly connect as root when matrix.user != 'root'.
| 'journalctl -n 100' 2>/dev/null || echo "Could not connect with new credentials" | |
| 'sudo journalctl -n 100' 2>/dev/null || echo "Could not connect with new credentials" |
| - Polls for SSH availability with the **new password** (`newpass123`) | ||
| - Verifies the newly installed system | ||
|
|
||
| ### 7. Success Criteria |
There was a problem hiding this comment.
Section numbering is inconsistent: there are two "### 7" headings ("Full Installation Test" and "Success Criteria"). Please renumber so the document structure is unambiguous.
| ### 7. Success Criteria | |
| ### 8. Success Criteria |
| cat > /tmp/cloud-init/meta-data << 'EOF' | ||
| instance-id: test-debi-vm | ||
| local-hostname: test-debi | ||
| EOF | ||
|
|
||
| # user-data with root access | ||
| cat > /tmp/cloud-init/user-data << 'EOF' | ||
| #cloud-config | ||
| users: | ||
| - name: root | ||
| lock_passwd: false | ||
| plain_text_passwd: 'rootpass123' | ||
|
|
||
| ssh_pwauth: true | ||
| disable_root: false | ||
|
|
||
| packages: | ||
| - wget | ||
| - curl | ||
|
|
||
| runcmd: | ||
| - sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config | ||
| - systemctl restart sshd |
There was a problem hiding this comment.
The cloud-init user-data heredoc content is indented, so the first line is not #cloud-config at column 1. Cloud-init requires the magic header to start at the beginning of the line; with leading spaces it may ignore the file and the VM won’t get the expected SSH/password configuration. Please generate the heredoc without leading indentation (or use a <<-EOF heredoc with tab-indented content).
| cat > /tmp/cloud-init/meta-data << 'EOF' | |
| instance-id: test-debi-vm | |
| local-hostname: test-debi | |
| EOF | |
| # user-data with root access | |
| cat > /tmp/cloud-init/user-data << 'EOF' | |
| #cloud-config | |
| users: | |
| - name: root | |
| lock_passwd: false | |
| plain_text_passwd: 'rootpass123' | |
| ssh_pwauth: true | |
| disable_root: false | |
| packages: | |
| - wget | |
| - curl | |
| runcmd: | |
| - sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config | |
| - systemctl restart sshd | |
| cat > /tmp/cloud-init/meta-data <<-'EOF' | |
| instance-id: test-debi-vm | |
| local-hostname: test-debi | |
| EOF | |
| # user-data with root access | |
| cat > /tmp/cloud-init/user-data <<-'EOF' | |
| #cloud-config | |
| users: | |
| - name: root | |
| lock_passwd: false | |
| plain_text_passwd: 'rootpass123' | |
| ssh_pwauth: true | |
| disable_root: false | |
| packages: | |
| - wget | |
| - curl | |
| runcmd: | |
| - sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config | |
| - systemctl restart sshd |
| # meta-data | ||
| cat > /tmp/cloud-init/meta-data << 'EOF' | ||
| instance-id: test-debi-vm | ||
| local-hostname: test-debi | ||
| EOF |
There was a problem hiding this comment.
The meta-data heredoc is also written with leading spaces. Even if some YAML parsers tolerate this, it’s safer to write NoCloud meta-data with top-level keys starting at column 1 to avoid datasource parsing issues.
使用 workflow 对
debi.sh进行自动化测试这个 workflow 会启动一个 KVM 虚拟机,并真的使用
debi.sh安装系统。甚至通过 matrix,可以自动测试不同参数组合的结果。
辨别测试成功的方式:
KVM 基础镜像的密码,与
debi.sh --password设置的密码不同通过不断使用新密码 ssh 到机器,如果链接成功,则代表 DD 成功。
在 #148 pr 过程中,我们就已经用到了这个测试
148 补丁生效前,D11 安装测试以超时失败告终
https://github.com/cha0sCat/debi/actions/runs/19710528118
148 生效后,所有测试通过
https://github.com/cha0sCat/debi/actions/runs/19711492115
另外,我们还通过此功能,成功发现了一个潜伏的问题:
D10 无法安装,因为
debian-installer镜像被移动到archive.debian.orghttps://github.com/cha0sCat/debi/actions/runs/19725225408