From be695d78a9c41b17350c903a4d6f6f9de82af389 Mon Sep 17 00:00:00 2001 From: Christoph Brandau Date: Sat, 15 Aug 2026 17:00:42 +0200 Subject: [PATCH] feat(publishing): add support for prebuilt AppImage package This update enhances the publishing workflow by introducing a new prebuilt AppImage package for Gitty, allowing users to install the application without needing to compile from source. The workflow now includes steps to generate and publish the binary AUR package alongside the standard source package. - Introduced PKGBUILD-bin for the prebuilt AppImage - Updated workflow to handle both source and binary package publishing - Enhanced README to guide users on installing the new package --- .gitea/workflows/app_builder.yaml | 140 ++++++++++++++++++++---------- PKGBUILD-bin | 45 ++++++++++ README.md | 11 ++- 3 files changed, 147 insertions(+), 49 deletions(-) create mode 100644 PKGBUILD-bin diff --git a/.gitea/workflows/app_builder.yaml b/.gitea/workflows/app_builder.yaml index e00424c..a82c2a6 100644 --- a/.gitea/workflows/app_builder.yaml +++ b/.gitea/workflows/app_builder.yaml @@ -121,11 +121,13 @@ jobs: uv run main.py publish-arch: - name: Build and publish gitty-desktop to AUR + name: Build and publish AUR packages + needs: publish-ubuntu runs-on: archlinux environment: production env: AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} + ARTIFACT_BASE_URL: ${{ vars.ARTIFACT_BASE_URL }} defaults: run: @@ -236,6 +238,43 @@ jobs: echo "AUR_SOURCE_DIR=$AUR_SOURCE_DIR" >> "$GITHUB_ENV" + - name: Generate and build binary AUR package + run: | + set -euo pipefail + + LATEST_JSON="$(curl --fail --location --silent --show-error \ + "$ARTIFACT_BASE_URL/gitty/latest.json")" + export LATEST_JSON + APPIMAGE_URL="$(node -e "const p=JSON.parse(process.env.LATEST_JSON); const a=p.platforms?.['linux-x86_64']?.url; if (!a) process.exit(1); process.stdout.write(a)")" + APPIMAGE_NAME="${APPIMAGE_URL##*/}" + + AUR_BIN_DIR="$(mktemp -d)" + cp PKGBUILD-bin "$AUR_BIN_DIR/PKGBUILD" + APPIMAGE_PATH="$AUR_BIN_DIR/$APPIMAGE_NAME" + curl --fail --location --silent --show-error \ + --output "$APPIMAGE_PATH" "$APPIMAGE_URL" + APPIMAGE_CHECKSUM="$(sha256sum "$APPIMAGE_PATH" | cut -d ' ' -f 1)" + ICON_PATH="$AUR_BIN_DIR/gitty-desktop.png" + curl --fail --location --silent --show-error \ + --output "$ICON_PATH" \ + "https://git.cbsk-tech.de/Christoph/GitLite/raw/tag/$RELEASE_TAG/src-tauri/icons/icon.png" + ICON_CHECKSUM="$(sha256sum "$ICON_PATH" | cut -d ' ' -f 1)" + + sed -i \ + -e "s/^pkgver=.*/pkgver=$PACKAGE_VERSION/" \ + -e "s/^pkgrel=.*/pkgrel=1/" \ + -e "s|^_appimage=.*|_appimage=\"$APPIMAGE_NAME\"|" \ + -e "s|^_artifact_url=.*|_artifact_url=\"$APPIMAGE_URL\"|" \ + -e "s/^_tag=.*/_tag=$RELEASE_TAG/" \ + -e "/^sha256sums=/,/^[[:space:]]*'SKIP')$/c\\sha256sums=('$APPIMAGE_CHECKSUM'\\n '$ICON_CHECKSUM')" \ + "$AUR_BIN_DIR/PKGBUILD" + + chown -R builder:builder "$AUR_BIN_DIR" + runuser -u builder -- \ + bash -lc "cd '$AUR_BIN_DIR' && makepkg --cleanbuild --noconfirm && makepkg --printsrcinfo > .SRCINFO" + + echo "AUR_BIN_DIR=$AUR_BIN_DIR" >> "$GITHUB_ENV" + - name: Publish PKGBUILD to AUR env: AUR_GIT_NAME: ${{ vars.USERNAME_GIT }} @@ -273,55 +312,62 @@ jobs: install -m 0600 "$AUR_KNOWN_HOSTS_TEMP" "$HOME/.ssh/known_hosts" export GIT_SSH_COMMAND="ssh -i $HOME/.ssh/aur -o IdentitiesOnly=yes -o BatchMode=yes -o ConnectTimeout=30 -o ServerAliveInterval=15 -o ServerAliveCountMax=2" - AUR_CHECKOUT_ROOT="$(mktemp -d)" - AUR_CHECKOUT="" - for AUR_ATTEMPT in 1 2 3 4 5; do - AUR_CLONE_CANDIDATE="$AUR_CHECKOUT_ROOT/attempt-$AUR_ATTEMPT" - echo "AUR clone attempt $AUR_ATTEMPT of 5" - if timeout 3m git -c init.defaultBranch=master clone \ - ssh://aur@aur.archlinux.org/gitty-desktop.git "$AUR_CLONE_CANDIDATE"; then - AUR_CHECKOUT="$AUR_CLONE_CANDIDATE" - break - fi - if [ "$AUR_ATTEMPT" -lt 5 ]; then - echo "AUR is unavailable; retrying after backoff" - sleep "${AUR_RETRY_DELAYS[$((AUR_ATTEMPT - 1))]}" - fi - done - if [ -z "$AUR_CHECKOUT" ]; then - echo "Could not clone the AUR repository after 5 attempts" >&2 - exit 1 - fi + publish_aur_package() { + local package_name="$1" + local package_source_dir="$2" + local checkout_root checkout clone_candidate pushed - cp "$AUR_SOURCE_DIR/PKGBUILD" "$AUR_SOURCE_DIR/.SRCINFO" "$AUR_CHECKOUT/" - - cd "$AUR_CHECKOUT" - git config user.name "${AUR_GIT_NAME:-Gitty Release Bot}" - git config user.email "${AUR_GIT_EMAIL:-aur@localhost}" - git add PKGBUILD .SRCINFO - - if git diff --cached --quiet; then - echo "AUR metadata already matches release $PACKAGE_VERSION" - exit 0 - fi - - git commit -m "Update to $PACKAGE_VERSION" - AUR_PUSHED=0 - for AUR_ATTEMPT in 1 2 3 4 5; do - echo "AUR push attempt $AUR_ATTEMPT of 5" - if timeout 3m git push origin HEAD:master; then - AUR_PUSHED=1 - break + checkout_root="$(mktemp -d)" + checkout="" + for AUR_ATTEMPT in 1 2 3 4 5; do + clone_candidate="$checkout_root/attempt-$AUR_ATTEMPT" + echo "$package_name clone attempt $AUR_ATTEMPT of 5" + if timeout 3m git -c init.defaultBranch=master clone \ + "ssh://aur@aur.archlinux.org/$package_name.git" "$clone_candidate"; then + checkout="$clone_candidate" + break + fi + if [ "$AUR_ATTEMPT" -lt 5 ]; then + echo "AUR is unavailable; retrying after backoff" + sleep "${AUR_RETRY_DELAYS[$((AUR_ATTEMPT - 1))]}" + fi + done + if [ -z "$checkout" ]; then + echo "Could not clone $package_name after 5 attempts" >&2 + return 1 fi - if [ "$AUR_ATTEMPT" -lt 5 ]; then - echo "AUR push failed; retrying after backoff" - sleep "${AUR_RETRY_DELAYS[$((AUR_ATTEMPT - 1))]}" + + cp "$package_source_dir/PKGBUILD" "$package_source_dir/.SRCINFO" "$checkout/" + git -C "$checkout" config user.name "${AUR_GIT_NAME:-Gitty Release Bot}" + git -C "$checkout" config user.email "${AUR_GIT_EMAIL:-aur@localhost}" + git -C "$checkout" add PKGBUILD .SRCINFO + + if git -C "$checkout" diff --cached --quiet; then + echo "$package_name already matches release $PACKAGE_VERSION" + return 0 fi - done - if [ "$AUR_PUSHED" -ne 1 ]; then - echo "Could not publish to AUR after 5 attempts" >&2 - exit 1 - fi + + git -C "$checkout" commit -m "Update to $PACKAGE_VERSION" + pushed=0 + for AUR_ATTEMPT in 1 2 3 4 5; do + echo "$package_name push attempt $AUR_ATTEMPT of 5" + if timeout 3m git -C "$checkout" push origin HEAD:master; then + pushed=1 + break + fi + if [ "$AUR_ATTEMPT" -lt 5 ]; then + echo "AUR push failed; retrying after backoff" + sleep "${AUR_RETRY_DELAYS[$((AUR_ATTEMPT - 1))]}" + fi + done + if [ "$pushed" -ne 1 ]; then + echo "Could not publish $package_name after 5 attempts" >&2 + return 1 + fi + } + + publish_aur_package gitty-desktop "$AUR_SOURCE_DIR" + publish_aur_package gitty-desktop-bin "$AUR_BIN_DIR" publish-ubuntu: name: Build and publish Ubuntu AppImage diff --git a/PKGBUILD-bin b/PKGBUILD-bin new file mode 100644 index 0000000..40704ee --- /dev/null +++ b/PKGBUILD-bin @@ -0,0 +1,45 @@ +# Maintainer: Christoph Brandau + +pkgname=gitty-desktop-bin +pkgver=2026.8.3 +pkgrel=1 +pkgdesc="A lightweight, modern Git client built with Tauri (prebuilt AppImage)" +arch=('x86_64') +url="https://git.cbsk-tech.de/Christoph/GitLite" +license=('MIT') +depends=('fuse2' 'git' 'webkit2gtk-4.1' 'gtk3' 'hicolor-icon-theme' 'libappindicator-gtk3' 'librsvg' 'xdotool') +provides=('gitty-desktop') +conflicts=('gitty-desktop') +options=('!strip') + +_appimage="Gitty_${pkgver}_amd64.AppImage" +_artifact_url="https://cdn.cbsk-tech.de/gitty/${pkgver}/${_appimage}" +_tag=2026.8.3 +source=("${_appimage}::${_artifact_url}" + "gitty-desktop.png::${url}/raw/tag/${_tag}/src-tauri/icons/icon.png") +sha256sums=('SKIP' + 'SKIP') + +package() { + install -Dm755 "$srcdir/$_appimage" \ + "$pkgdir/opt/$pkgname/gitty-desktop.AppImage" + install -d "$pkgdir/usr/bin" + ln -s "/opt/$pkgname/gitty-desktop.AppImage" \ + "$pkgdir/usr/bin/gitty-desktop" + + install -Dm644 "$srcdir/gitty-desktop.png" \ + "$pkgdir/usr/share/icons/hicolor/512x512/apps/gitty-desktop.png" + + install -d "$pkgdir/usr/share/applications" + cat > "$pkgdir/usr/share/applications/gitty-desktop.desktop" <<-EOF + [Desktop Entry] + Type=Application + Name=Gitty + Comment=$pkgdesc + Exec=gitty-desktop + Icon=gitty-desktop + Terminal=false + Categories=Development;RevisionControl; + StartupWMClass=gitty + EOF +} diff --git a/README.md b/README.md index ebb6954..d4217af 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,12 @@ Install Gitty from the AUR with an AUR helper: yay -S gitty-desktop ``` +To install the prebuilt AppImage instead of compiling from source: + +```bash +yay -S gitty-desktop-bin +``` + Or build the AUR package manually: ```bash @@ -68,8 +74,9 @@ cd gitty-desktop makepkg -si ``` -The AUR recipe downloads the public Gitea release archive and builds Gitty from -source. The release pipeline updates its version, checksum, and `.SRCINFO`. +The source recipe downloads the public Gitea release archive and builds Gitty. +The `-bin` recipe installs the prebuilt AppImage. The release pipeline updates +both packages' versions, checksums, and `.SRCINFO` files. ---