diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9b2b20df..f2816994 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -100,6 +100,10 @@ jobs: needs: [dist, test-dist] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') + strategy: + fail-fast: true + matrix: + series: [focal, jammy, noble] steps: - name: Install dependencies @@ -118,6 +122,8 @@ jobs: name: packaging-assets - name: Assemble Debian source tree + env: + SERIES: ${{ matrix.series }} run: | tar xzf try-*.tgz srcdir=$(echo try-*/) @@ -130,10 +136,30 @@ jobs: cp -R packaging/debian "$srcdir/debian" rm -f try-*.tgz packaging.tgz - revision=$(sed -n "1s/^try ([^)-]*-\([0-9]*\)).*/\1/p" "$srcdir/debian/changelog") - sed -i "1s/^try ([^)]*)/try (${version}-${revision})/" "$srcdir/debian/changelog" - - sed -i "1s/UNRELEASED/noble/" "$srcdir/debian/changelog" + changelog="$srcdir/debian/changelog" + committed=$(sed -n '1s/^try (\([^)]*\)).*/\1/p' "$changelog") + if [ "${committed%-*}" = "$version" ] + then + # same upstream version: packaging-only revision, keep the committed one + revision=${committed##*-} + else + # new upstream release: start again at revision 1 + revision=1 + maintainer=$(sed -n 's/^Maintainer: //p' "$srcdir/debian/control") + { + echo "try (${version}-1) UNRELEASED; urgency=medium" + echo + echo " * New upstream release ${version}." + echo + echo " -- ${maintainer} $(date -R)" + echo + cat "$changelog" + } > "$changelog.new" + mv "$changelog.new" "$changelog" + fi + sed -i "1s/^try ([^)]*)/try (${version}-${revision}~${SERIES}1)/" "$changelog" + + sed -i "1s/UNRELEASED/${SERIES}/" "$changelog" echo "SRCDIR=$srcdir" >> "$GITHUB_ENV" - name: Build the Debian source package @@ -148,7 +174,7 @@ jobs: - name: Upload Debian source package uses: actions/upload-artifact@v7 with: - name: try-ppa-source + name: try-ppa-source-${{ matrix.series }} path: | try_*.dsc try_*.orig.tar.gz @@ -446,12 +472,13 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y devscripts dput gnupg + sudo apt-get install -y devscripts dput gnupg openssh-client python3-paramiko - - name: Download the Debian source package + - name: Download the Debian source packages uses: actions/download-artifact@v8 with: - name: try-ppa-source + pattern: try-ppa-source-* + merge-multiple: true - name: Import GPG signing key env: @@ -460,14 +487,57 @@ jobs: echo "$GPG_PRIVATE_KEY" | gpg --batch --import echo "KEYID=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec/ {print $5; exit}')" >> "$GITHUB_ENV" + - name: Configure SFTP upload to Launchpad + env: + SSH_KEY: ${{ secrets.PPA_SSH_KEY }} + PPA_TARGET: ${{ vars.PPA_TARGET }} + PPA_LOGIN: ${{ vars.PPA_LOGIN }} + run: | + mkdir -p ~/.ssh + chmod 700 ~/.ssh + echo "$SSH_KEY" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + ssh-keyscan ppa.launchpad.net >> ~/.ssh/known_hosts + ssh-keygen -lf ~/.ssh/known_hosts + + ppa=${PPA_TARGET#ppa:} + owner=${ppa%%/*} + name=${ppa#*/} + cat > ~/.dput.cf < /tmp/gpg-passphrase - debsign -k"$KEYID" -p"gpg --batch --yes --pinentry-mode loopback --passphrase-file /tmp/gpg-passphrase" try_*_source.changes + failed="" + for changes in try_*_source.changes + do + debsign -k"$KEYID" -p"gpg --batch --yes --pinentry-mode loopback --passphrase-file /tmp/gpg-passphrase" "$changes" + uploaded="" + for attempt in 1 2 3 4 5 + do + if dput ppa-sftp "$changes" + then + uploaded=yes + break + fi + echo "upload of $changes failed (attempt $attempt); retrying in 60s" + sleep 60 + done + [ -n "$uploaded" ] || failed="$failed $changes" + # give Launchpad's upload server time to finish the previous upload + sleep 30 + done rm -f /tmp/gpg-passphrase - dput "${{ vars.PPA_TARGET }}" try_*_source.changes + [ -z "$failed" ] || { echo "failed uploads:$failed"; exit 1; } prerelease: needs: diff --git a/packaging/debian/README b/packaging/debian/README index 8bfa8fb5..2799b197 100644 --- a/packaging/debian/README +++ b/packaging/debian/README @@ -16,6 +16,31 @@ builds a source package. CI (`ppa-source-check` in result with `lintian`; `publish-ppa` signs and uploads it to the configured PPA via `dput`. +# Versioning + +You don't edit `debian/changelog` for a normal release. CI takes the +upstream version from the release tarball and compares it with the top +entry of the committed changelog: + +* Different (a new upstream release): CI starts at revision 1 and adds a + "New upstream release" entry itself. +* Same (a packaging-only fix, e.g. a `debian/control` change): CI keeps the + committed revision, so bump it by hand (`0.2.1-1` to `0.2.1-2`) in the PR + that makes the fix. + +# Supported Ubuntu series + +CI builds and uploads one source package per Ubuntu series, listed in the +`matrix.series` of `ppa-source-check` in `.github/workflows/test.yaml` +(currently `focal`, `jammy`, `noble`). Each upload gets its own version +(`-~1`, e.g. `0.2.1-1~focal1`), because a PPA +won't accept the same version twice; the `.orig.tar.gz` is shared and +byte-identical across them. + +`debian/control` uses `debhelper-compat (= 12)` rather than 13 because +focal (20.04) ships debhelper 12.10, which can't satisfy 13. Raise it only +if focal is dropped. + # Testing that a published PPA package actually installs and works Once a build succeeds on Launchpad, verify it installs cleanly in an diff --git a/packaging/debian/changelog b/packaging/debian/changelog index b0895811..c203d5df 100644 --- a/packaging/debian/changelog +++ b/packaging/debian/changelog @@ -1,7 +1,7 @@ -try (0.2.1-1) UNRELEASED; urgency=medium +try (0.2.1-2) UNRELEASED; urgency=medium * Add PPA release workflow: Debian source packaging (debian/) built, linted, signed, and published to a Launchpad PPA by CI on version - tag pushes. + tag pushes, for Ubuntu 20.04 (focal), 22.04 (jammy) and 24.04 (noble). -- try maintainers Tue, 15 Sep 2026 14:32:00 -0400 diff --git a/packaging/debian/control b/packaging/debian/control index 020ba55e..d212530a 100644 --- a/packaging/debian/control +++ b/packaging/debian/control @@ -2,7 +2,7 @@ Source: try Section: utils Priority: optional Maintainer: try maintainers -Build-Depends: debhelper-compat (= 13), autoconf, pandoc, attr +Build-Depends: debhelper-compat (= 12), autoconf, pandoc, attr Standards-Version: 4.6.2 Homepage: https://github.com/binpash/try Rules-Requires-Root: no