name: AUR Release permissions: contents: read actions: read on: workflow_dispatch: inputs: tag: description: 'Tag version to release to AUR (e.g., v0.5.1)' required: true type: string workflow_call: inputs: tag: description: 'Tag version to release to AUR' required: true type: string jobs: aur-release: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ inputs.tag }} - name: Get release information id: release_info uses: actions/github-script@v7 with: script: | const fs = require('fs'); const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')); const tag = "${{ inputs.tag }}"; const version = tag.replace(/^v/, ''); const authorName = packageJson.author.name; const authorEmail = packageJson.author.email; const appImageUrl = `https://github.com/lone-cloud/friendly-kobold/releases/download/${tag}/Friendly.Kobold-${version}.AppImage`; core.setOutput('version', version); core.setOutput('tag', tag); core.setOutput('author_name', authorName); core.setOutput('author_email', authorEmail); core.setOutput('appimage_url', appImageUrl); console.log(`Release info:`); console.log(`Version: ${version}`); console.log(`Tag: ${tag}`); console.log(`Author: ${authorName} <${authorEmail}>`); console.log(`AppImage URL: ${appImageUrl}`); - name: Verify AppImage availability run: | echo "Verifying AppImage is accessible..." APPIMAGE_URL="${{ steps.release_info.outputs.appimage_url }}" max_attempts=10 attempt=1 while [ $attempt -le $max_attempts ]; do echo "Attempt $attempt: Checking if AppImage is available..." if curl -I -f "$APPIMAGE_URL" > /dev/null 2>&1; then echo "✅ AppImage is accessible" break else echo "❌ AppImage not yet accessible, waiting 30 seconds..." sleep 30 attempt=$((attempt + 1)) fi done if [ $attempt -gt $max_attempts ]; then echo "❌ AppImage not accessible after $max_attempts attempts" exit 1 fi - name: Download artifacts and calculate SHA256s id: sha_calc run: | # Download AppImage and desktop file, then calculate SHA256s curl -L -o "friendly-kobold-${{ steps.release_info.outputs.version }}.AppImage" "${{ steps.release_info.outputs.appimage_url }}" curl -L -o "friendly-kobold.desktop" "https://raw.githubusercontent.com/lone-cloud/friendly-kobold/${{ inputs.tag }}/assets/friendly-kobold.desktop" SHA256_APPIMAGE=$(sha256sum "friendly-kobold-${{ steps.release_info.outputs.version }}.AppImage" | cut -d' ' -f1) SHA256_DESKTOP=$(sha256sum "friendly-kobold.desktop" | cut -d' ' -f1) echo "sha256_appimage=$SHA256_APPIMAGE" >> $GITHUB_OUTPUT echo "sha256_desktop=$SHA256_DESKTOP" >> $GITHUB_OUTPUT echo "AppImage SHA256: $SHA256_APPIMAGE" echo "Desktop SHA256: $SHA256_DESKTOP" - name: Generate PKGBUILD run: | cat > PKGBUILD << 'EOF' # Maintainer: ${{ steps.release_info.outputs.author_name }} <${{ steps.release_info.outputs.author_email }}> pkgname=friendly-kobold pkgver=${{ steps.release_info.outputs.version }} pkgrel=1 pkgdesc="A desktop app for running Large Language Models locally" arch=('x86_64') url="https://github.com/lone-cloud/friendly-kobold" license=('AGPL-3.0-or-later') depends=('gtk3' 'nss') optdepends=('alsa-lib: Audio support for sound effects' 'libxss: Screen saver detection support') provides=('friendly-kobold') conflicts=('friendly-kobold-git') source=("friendly-kobold-${pkgver}.AppImage::${{ steps.release_info.outputs.appimage_url }}" "friendly-kobold.desktop::https://raw.githubusercontent.com/lone-cloud/friendly-kobold/${{ steps.release_info.outputs.tag }}/assets/friendly-kobold.desktop") sha256sums=('${{ steps.sha_calc.outputs.sha256_appimage }}' '${{ steps.sha_calc.outputs.sha256_desktop }}') prepare() { chmod +x "friendly-kobold-${pkgver}.AppImage" "./friendly-kobold-${pkgver}.AppImage" --appimage-extract } package() { # Install the application install -dm755 "${pkgdir}/opt/friendly-kobold" cp -r squashfs-root/* "${pkgdir}/opt/friendly-kobold/" # Fix permissions on extracted files chmod -R 755 "${pkgdir}/opt/friendly-kobold/" # Create executable wrapper install -dm755 "${pkgdir}/usr/bin" cat > "${pkgdir}/usr/bin/friendly-kobold" << 'WRAPPER' #!/bin/bash exec "/opt/friendly-kobold/Friendly Kobold" "$@" WRAPPER chmod +x "${pkgdir}/usr/bin/friendly-kobold" # Install desktop file from assets install -dm755 "${pkgdir}/usr/share/applications" cp "${srcdir}/friendly-kobold.desktop" "${pkgdir}/usr/share/applications/" # Install icon install -dm755 "${pkgdir}/usr/share/pixmaps" # Try different possible icon locations if [ -f "${pkgdir}/opt/friendly-kobold/resources/assets/icon.png" ]; then cp "${pkgdir}/opt/friendly-kobold/resources/assets/icon.png" "${pkgdir}/usr/share/pixmaps/friendly-kobold.png" elif [ -f "${pkgdir}/opt/friendly-kobold/assets/icon.png" ]; then cp "${pkgdir}/opt/friendly-kobold/assets/icon.png" "${pkgdir}/usr/share/pixmaps/friendly-kobold.png" elif [ -f "${pkgdir}/opt/friendly-kobold/icon.png" ]; then cp "${pkgdir}/opt/friendly-kobold/icon.png" "${pkgdir}/usr/share/pixmaps/friendly-kobold.png" else echo "Warning: Could not find icon.png in expected locations" fi } EOF - name: Create .SRCINFO run: | # Create .SRCINFO file (required for AUR) cat > .SRCINFO << 'EOF' pkgbase = friendly-kobold pkgdesc = A desktop app for running Large Language Models locally pkgver = ${{ steps.release_info.outputs.version }} pkgrel = 1 url = https://github.com/lone-cloud/friendly-kobold arch = x86_64 license = AGPL-3.0-or-later depends = gtk3 depends = nss optdepends = alsa-lib: Audio support for sound effects optdepends = libxss: Screen saver detection support provides = friendly-kobold conflicts = friendly-kobold-git source = friendly-kobold-${{ steps.release_info.outputs.version }}.AppImage::${{ steps.release_info.outputs.appimage_url }} source = friendly-kobold.desktop::https://raw.githubusercontent.com/lone-cloud/friendly-kobold/${{ steps.release_info.outputs.tag }}/assets/friendly-kobold.desktop sha256sums = ${{ steps.sha_calc.outputs.sha256_appimage }} sha256sums = ${{ steps.sha_calc.outputs.sha256_desktop }} pkgname = friendly-kobold EOF - name: Publish to AUR uses: KSXGitHub/github-actions-deploy-aur@v2.7.2 with: pkgname: friendly-kobold pkgbuild: ./PKGBUILD commit_username: ${{ steps.release_info.outputs.author_name }} commit_email: ${{ steps.release_info.outputs.author_email }} ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} commit_message: 'Update to ${{ steps.release_info.outputs.version }}' ssh_keyscan_types: rsa,ecdsa,ed25519 - name: Create AUR release summary run: | echo "## AUR Release Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "📦 **Package**: friendly-kobold" >> $GITHUB_STEP_SUMMARY echo "🔖 **Version**: ${{ steps.release_info.outputs.version }}" >> $GITHUB_STEP_SUMMARY echo "🔗 **AUR Page**: https://aur.archlinux.org/packages/friendly-kobold" >> $GITHUB_STEP_SUMMARY echo "✅ **Status**: Successfully published to AUR" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Installation" >> $GITHUB_STEP_SUMMARY echo '```bash' >> $GITHUB_STEP_SUMMARY echo "# Using yay" >> $GITHUB_STEP_SUMMARY echo "yay -S friendly-kobold" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "# Using paru" >> $GITHUB_STEP_SUMMARY echo "paru -S friendly-kobold" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY