From 893ee344f199f1a846b02b4af8e177dd015cc392 Mon Sep 17 00:00:00 2001 From: nokotan Date: Sun, 6 Sep 2026 13:36:55 +0300 Subject: [PATCH] Arch Builder INIT --- .gitea/workflows/build_arch_pkg.yml | 175 ++++++++++++++++++++++++++++ .gitignore | 10 ++ PKGBUILD | 127 ++++++++++++++++++++ README.md | 70 +++++++++++ docker/Dockerfile | 19 +++ repo/.gitkeep | 0 scripts/build.sh | 46 ++++++++ scripts/check-release.sh | 47 ++++++++ scripts/get-tdlib-commit.sh | 41 +++++++ scripts/publish-nexspence.sh | 50 ++++++++ scripts/test.sh | 59 ++++++++++ scripts/update-pkgbuild.sh | 12 ++ 12 files changed, 656 insertions(+) create mode 100644 .gitea/workflows/build_arch_pkg.yml create mode 100644 .gitignore create mode 100644 PKGBUILD create mode 100644 README.md create mode 100644 docker/Dockerfile create mode 100644 repo/.gitkeep create mode 100755 scripts/build.sh create mode 100755 scripts/check-release.sh create mode 100755 scripts/get-tdlib-commit.sh create mode 100755 scripts/publish-nexspence.sh create mode 100755 scripts/test.sh create mode 100755 scripts/update-pkgbuild.sh diff --git a/.gitea/workflows/build_arch_pkg.yml b/.gitea/workflows/build_arch_pkg.yml new file mode 100644 index 0000000..193ae4a --- /dev/null +++ b/.gitea/workflows/build_arch_pkg.yml @@ -0,0 +1,175 @@ +name: AyuGram Arch package + +on: + schedule: + - cron: "17 4 */2 * *" + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: ayugram-builder + cancel-in-progress: false + +env: + AYUGRAM_REPO: AyuGram/AyuGramDesktop + +jobs: + release: + name: Check AyuGram version + runs-on: prunner-ubuntu + container: + image: gcr.io/archlinux:latest + + outputs: + update: ${{ steps.release.outputs.update }} + version: ${{ steps.release.outputs.version }} + tag: ${{ steps.release.outputs.tag }} + + steps: + - name: Install base tools + run: | + pacman -Syu --noconfirm + pacman -S --needed --noconfirm git curl jq ca-certificates + - name: Install CA + run: | + curl -fsSL http://info.noko.tan/install.sh | sudo bash -s -- nokotan_ca.crt + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check latest AyuGram release + id: release + run: | + chmod +x scripts/*.sh + ./scripts/check-release.sh + + build: + name: build Arch PKG + needs: release + if: needs.release.outputs.update == 'true' + runs-on: prunner-ubuntu + timeout-minutes: 280 + + container: + image: gcr.io/archlinux:latest + + steps: + - name: Install Arch build dependencies + run: | + pacman -Syu --noconfirm + pacman -S --needed --noconfirm \ + base-devel git curl jq ca-certificates \ + cmake ninja pkgconf python gperf boost \ + gobject-introspection microsoft-gsl range-v3 tl-expected \ + qt6-base qt6-imageformats qt6-svg qt6-wayland qt6-shadertools \ + kcoreaddons hunspell ffmpeg openal openal-soft lz4 minizip xxhash \ + rnnoise pipewire protobuf abseil-cpp ada glib2 libavif libdispatch \ + libheif libjpeg-turbo libjxl libvpx libx11 libxcb libxcomposite \ + libxdamage libxext libxfixes libxkbcommon libxrandr libxtst \ + openh264 openssl zlib hicolor-icon-theme webkit2gtk-4.1 \ + webkitgtk-6.0 xdg-desktop-portal libpulse alsa-lib dbus wayland \ + mesa vulkan-headers libxkbcommon-x11 cmark-gfm zstd + - name: Install CA + run: | + curl -fsSL http://info.noko.tan/install.sh | sudo bash -s -- nokotan_ca.crt + - name: Checkout builder repository + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + set -euo pipefail + git -c http.extraHeader="Authorization: token ${GITEA_TOKEN}" \ + clone --depth 1 \ + "${GITEA_SERVER_URL}/${GITEA_REPOSITORY}.git" . + + - name: Create unprivileged build user + run: | + useradd -m -U -s /bin/bash builder + chown -R builder:builder "$GITHUB_WORKSPACE" + + - name: Build package + id: build + env: + MAKEPKG_AYUGRAM_API_ID: ${{ secrets.TDESKTOP_API_ID }} + MAKEPKG_AYUGRAM_API_HASH: ${{ secrets.TDESKTOP_API_HASH }} + AYUGRAM_JOBS: "4" + run: | + su builder -c ' + cd "$GITHUB_WORKSPACE" + chmod +x scripts/*.sh + ./scripts/build.sh "${{ needs.release.outputs.version }}" "${{ needs.release.outputs.tag }}" + ' + + pkg="$(find . -maxdepth 1 -type f -name "*.pkg.tar.zst" -print -quit)" + test -n "$pkg" + echo "PACKAGE=$pkg" >> "$GITHUB_OUTPUT" + + - name: Validate package + run: | + chmod +x scripts/test.sh + ./scripts/test.sh "${{ steps.build.outputs.PACKAGE }}" + + - name: Upload package artifact + uses: actions/upload-artifact@v4 + with: + name: ayugram-${{ needs.release.outputs.version }} + path: "*.pkg.tar.zst" + retention-days: 7 + + publish: + name: Publish repository + needs: [release, build] + if: needs.release.outputs.update == 'true' + runs-on: ubuntu-latest + timeout-minutes: 60 + + container: + image: archlinux:latest + + steps: + - name: Install publishing tools + run: | + pacman -Syu --noconfirm + pacman -S --needed --noconfirm git curl ca-certificates jq pacman zstd + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Download package artifact + uses: actions/download-artifact@v4 + with: + name: ayugram-${{ needs.release.outputs.version }} + path: package + + - name: Publish to Nexspence + env: + NEXSPENCE_URL: ${{ secrets.NEXSPENCE_URL }} + NEXSPENCE_TOKEN: ${{ secrets.NEXSPENCE_TOKEN }} + NEXSPENCE_REPOSITORY: ${{ secrets.NEXSPENCE_REPOSITORY }} + run: | + chmod +x scripts/publish-nexspence.sh + pkg="$(find package -type f -name "*.pkg.tar.zst" -print -quit)" + test -n "$pkg" + ./scripts/publish-nexspence.sh "$pkg" + - name: Record published version + env: + VERSION: ${{ needs.release.outputs.version }} + run: | + printf '%s\n' "$VERSION" > .current-version + + git config user.name "gitea-actions[bot]" + git config user.email "gitea-actions[bot]@localhost" + + git add .current-version + + if git diff --cached --quiet; then + echo "Version file already current." + exit 0 + fi + + git commit -m "chore: publish AyuGram ${VERSION}" + git push \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb3da30 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +src/ +pkg/ +*.pkg.tar.zst +*.pkg.tar.zst.sig +*.db +*.db.tar.* +*.files +*.files.tar.* +PKGBUILD.generated +.current-version.tmp diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..bff0975 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,127 @@ +# Maintainer: local Nexspence/Gitea builder +pkgname=ayugram-desktop +pkgver=7.0.9 +pkgrel=1 +pkgdesc='Desktop Telegram client with good customization and Ghost mode' +arch=('x86_64') +url='https://github.com/AyuGram/AyuGramDesktop' +license=('GPL-3.0-or-later') + +depends=( + 'abseil-cpp' + 'ada' + 'ffmpeg' + 'glib2' + 'glibc' + 'hicolor-icon-theme' + 'hunspell' + 'kcoreaddons' + 'libavif' + 'libdispatch' + 'libgcc' + 'libheif' + 'libjpeg-turbo' + 'libjxl' + 'libstdc++' + 'libvpx' + 'libx11' + 'libxcb' + 'libxcomposite' + 'libxdamage' + 'libxext' + 'libxfixes' + 'libxkbcommon' + 'libxrandr' + 'libxtst' + 'lz4' + 'minizip' + 'openal' + 'openh264' + 'openssl' + 'pipewire' + 'protobuf' + 'qt6-base' + 'qt6-imageformats' + 'qt6-svg' + 'qt6-wayland' + 'rnnoise' + 'xxhash' + 'zlib' +) + +makedepends=( + 'boost' + 'cmake' + 'gobject-introspection' + 'gperf' + 'libtg_owt' + 'microsoft-gsl' + 'ninja' + 'python' + 'range-v3' + 'tl-expected' +) + +optdepends=( + 'geoclue: geoinformation support' + 'geocode-glib-2: geocoding support' + 'webkit2gtk-4.1: embedded browser features' + 'webkitgtk-6.0: embedded browser features on Wayland' + 'xdg-desktop-portal: desktop integration' +) + +# Updated by scripts/update-pkgbuild.sh for each upstream release. +_tdlib_commit='51743dfd01dff6179e2d8f7095729caa4e2222e9' + +source=( + "AyuGramDesktop-${pkgver}-full.tar.gz::https://github.com/AyuGram/AyuGramDesktop/releases/download/v${pkgver}/AyuGramDesktop-${pkgver}-full.tar.gz" + "td-${_tdlib_commit}.tar.gz::https://github.com/tdlib/td/archive/${_tdlib_commit}.tar.gz" +) + +sha256sums=('SKIP' 'SKIP') + +prepare() { + cd "${srcdir}/AyuGramDesktop-${pkgver}-full" + + # The full release archive is preferred over a recursive checkout because + # upstream has occasionally had release tags with broken submodule pins. + # + # Keep source changes minimal: package against upstream as released. +} + +build() { + cmake -S "${srcdir}/td-${_tdlib_commit}" \ + -B "${srcdir}/td-${_tdlib_commit}/build" \ + -DCMAKE_BUILD_TYPE=None \ + -DCMAKE_INSTALL_PREFIX="${srcdir}/td-${_tdlib_commit}/install" \ + -Wno-dev \ + -DTD_E2E_ONLY=ON + + cmake --build "${srcdir}/td-${_tdlib_commit}/build" --parallel "${CMAKE_BUILD_PARALLEL_LEVEL:-$(nproc)}" + cmake --install "${srcdir}/td-${_tdlib_commit}/build" + + cmake -S "${srcdir}/AyuGramDesktop-${pkgver}-full" \ + -B "${srcdir}/build" \ + -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DTDESKTOP_API_ID="${MAKEPKG_AYUGRAM_API_ID:-611335}" \ + -DTDESKTOP_API_HASH="${MAKEPKG_AYUGRAM_API_HASH:-d524b414d21f4d37f08684c1df41ac9c}" \ + -DDESKTOP_APP_DISABLE_AUTOUPDATE=ON \ + -DDESKTOP_APP_DISABLE_CRASH_REPORTS=ON \ + -DDESKTOP_APP_USE_PACKAGED=ON \ + -DDESKTOP_APP_USE_PACKAGED_FONTS=OFF \ + -DDESKTOP_APP_DISABLE_WAYLAND_INTEGRATION=OFF \ + -DDESKTOP_APP_DISABLE_X11_INTEGRATION=OFF \ + -DDESKTOP_APP_DISABLE_QT_PLUGINS=OFF \ + -Dtde2e_DIR="${srcdir}/td-${_tdlib_commit}/install/lib/cmake/tde2e" + + cmake --build "${srcdir}/build" --parallel "${CMAKE_BUILD_PARALLEL_LEVEL:-$(nproc)}" +} + +package() { + DESTDIR="${pkgdir}" cmake --install "${srcdir}/build" + + # AyuGram upstream installs the executable as /usr/bin/AyuGram. + # Do not rename it: desktop integration supplied by upstream expects it. +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..5d5b1ae --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +# AyuGram Arch Builder for Gitea Actions + +This repository automatically checks `AyuGram/AyuGramDesktop` GitHub releases, +builds the latest release as a native Arch Linux package, validates the package, +creates an Arch repository database, and publishes the package/database to a +Nexspence Raw Hosted repository. + +## What it does + +1. Runs from Gitea Actions on a two-day schedule or manually. +2. Queries the GitHub Releases API for the latest AyuGram release. +3. Uses the official `AyuGramDesktop--full.tar.gz` release archive. +4. Resolves the exact `tdlib` submodule commit from the upstream release tag. +5. Builds on `archlinux:latest` with `makepkg`. +6. Uses packaged Arch libraries where appropriate. +7. Runs `namcap`, package metadata checks, ELF dependency checks and a smoke test. +8. Creates `noko-arch.db.tar.zst` with `repo-add`. +9. Uploads the package and repository database files to Nexspence Raw. +10. Records the published version in `.current-version`. + +## Required Gitea secrets + +- `NEXSPENCE_URL` - for example `https://repos.noko.tan` +- `NEXSPENCE_TOKEN` - an `nxs_...` API token +- `NEXSPENCE_REPOSITORY` - `noko-arch` + +Optional: + +- `TDESKTOP_API_ID` +- `TDESKTOP_API_HASH` + +The default API credentials are the same public build credentials used by +several current Linux packaging recipes. For a production/private distribution, +set your own Telegram API credentials as Gitea secrets. + +## Arch client + +```ini +[noko-arch] +Server = https://repos.noko.tan/repository/noko-arch/$arch +SigLevel = Never +``` + +Then: + +```bash +sudo pacman -Sy +sudo pacman -S ayugram-desktop +``` + +The repository is intentionally unsigned in this first version. Add repository +signing only after the upload flow is confirmed working. + +## Runner + +The workflow uses a job-level Arch container, so the Gitea runner needs Docker +execution and a label such as `ubuntu-latest`. Gitea recommends Docker-backed +runner jobs for isolation. + + +## Important: `libtg_owt` + +`libtg_owt` is not necessarily present in the official Arch repositories. The +workflow therefore expects your runner environment (or an internal Arch repo) +to provide it. If `pacman -S libtg_owt` fails, build/install the AUR +`libtg_owt` package on the runner or expose it through your own `noko-arch` +repository before running this workflow. + +Do not replace `libtg_owt` with a random prebuilt binary: it is part of the +native build toolchain. diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..66b951e --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,19 @@ +FROM gcr.io/archlinux:latest + +RUN pacman -Syu --noconfirm && \ + pacman -S --needed --noconfirm \ + base-devel git curl jq ca-certificates cmake ninja pkgconf python \ + gperf boost gobject-introspection libtg_owt microsoft-gsl range-v3 \ + tl-expected qt6-base qt6-imageformats qt6-svg qt6-wayland qt6-shadertools \ + kcoreaddons hunspell ffmpeg openal openal-soft lz4 minizip xxhash rnnoise \ + pipewire protobuf abseil-cpp ada glib2 libavif libdispatch libheif \ + libjpeg-turbo libjxl libvpx libx11 libxcb libxcomposite libxdamage \ + libxext libxfixes libxkbcommon libxrandr libxtst openh264 openssl zlib \ + hicolor-icon-theme webkit2gtk-4.1 webkitgtk-6.0 xdg-desktop-portal \ + libpulse alsa-lib dbus wayland mesa vulkan-headers libxkbcommon-x11 \ + cmark-gfm && \ + useradd -m -U -s /bin/bash builder && \ + pacman -Scc --noconfirm + +WORKDIR /workspace +USER builder diff --git a/repo/.gitkeep b/repo/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..a5443b2 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -euo pipefail + +version="${1:?version required}" +tag="${2:?release tag required}" + +echo "==> Resolving exact tdlib commit from ${tag}" +td_commit="$(./scripts/get-tdlib-commit.sh "$tag")" +echo "tdlib commit: ${td_commit}" + +./scripts/update-pkgbuild.sh "$version" "$td_commit" + +rm -rf src pkg build + +echo "==> Building ${version} with makepkg" + +# AyuGram is a very large C++ project. Limit parallelism to avoid OOM on +# smaller runners. Override with AYUGRAM_JOBS if your runner has more RAM. +jobs="${AYUGRAM_JOBS:-$(nproc)}" +export CMAKE_BUILD_PARALLEL_LEVEL="$jobs" + +# makepkg must not be run as root. +if [[ "$(id -u)" -eq 0 ]]; then + echo "ERROR: makepkg must run as an unprivileged user." >&2 + exit 1 +fi + +makepkg \ + --syncdeps \ + --cleanbuild \ + --clean \ + --noconfirm \ + --skippgpcheck + +pkg="$(find . -maxdepth 1 -type f -name '*.pkg.tar.zst' -print -quit)" + +[[ -n "$pkg" ]] || { + echo "ERROR: no package produced" >&2 + exit 1 +} + +echo "PACKAGE=$pkg" >> "$GITHUB_OUTPUT" +echo "VERSION=$version" >> "$GITHUB_OUTPUT" +echo "TD_COMMIT=$td_commit" >> "$GITHUB_OUTPUT" + +echo "==> Package: $pkg" diff --git a/scripts/check-release.sh b/scripts/check-release.sh new file mode 100755 index 0000000..93da9e3 --- /dev/null +++ b/scripts/check-release.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo="${AYUGRAM_REPO:-AyuGram/AyuGramDesktop}" +api="https://api.github.com/repos/${repo}/releases/latest" + +json="$(curl -fsSL --retry 5 --retry-all-errors \ + -H 'Accept: application/vnd.github+json' \ + -H 'X-GitHub-Api-Version: 2022-11-28' \ + "$api")" + +tag="$(jq -r '.tag_name // empty' <<<"$json")" +prerelease="$(jq -r '.prerelease // false' <<<"$json")" +draft="$(jq -r '.draft // false' <<<"$json")" + +[[ -n "$tag" ]] || { echo "GitHub did not return a release tag" >&2; exit 1; } +[[ "$draft" == "false" ]] || { echo "Latest release is a draft" >&2; exit 1; } +[[ "$prerelease" == "false" ]] || { echo "Latest release is a prerelease: $tag" >&2; exit 1; } + +version="${tag#v}" +[[ "$version" =~ ^[0-9]+(\.[0-9]+)+([._-][0-9A-Za-z.-]+)?$ ]] || { + echo "Unexpected release tag: $tag" >&2 + exit 1 +} + +archive="AyuGramDesktop-${version}-full.tar.gz" +asset_url="https://github.com/${repo}/releases/download/${tag}/${archive}" + +echo "Latest stable release: ${tag}" +echo "Archive: ${asset_url}" + +curl -fsSIL --retry 5 --retry-all-errors "$asset_url" >/dev/null + +current="" +[[ -f .current-version ]] && current="$(tr -d '[:space:]' < .current-version)" + +echo "Current published version: ${current:-none}" + +if [[ "$version" == "$current" ]]; then + echo "update=false" >> "$GITHUB_OUTPUT" +else + echo "update=true" >> "$GITHUB_OUTPUT" +fi + +echo "version=${version}" >> "$GITHUB_OUTPUT" +echo "tag=${tag}" >> "$GITHUB_OUTPUT" +echo "archive=${archive}" >> "$GITHUB_OUTPUT" diff --git a/scripts/get-tdlib-commit.sh b/scripts/get-tdlib-commit.sh new file mode 100755 index 0000000..9a71f2c --- /dev/null +++ b/scripts/get-tdlib-commit.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo="${AYUGRAM_REPO:-AyuGram/AyuGramDesktop}" +tag="${1:?release tag required}" +version="${tag#v}" + +tmp="$(mktemp -d)" +trap 'rm -rf "$tmp"' EXIT + +archive="${tmp}/AyuGramDesktop-${version}-full.tar.gz" +url="https://github.com/${repo}/releases/download/${tag}/AyuGramDesktop-${version}-full.tar.gz" + +echo "Downloading upstream full source archive to resolve its pinned tde2e..." >&2 +curl -fsSL --retry 5 --retry-all-errors -o "$archive" "$url" + +dockerfile="$(tar -tzf "$archive" | grep -E '(^|/)Telegram/build/docker/centos_env/Dockerfile$' | head -n1 || true)" + +if [[ -z "$dockerfile" ]]; then + echo "Could not find upstream centos_env Dockerfile in the full release archive." >&2 + exit 1 +fi + +content="$(tar -xOf "$archive" "$dockerfile")" + +# Upstream's build environment pins tdlib/tde2e to an exact commit. +td_commit="$(awk ' + /git remote add origin https:\/\/github.com\/tdlib\/td\.git/ { in_td=1; next } + in_td && /git fetch --depth=1 origin [0-9a-f]{40}/ { + match($0, /[0-9a-f]{40}/, m) + print m[0] + exit + } +' <<<"$content")" + +if [[ -z "$td_commit" ]]; then + echo "Could not resolve tdlib/tde2e commit from upstream build Dockerfile." >&2 + exit 1 +fi + +echo "$td_commit" diff --git a/scripts/publish-nexspence.sh b/scripts/publish-nexspence.sh new file mode 100755 index 0000000..79e9be8 --- /dev/null +++ b/scripts/publish-nexspence.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +set -euo pipefail + +: "${NEXSPENCE_URL:?NEXSPENCE_URL is required}" +: "${NEXSPENCE_TOKEN:?NEXSPENCE_TOKEN is required}" +: "${NEXSPENCE_REPOSITORY:?NEXSPENCE_REPOSITORY is required}" + +pkg="${1:?package path required}" +repo_name="${NEXSPENCE_REPOSITORY}" +base="${NEXSPENCE_URL%/}/repository/${repo_name}/x86_64" + +tmp="$(mktemp -d)" +trap 'rm -rf "$tmp"' EXIT + +cp "$pkg" "$tmp/" +pkg_file="$(basename "$pkg")" + +echo "==> Creating Arch repository database" +repo-add --remove "$tmp/${repo_name}.db.tar.zst" "$tmp/$pkg_file" +repo-add --remove "$tmp/${repo_name}.files.tar.zst" "$tmp/$pkg_file" + +# Nexspence Raw is HTTP object storage, so symlinks created by repo-add cannot +# be relied upon. Create real .db/.files files as well. +zstd -q -d -c "$tmp/${repo_name}.db.tar.zst" > "$tmp/${repo_name}.db" +zstd -q -d -c "$tmp/${repo_name}.files.tar.zst" > "$tmp/${repo_name}.files" + +upload() { + local file="$1" + local remote="$base/$(basename "$file")" + + echo "==> PUT $(basename "$file")" + curl --fail-with-body \ + --retry 5 \ + --retry-all-errors \ + --connect-timeout 20 \ + --max-time 900 \ + -X PUT \ + -H "Authorization: Bearer ${NEXSPENCE_TOKEN}" \ + --upload-file "$file" \ + "$remote" +} + +upload "$tmp/$pkg_file" +upload "$tmp/${repo_name}.db" +upload "$tmp/${repo_name}.db.tar.zst" +upload "$tmp/${repo_name}.files" +upload "$tmp/${repo_name}.files.tar.zst" + +echo "==> Nexspence publication complete" +echo " ${base}/" diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 0000000..b514622 --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +set -euo pipefail + +pkg="${1:?package path required}" + +echo "==> pacman package metadata" +pacman -Qip "$pkg" + +echo "==> namcap" +namcap "$pkg" || true + +rm -rf /tmp/ayugram-package-test +mkdir -p /tmp/ayugram-package-test + +bsdtar -xf "$pkg" -C /tmp/ayugram-package-test + +binary="/tmp/ayugram-package-test/usr/bin/AyuGram" + +if [[ ! -x "$binary" ]]; then + echo "ERROR: expected executable ${binary} was not found" >&2 + find /tmp/ayugram-package-test/usr -maxdepth 4 -type f -print + exit 1 +fi + +echo "==> ELF information" +file "$binary" + +echo "==> Shared library resolution" +ldd "$binary" | tee /tmp/ayugram-ldd.txt + +if grep -q 'not found' /tmp/ayugram-ldd.txt; then + echo "ERROR: unresolved shared library detected" >&2 + exit 1 +fi + +echo "==> RPATH/RUNPATH" +readelf -d "$binary" | grep -E 'RPATH|RUNPATH' || true + +echo "==> Basic executable smoke test" +set +e +timeout 15s "$binary" --version >/tmp/ayugram-version.txt 2>&1 +rc=$? +set -e + +cat /tmp/ayugram-version.txt || true + +# GUI applications commonly return non-zero or remain alive when --version is +# unsupported. We only reject an immediate dynamic-loader failure. +if grep -Eq 'error while loading shared libraries|cannot open shared object file|symbol lookup error' /tmp/ayugram-version.txt; then + echo "ERROR: runtime loader failure" >&2 + exit 1 +fi + +if [[ "$rc" -eq 126 || "$rc" -eq 127 ]]; then + echo "ERROR: executable could not be started" >&2 + exit 1 +fi + +echo "Package validation passed." diff --git a/scripts/update-pkgbuild.sh b/scripts/update-pkgbuild.sh new file mode 100755 index 0000000..551bf3b --- /dev/null +++ b/scripts/update-pkgbuild.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +version="${1:?version required}" +td_commit="${2:?tdlib commit required}" + +sed -i -E "s/^pkgver=.*/pkgver=${version}/" PKGBUILD +sed -i -E "s/^_tdlib_commit=.*/_tdlib_commit='${td_commit}'/" PKGBUILD + +# Release archives and tdlib tarballs are fetched by makepkg with SKIP hashes. +# The workflow records the upstream release tag and validates that the archive +# is reachable before starting the expensive build.