From 195c680455a713fd84153e55e55e9656ede4f64f Mon Sep 17 00:00:00 2001 From: holger krekel Date: Sat, 7 Mar 2026 14:36:27 +0100 Subject: [PATCH] ci: replace staging workflows with LXC-local testing Replace the two staging-server CI workflows and their zone-file helpers with a single lxc-test job in ci.yaml that runs 'cmdeploy lxc-test' inside an ubuntu-24.04 runner. The new workflow installs Incus from the Zabbly apt repository, initialises it, bootstraps the venv, caches the base LXC image together with SSH keys, and runs the full LXC pipeline (container creation, deploy, DNS zones, tests). --- .github/workflows/ci.yaml | 68 ++++++++++-- .../staging-ipv4.testrun.org-default.zone | 20 ---- .../staging.testrun.org-default.zone | 21 ---- .../workflows/test-and-deploy-ipv4only.yaml | 104 ------------------ .github/workflows/test-and-deploy.yaml | 97 ---------------- 5 files changed, 59 insertions(+), 251 deletions(-) delete mode 100644 .github/workflows/staging-ipv4.testrun.org-default.zone delete mode 100644 .github/workflows/staging.testrun.org-default.zone delete mode 100644 .github/workflows/test-and-deploy-ipv4only.yaml delete mode 100644 .github/workflows/test-and-deploy.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9af1c3f5..ea8bd64d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,27 +16,77 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: download filtermail run: curl -L https://github.com/chatmail/filtermail/releases/download/v0.5.2/filtermail-x86_64 -o /usr/local/bin/filtermail && chmod +x /usr/local/bin/filtermail - - name: run chatmaild tests + - name: run chatmaild tests working-directory: chatmaild run: pipx run tox scripts: - name: deploy-chatmail tests + name: deploy-chatmail tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: initenv + - name: initenv run: scripts/initenv.sh - name: append venv/bin to PATH run: echo venv/bin >>$GITHUB_PATH - - name: run formatting checks - run: cmdeploy fmt -v + - name: run formatting checks + run: cmdeploy fmt -v - - name: run deploy-chatmail offline tests - run: pytest --pyargs cmdeploy + - name: run deploy-chatmail offline tests + run: pytest --pyargs cmdeploy - # all other cmdeploy commands require a staging server - # see https://github.com/deltachat/chatmail/issues/100 + lxc-test: + name: LXC deploy and test + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: install incus + run: | + # zabbly is the official incus community packages source + curl -fsSL https://pkgs.zabbly.com/key.asc \ + | sudo gpg --dearmor -o /etc/apt/keyrings/zabbly.gpg + sudo sh -c 'cat < /etc/apt/sources.list.d/zabbly-incus-stable.sources + Enabled: yes + Types: deb + URIs: https://pkgs.zabbly.com/incus/stable + Suites: $(. /etc/os-release && echo ${VERSION_CODENAME}) + Components: main + Architectures: $(dpkg --print-architecture) + Signed-By: /etc/apt/keyrings/zabbly.gpg + EOF' + sudo apt-get update + sudo apt-get install -y incus + + - name: initialise incus + run: | + sudo systemctl stop docker.socket docker || true + sudo iptables -P FORWARD ACCEPT + sudo sysctl -w fs.inotify.max_user_instances=65535 + sudo sysctl -w fs.inotify.max_user_watches=65535 + sudo incus admin init --minimal + sudo usermod -aG incus-admin "$USER" + + - name: initenv + run: scripts/initenv.sh + + - name: append venv/bin to PATH + run: echo venv/bin >>$GITHUB_PATH + + - name: lxc-test + run: sg incus-admin -c 'cmdeploy lxc-test' + + - name: export images for cache + if: always() + run: | + for alias in localchat-base localchat-ns localchat-test0 localchat-test1; do + if ! [ -f /tmp/$alias.tar.gz ]; then + sg incus-admin -c "incus image export $alias /tmp/$alias" || true + fi + done diff --git a/.github/workflows/staging-ipv4.testrun.org-default.zone b/.github/workflows/staging-ipv4.testrun.org-default.zone deleted file mode 100644 index 785b71aa..00000000 --- a/.github/workflows/staging-ipv4.testrun.org-default.zone +++ /dev/null @@ -1,20 +0,0 @@ -;; Zone file for staging-ipv4.testrun.org - -$ORIGIN staging-ipv4.testrun.org. -$TTL 300 - -@ IN SOA ns.testrun.org. root.nine.testrun.org ( - 2023010101 ; Serial - 7200 ; Refresh - 3600 ; Retry - 1209600 ; Expire - 3600 ; Negative response caching TTL -) - -;; Nameservers. -@ IN NS ns.testrun.org. - -;; DNS records. -@ IN A 37.27.95.249 -mta-sts.staging-ipv4.testrun.org. CNAME staging-ipv4.testrun.org. -www.staging-ipv4.testrun.org. CNAME staging-ipv4.testrun.org. diff --git a/.github/workflows/staging.testrun.org-default.zone b/.github/workflows/staging.testrun.org-default.zone deleted file mode 100644 index 444e4d86..00000000 --- a/.github/workflows/staging.testrun.org-default.zone +++ /dev/null @@ -1,21 +0,0 @@ -;; Zone file for staging2.testrun.org - -$ORIGIN staging2.testrun.org. -$TTL 300 - -@ IN SOA ns.testrun.org. root.nine.testrun.org ( - 2023010101 ; Serial - 7200 ; Refresh - 3600 ; Retry - 1209600 ; Expire - 3600 ; Negative response caching TTL -) - -;; Nameservers. -@ IN NS ns.testrun.org. - -;; DNS records. -@ IN A 37.27.24.139 -mta-sts.staging2.testrun.org. CNAME staging2.testrun.org. -www.staging2.testrun.org. CNAME staging2.testrun.org. - diff --git a/.github/workflows/test-and-deploy-ipv4only.yaml b/.github/workflows/test-and-deploy-ipv4only.yaml deleted file mode 100644 index 990963ec..00000000 --- a/.github/workflows/test-and-deploy-ipv4only.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: deploy on staging-ipv4.testrun.org, and run tests - -on: - push: - branches: - - main - pull_request: - paths-ignore: - - 'scripts/**' - - '**/README.md' - - 'CHANGELOG.md' - - 'LICENSE' - -jobs: - deploy: - name: deploy on staging-ipv4.testrun.org, and run tests - runs-on: ubuntu-latest - timeout-minutes: 30 - environment: - name: staging-ipv4.testrun.org - url: https://staging-ipv4.testrun.org/ - concurrency: staging-ipv4.testrun.org - steps: - - uses: actions/checkout@v4 - - - name: prepare SSH - run: | - mkdir ~/.ssh - echo "${{ secrets.STAGING_SSH_KEY }}" >> ~/.ssh/id_ed25519 - chmod 600 ~/.ssh/id_ed25519 - ssh-keyscan staging-ipv4.testrun.org > ~/.ssh/known_hosts - # save previous acme & dkim state - rsync -avz root@staging-ipv4.testrun.org:/var/lib/acme acme-ipv4 || true - rsync -avz root@staging-ipv4.testrun.org:/etc/dkimkeys dkimkeys-ipv4 || true - # store previous acme & dkim state on ns.testrun.org, if it contains useful certs - if [ -f dkimkeys-ipv4/dkimkeys/opendkim.private ]; then rsync -avz -e "ssh -o StrictHostKeyChecking=accept-new" dkimkeys-ipv4 root@ns.testrun.org:/tmp/ || true; fi - if [ "$(ls -A acme-ipv4/acme/certs)" ]; then rsync -avz -e "ssh -o StrictHostKeyChecking=accept-new" acme-ipv4 root@ns.testrun.org:/tmp/ || true; fi - # make sure CAA record isn't set - scp -o StrictHostKeyChecking=accept-new .github/workflows/staging-ipv4.testrun.org-default.zone root@ns.testrun.org:/etc/nsd/staging-ipv4.testrun.org.zone - ssh root@ns.testrun.org sed -i '/CAA/d' /etc/nsd/staging-ipv4.testrun.org.zone - ssh root@ns.testrun.org nsd-checkzone staging-ipv4.testrun.org /etc/nsd/staging-ipv4.testrun.org.zone - ssh root@ns.testrun.org systemctl reload nsd - - - name: rebuild staging-ipv4.testrun.org to have a clean VPS - run: | - curl -X POST \ - -H "Authorization: Bearer ${{ secrets.HETZNER_API_TOKEN }}" \ - -H "Content-Type: application/json" \ - -d '{"image":"debian-12"}' \ - "https://api.hetzner.cloud/v1/servers/${{ secrets.STAGING_IPV4_SERVER_ID }}/actions/rebuild" - - - run: scripts/initenv.sh - - - name: append venv/bin to PATH - run: echo venv/bin >>$GITHUB_PATH - - - name: upload TLS cert after rebuilding - run: | - echo " --- wait until staging-ipv4.testrun.org VPS is rebuilt --- " - rm ~/.ssh/known_hosts - while ! ssh -o ConnectTimeout=180 -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org id -u ; do sleep 1 ; done - ssh -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org id -u - # download acme & dkim state from ns.testrun.org - rsync -e "ssh -o StrictHostKeyChecking=accept-new" -avz root@ns.testrun.org:/tmp/acme-ipv4/acme acme-restore || true - rsync -avz root@ns.testrun.org:/tmp/dkimkeys-ipv4/dkimkeys dkimkeys-restore || true - # restore acme & dkim state to staging2.testrun.org - rsync -avz acme-restore/acme root@staging-ipv4.testrun.org:/var/lib/ || true - rsync -avz dkimkeys-restore/dkimkeys root@staging-ipv4.testrun.org:/etc/ || true - ssh -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org chown root:root -R /var/lib/acme || true - - - name: run deploy-chatmail offline tests - run: pytest --pyargs cmdeploy - - - name: setup dependencies - run: | - ssh root@staging-ipv4.testrun.org apt update - ssh root@staging-ipv4.testrun.org apt install -y git python3.11-venv python3-dev gcc - ssh root@staging-ipv4.testrun.org git clone https://github.com/chatmail/relay - ssh root@staging-ipv4.testrun.org "cd relay && git checkout " ${{ github.head_ref }} - ssh root@staging-ipv4.testrun.org "cd relay && scripts/initenv.sh" - - - name: initialize config - run: | - ssh root@staging-ipv4.testrun.org "cd relay && scripts/cmdeploy init staging-ipv4.testrun.org" - ssh root@staging-ipv4.testrun.org "sed -i 's#disable_ipv6 = False#disable_ipv6 = True#' relay/chatmail.ini" - ssh root@staging-ipv4.testrun.org "sed -i 's/#\s*mtail_address/mtail_address/' relay/chatmail.ini" - - - run: ssh root@staging-ipv4.testrun.org "cd relay && scripts/cmdeploy run --verbose --skip-dns-check --ssh-host localhost" - - - name: set DNS entries - run: | - ssh root@staging-ipv4.testrun.org "cd relay && scripts/cmdeploy dns --zonefile staging-generated.zone --ssh-host localhost" - ssh root@staging-ipv4.testrun.org cat relay/staging-generated.zone >> .github/workflows/staging-ipv4.testrun.org-default.zone - cat .github/workflows/staging-ipv4.testrun.org-default.zone - scp .github/workflows/staging-ipv4.testrun.org-default.zone root@ns.testrun.org:/etc/nsd/staging-ipv4.testrun.org.zone - ssh root@ns.testrun.org nsd-checkzone staging-ipv4.testrun.org /etc/nsd/staging-ipv4.testrun.org.zone - ssh root@ns.testrun.org systemctl reload nsd - - - name: cmdeploy test - run: ssh root@staging-ipv4.testrun.org "cd relay && CHATMAIL_DOMAIN2=ci-chatmail.testrun.org scripts/cmdeploy test --slow --ssh-host localhost" - - - name: cmdeploy dns - run: ssh root@staging-ipv4.testrun.org "cd relay && scripts/cmdeploy dns -v --ssh-host localhost" - diff --git a/.github/workflows/test-and-deploy.yaml b/.github/workflows/test-and-deploy.yaml deleted file mode 100644 index 2f744cb8..00000000 --- a/.github/workflows/test-and-deploy.yaml +++ /dev/null @@ -1,97 +0,0 @@ -name: deploy on staging2.testrun.org, and run tests - -on: - push: - branches: - - main - pull_request: - paths-ignore: - - 'scripts/**' - - '**/README.md' - - 'CHANGELOG.md' - - 'LICENSE' - -jobs: - deploy: - name: deploy on staging2.testrun.org, and run tests - runs-on: ubuntu-latest - timeout-minutes: 30 - environment: - name: staging2.testrun.org - url: https://staging2.testrun.org/ - concurrency: staging2.testrun.org - steps: - - uses: actions/checkout@v4 - - - name: prepare SSH - run: | - mkdir ~/.ssh - echo "${{ secrets.STAGING_SSH_KEY }}" >> ~/.ssh/id_ed25519 - chmod 600 ~/.ssh/id_ed25519 - ssh-keyscan staging2.testrun.org > ~/.ssh/known_hosts - # save previous acme & dkim state - rsync -avz root@staging2.testrun.org:/var/lib/acme . || true - rsync -avz root@staging2.testrun.org:/etc/dkimkeys . || true - # store previous acme & dkim state on ns.testrun.org, if it contains useful certs - if [ -f dkimkeys/opendkim.private ]; then rsync -avz -e "ssh -o StrictHostKeyChecking=accept-new" dkimkeys root@ns.testrun.org:/tmp/ || true; fi - if [ "$(ls -A acme/certs)" ]; then rsync -avz -e "ssh -o StrictHostKeyChecking=accept-new" acme root@ns.testrun.org:/tmp/ || true; fi - # make sure CAA record isn't set - scp -o StrictHostKeyChecking=accept-new .github/workflows/staging.testrun.org-default.zone root@ns.testrun.org:/etc/nsd/staging2.testrun.org.zone - ssh root@ns.testrun.org sed -i '/CAA/d' /etc/nsd/staging2.testrun.org.zone - ssh root@ns.testrun.org nsd-checkzone staging2.testrun.org /etc/nsd/staging2.testrun.org.zone - ssh root@ns.testrun.org systemctl reload nsd - - - name: rebuild staging2.testrun.org to have a clean VPS - run: | - curl -X POST \ - -H "Authorization: Bearer ${{ secrets.HETZNER_API_TOKEN }}" \ - -H "Content-Type: application/json" \ - -d '{"image":"debian-12"}' \ - "https://api.hetzner.cloud/v1/servers/${{ secrets.STAGING_SERVER_ID }}/actions/rebuild" - - - run: scripts/initenv.sh - - - name: append venv/bin to PATH - run: echo venv/bin >>$GITHUB_PATH - - - name: upload TLS cert after rebuilding - run: | - echo " --- wait until staging2.testrun.org VPS is rebuilt --- " - rm ~/.ssh/known_hosts - while ! ssh -o ConnectTimeout=180 -o StrictHostKeyChecking=accept-new -v root@staging2.testrun.org id -u ; do sleep 1 ; done - ssh -o StrictHostKeyChecking=accept-new -v root@staging2.testrun.org id -u - # download acme & dkim state from ns.testrun.org - rsync -e "ssh -o StrictHostKeyChecking=accept-new" -avz root@ns.testrun.org:/tmp/acme acme-restore || true - rsync -avz root@ns.testrun.org:/tmp/dkimkeys dkimkeys-restore || true - # restore acme & dkim state to staging2.testrun.org - rsync -avz acme-restore/acme root@staging2.testrun.org:/var/lib/ || true - rsync -avz dkimkeys-restore/dkimkeys root@staging2.testrun.org:/etc/ || true - ssh -o StrictHostKeyChecking=accept-new -v root@staging2.testrun.org chown root:root -R /var/lib/acme || true - - - name: add hpk42 key to staging server - run: ssh root@staging2.testrun.org 'curl -s https://github.com/hpk42.keys >> .ssh/authorized_keys' - - - name: run deploy-chatmail offline tests - run: pytest --pyargs cmdeploy - - - run: | - cmdeploy init staging2.testrun.org - sed -i 's/#\s*mtail_address/mtail_address/' chatmail.ini - - - run: cmdeploy run --verbose --skip-dns-check - - - name: set DNS entries - run: | - cmdeploy dns --zonefile staging-generated.zone --verbose - cat staging-generated.zone >> .github/workflows/staging.testrun.org-default.zone - cat .github/workflows/staging.testrun.org-default.zone - scp .github/workflows/staging.testrun.org-default.zone root@ns.testrun.org:/etc/nsd/staging2.testrun.org.zone - ssh root@ns.testrun.org nsd-checkzone staging2.testrun.org /etc/nsd/staging2.testrun.org.zone - ssh root@ns.testrun.org systemctl reload nsd - - - name: cmdeploy test - run: CHATMAIL_DOMAIN2=ci-chatmail.testrun.org cmdeploy test --slow - - - name: cmdeploy dns - run: cmdeploy dns -v -