From 78a314b7611224fcf07274bf27ea7080329daebe Mon Sep 17 00:00:00 2001 From: vii Date: Wed, 16 Sep 2026 02:47:46 -0500 Subject: [PATCH] ci(packages): reduce to a branded nightly AppImage The workflow built DEB, RPM and pacman packages on every push to main and every pull request, then published them as "Mocktail continuous" with assets named Mocktail-* and a continuous tag pushed as komaruworld. Nightcap ships the AppImage and the Flatpak, so the three native package jobs are removed along with the APT and RPM repository step, which could not work here regardless: it downloads .deb and .rpm from this repository's latest release, and the release workflow publishes neither. What remains runs nightly and on demand rather than per commit, skips the build when the continuous tag already points at HEAD, publishes Nightcap-nightly-x86_64.AppImage with a checksum beside it, and tags as github-actions[bot]. A manual run from another branch builds and smoke-tests without touching the release. --- .github/workflows/packages.yml | 275 +++++++-------------------------- tests/native_packaging_test.sh | 37 ++--- 2 files changed, 74 insertions(+), 238 deletions(-) diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml index b10c25d..ef4786c 100644 --- a/.github/workflows/packages.yml +++ b/.github/workflows/packages.yml @@ -1,39 +1,47 @@ -name: Native packages +name: Nightly AppImage on: - push: - branches: [main] - paths-ignore: - - '.github/workflows/ci.yml' - - '.gitignore' - - 'README.md' - - 'assets/screenshots/**' - - 'docs/**' - - 'packaging/aur/**' - - 'scripts/build_flatpak.sh' - - 'tests/**' - pull_request: - paths-ignore: - - '.github/workflows/ci.yml' - - '.gitignore' - - 'README.md' - - 'assets/screenshots/**' - - 'docs/**' - - 'packaging/aur/**' - - 'scripts/build_flatpak.sh' - - 'tests/**' + schedule: + # 05:00 UTC daily. A run whose commit already carries the continuous tag + # exits without rebuilding, so a quiet day costs one probe job. + - cron: '0 5 * * *' workflow_dispatch: permissions: contents: read concurrency: - group: packages-${{ github.ref }} - cancel-in-progress: true + group: nightly-appimage + cancel-in-progress: false jobs: + probe: + name: Check for new commits + runs-on: ubuntu-24.04 + timeout-minutes: 5 + outputs: + build: ${{ steps.decide.outputs.build }} + steps: + - name: Compare HEAD against the published continuous tag + id: decide + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + set -Eeuo pipefail + published="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/continuous" \ + --jq .object.sha 2>/dev/null || true)" + if [[ "$GITHUB_EVENT_NAME" == "schedule" && "$published" == "$GITHUB_SHA" ]]; then + echo 'build=false' >>"$GITHUB_OUTPUT" + echo "continuous already points at $GITHUB_SHA; nothing to build" + else + echo 'build=true' >>"$GITHUB_OUTPUT" + fi + appimage: name: AppImage (AnyLinux) + needs: probe + if: needs.probe.outputs.build == 'true' runs-on: ubuntu-24.04 timeout-minutes: 90 steps: @@ -138,155 +146,17 @@ jobs: - name: Upload AppImage uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: Mocktail-AppImage + name: Nightcap-AppImage path: dist/Mocktail-x86_64.AppImage if-no-files-found: error retention-days: 14 - deb: - name: DEB (Ubuntu 26.04) - runs-on: ubuntu-24.04 - timeout-minutes: 45 - steps: - - name: Check out source - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - fetch-depth: 0 - submodules: recursive - - - name: Build DEB - shell: bash - run: | - nightly_suffix=".nightly.$(git show -s --format=%cd --date=format:%Y%m%d%H%M%S "$GITHUB_SHA").g${GITHUB_SHA:0:8}" - docker run --rm \ - --volume "$GITHUB_WORKSPACE:/workspace" \ - --workdir /workspace \ - --env MOCKTAIL_PACKAGE_VERSION_SUFFIX="$nightly_suffix" \ - ubuntu:26.04 bash -Eeuo pipefail -c ' - export DEBIAN_FRONTEND=noninteractive - apt-get update - apt-get install --yes --no-install-recommends \ - build-essential cmake git ninja-build pkg-config lld fakeroot \ - dpkg-dev file libsdl3-dev libsdl3-ttf-dev \ - libcurl4-openssl-dev libssl-dev nlohmann-json3-dev \ - libyaml-dev libelf-dev libminizip-dev libcapstone-dev \ - libgtk-4-dev libadwaita-1-dev libwebkitgtk-6.0-dev \ - libutf8proc-dev libfontconfig1-dev libegl-dev \ - libvulkan-dev libplacebo-dev zlib1g-dev - cmake -S . -B build-deb -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr \ - -DMOCKTAIL_PACKAGE_NAME=mocktail-nightly \ - -DMOCKTAIL_PACKAGE_VERSION_SUFFIX="$MOCKTAIL_PACKAGE_VERSION_SUFFIX" \ - -DBUILD_TESTING=OFF - cmake --build build-deb --parallel 4 - cpack --config build-deb/CPackConfig.cmake \ - -G DEB -B dist/deb - dpkg-deb --info dist/deb/*.deb >/dev/null - ' - - - name: Upload DEB - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: Mocktail-DEB - path: dist/deb/*.deb - if-no-files-found: error - retention-days: 14 - - rpm: - name: RPM (Fedora 44) - runs-on: ubuntu-24.04 - timeout-minutes: 45 - steps: - - name: Check out source - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - fetch-depth: 0 - submodules: recursive - - - name: Build RPM - shell: bash - run: | - nightly_suffix=".nightly.$(git show -s --format=%cd --date=format:%Y%m%d%H%M%S "$GITHUB_SHA").g${GITHUB_SHA:0:8}" - docker run --rm \ - --volume "$GITHUB_WORKSPACE:/workspace" \ - --workdir /workspace \ - --env MOCKTAIL_PACKAGE_VERSION_SUFFIX="$nightly_suffix" \ - fedora:44 bash -Eeuo pipefail -c ' - dnf install --assumeyes \ - gcc-c++ cmake git ninja-build pkgconf-pkg-config lld rpm-build \ - SDL3-devel SDL3_ttf-devel libcurl-devel openssl-devel \ - nlohmann-json-devel libyaml-devel elfutils-libelf-devel \ - minizip-ng-compat-devel capstone-devel gtk4-devel libadwaita-devel \ - webkitgtk6.0-devel utf8proc-devel fontconfig-devel \ - libglvnd-devel vulkan-headers vulkan-loader-devel \ - libplacebo-devel zlib-ng-compat-devel - cmake -S . -B build-rpm -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=/usr \ - -DCMAKE_INSTALL_LIBDIR=lib \ - -DMOCKTAIL_PACKAGE_NAME=mocktail-nightly \ - -DMOCKTAIL_PACKAGE_VERSION_SUFFIX="$MOCKTAIL_PACKAGE_VERSION_SUFFIX" \ - -DBUILD_TESTING=OFF - cmake --build build-rpm --parallel 4 - cpack --config build-rpm/CPackConfig.cmake \ - -G RPM -B dist/rpm - rpm --query --package --info dist/rpm/*.rpm >/dev/null - ' - - - name: Upload RPM - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: Mocktail-RPM - path: dist/rpm/*.rpm - if-no-files-found: error - retention-days: 14 - - arch: - name: Pacman package (Arch Linux) - runs-on: ubuntu-24.04 - timeout-minutes: 45 - steps: - - name: Check out source - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - fetch-depth: 0 - submodules: recursive - - - name: Build pacman package - shell: bash - run: | - docker run --rm \ - --volume "$GITHUB_WORKSPACE:/workspace" \ - --workdir /workspace \ - archlinux:base-devel bash -Eeuo pipefail -c ' - pacman -Syu --needed --noconfirm \ - cmake git ninja pkgconf lld sdl3 sdl3_ttf curl openssl \ - nlohmann-json libyaml libelf minizip capstone gtk4 \ - libadwaita webkitgtk-6.0 libutf8proc fontconfig \ - libplacebo vulkan-headers vulkan-icd-loader libglvnd zlib - useradd --create-home builder - chown -R builder:builder /workspace - runuser -u builder -- env MOCKTAIL_SOURCE_DIR=/workspace \ - makepkg --dir /workspace/packaging/arch \ - --noconfirm --cleanbuild --force - install -d dist/arch - cp packaging/arch/*.pkg.tar.zst dist/arch/ - pacman -Qp dist/arch/*.pkg.tar.zst >/dev/null - ' - - - name: Upload pacman package - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: Mocktail-Arch - path: dist/arch/*.pkg.tar.zst - if-no-files-found: error - retention-days: 14 - publish: - name: Publish continuous packages - if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' - needs: [appimage, deb, rpm, arch] + name: Publish continuous release + needs: [probe, appimage] + # A manual run from another branch still builds and smoke-tests, but the + # continuous tag and release only ever follow main. + if: needs.probe.outputs.build == 'true' && github.ref == 'refs/heads/main' runs-on: ubuntu-24.04 timeout-minutes: 30 permissions: @@ -297,84 +167,49 @@ jobs: with: fetch-depth: 0 - - name: Download packages + - name: Download AppImage uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - pattern: Mocktail-* + name: Nightcap-AppImage path: release - merge-multiple: true - - name: Prepare continuous packages + - name: Name and checksum the nightly build shell: bash run: | set -Eeuo pipefail - mv -- release/*.AppImage release/mocktail-nightly.AppImage - mv -- release/*.deb release/mocktail-nightly.deb - mv -- release/*.rpm release/mocktail-nightly.rpm - mv -- release/*.pkg.tar.zst release/mocktail-nightly.pkg.tar.zst + # The Makefile builds under upstream's artifact name; the published + # asset carries this fork's. + mv -- release/Mocktail-x86_64.AppImage release/Nightcap-nightly-x86_64.AppImage + (cd release && sha256sum Nightcap-nightly-x86_64.AppImage \ + > Nightcap-nightly-x86_64.AppImage.sha256) find release -maxdepth 1 -type f -print - - name: Build package repositories - shell: bash - env: - GH_TOKEN: ${{ github.token }} - FLATPAK_GPG_PRIVATE_KEY: ${{ secrets.FLATPAK_GPG_PRIVATE_KEY }} - FLATPAK_GPG_KEY_ID: ${{ secrets.FLATPAK_GPG_KEY_ID }} - run: | - set -Eeuo pipefail - [[ -n "$FLATPAK_GPG_PRIVATE_KEY" && -n "$FLATPAK_GPG_KEY_ID" ]] - sudo apt-get update - sudo apt-get install --yes --no-install-recommends \ - apt-utils createrepo-c gnupg rpm - install -d stable/deb stable/rpm - stable_tag="$(gh api "repos/$GITHUB_REPOSITORY/releases/latest" --jq .tag_name)" - gh release download "$stable_tag" --pattern '*.deb' --dir stable/deb - gh release download "$stable_tag" --pattern '*.rpm' --dir stable/rpm - mapfile -t stable_debs < <(find stable/deb -maxdepth 1 -type f -name '*.deb' -print) - mapfile -t stable_rpms < <(find stable/rpm -maxdepth 1 -type f -name '*.rpm' -print) - [[ "${#stable_debs[@]}" -eq 1 && "${#stable_rpms[@]}" -eq 1 ]] - install -d -m 0700 "$RUNNER_TEMP/mocktail-native-gnupg" - printf '%s' "$FLATPAK_GPG_PRIVATE_KEY" | \ - gpg --batch --homedir "$RUNNER_TEMP/mocktail-native-gnupg" --import - gpg --batch --homedir "$RUNNER_TEMP/mocktail-native-gnupg" \ - --export "$FLATPAK_GPG_KEY_ID" >mocktail-packages.gpg - ./scripts/assemble_native_repositories.sh \ - "${stable_debs[0]}" release/mocktail-nightly.deb \ - "${stable_rpms[0]}" release/mocktail-nightly.rpm \ - mocktail-packages.gpg "$FLATPAK_GPG_KEY_ID" \ - "$RUNNER_TEMP/mocktail-native-gnupg" native-repositories - - name: Update continuous release shell: bash env: GH_TOKEN: ${{ github.token }} run: | set -Eeuo pipefail - git config user.name komaruworld - git config user.email rtysus228@gmail.com + git config user.name 'github-actions[bot]' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' git tag --force continuous "$GITHUB_SHA" git push origin refs/tags/continuous --force + notes="Automated build of main at ${GITHUB_SHA:0:8}. Untested and unreleased; use a tagged release for normal play." if ! gh release view continuous >/dev/null 2>&1; then gh release create continuous \ --prerelease \ - --title "Mocktail continuous" \ - --notes "Automated development packages from main." + --title "Nightcap continuous" \ + --notes "$notes" fi + gh release edit continuous --title "Nightcap continuous" --notes "$notes" gh release upload continuous release/* --clobber + # Drop assets left by earlier runs under other names. while IFS= read -r asset; do case "$asset" in - mocktail-nightly.AppImage|mocktail-nightly.deb|mocktail-nightly.rpm|mocktail-nightly.pkg.tar.zst) + Nightcap-nightly-x86_64.AppImage|Nightcap-nightly-x86_64.AppImage.sha256) ;; - Mocktail-*.AppImage|mocktail_*.deb|mocktail-*.deb|mocktail-*.rpm|mocktail-*.pkg.tar.zst) + *) gh release delete-asset continuous "$asset" --yes ;; esac done < <(gh release view continuous --json assets --jq '.assets[].name') - - - name: Upload package repositories - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: Mocktail-native-repositories - path: native-repositories - if-no-files-found: error - retention-days: 14 diff --git a/tests/native_packaging_test.sh b/tests/native_packaging_test.sh index acd8e71..bc9577c 100755 --- a/tests/native_packaging_test.sh +++ b/tests/native_packaging_test.sh @@ -86,34 +86,35 @@ grep -Fq 'mz_stream_tell(unzGetStream(archive))' "${ANDROID_STUB}" || Fail 'Android assets do not support the minizip-ng offset API' for expected in \ - 'ubuntu:26.04' \ - 'fedora:44' \ - 'archlinux:base-devel' \ - 'minizip-ng-compat-devel' \ - '-G DEB' \ - '-G RPM' \ - 'makepkg --dir' \ + 'cron:' \ 'APPIMAGE_FORMAT=anylinux' \ 'quick-sharun' \ './scripts/install_anylinux_dependencies.sh' \ + '--env GH_TOKEN' \ 'MOCKTAIL_ANYLINUX_SYSTEM_INSTALL=1' \ '--appimage-extract-and-run mocktail_updater status' \ 'Mocktail-x86_64.AppImage' \ + 'Nightcap-nightly-x86_64.AppImage' \ + 'github-actions[bot]' \ 'gh release upload continuous'; do grep -Fq -- "${expected}" "${WORKFLOW}" || - Fail "native package workflow is missing: ${expected}" + Fail "nightly AppImage workflow is missing: ${expected}" done -grep -Fq 'paths-ignore:' "${WORKFLOW}" || - Fail 'native package workflow has no path filters' -grep -Fq "'assets/screenshots/**'" "${WORKFLOW}" || - Fail 'native packages rebuild for screenshot-only changes' -if grep -Fq "'packaging/flatpak/**'" "${WORKFLOW}"; then - Fail 'native packages ignore Flatpak changes required by Pages publication' -fi -if grep -Fq "'site/**'" "${WORKFLOW}"; then - Fail 'native packages ignore website changes required by Pages publication' -fi +# The nightly runs on a schedule and on demand. Per-commit triggers would +# rebuild a full AppImage for every push and pull request. The DEB, RPM and +# pacman packages are built by the Makefile but are not published from here; +# upstream ships those for unmodified Mocktail. +for unexpected in \ + 'push:' \ + 'pull_request:' \ + '-G DEB' \ + '-G RPM' \ + 'makepkg --dir'; do + if grep -Fq -- "${unexpected}" "${WORKFLOW}"; then + Fail "nightly AppImage workflow should not contain: ${unexpected}" + fi +done grep -Fq 'Ubuntu 26.04+' "${README}" || Fail 'README has no Ubuntu source dependency guide'