From 78459b964faa0cdd841a27bc5d551f621c1b37aa Mon Sep 17 00:00:00 2001 From: av Date: Sat, 24 Oct 2026 12:06:23 +0200 Subject: [PATCH 1/4] fix(app): build AppImages with portable icon symlinks --- .facts | 2 + README.md | 2 + app/bun.lockb | Bin 165150 -> 165150 bytes app/package-lock.json | 96 +++++++++++++++++++++--------------------- app/package.json | 2 +- 5 files changed, 53 insertions(+), 49 deletions(-) diff --git a/.facts b/.facts index 2558a472b..188baf7a7 100644 --- a/.facts +++ b/.facts @@ -1461,6 +1461,8 @@ command: grep -q 'manualChunks' app/vite.config.ts tags: [implemented] - Harbor App Profiles loads profiles under a dot-prefixed Harbor home without a Tauri forbidden-path error @spec @issue-64 @implemented +- Harbor AppImage builds use Tauri CLI 2.11.4 or later so AppDir icon and desktop symlinks remain valid after mounting @appimage @implemented +- Harbor README starts with the application name before any shell examples @appimage @implemented # boost - label: Boost is a FastAPI LLM proxy that exposes OpenAI chat completions and optional Anthropic and Responses compat layers diff --git a/README.md b/README.md index 3dc01b199..cbfeb6993 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +# Harbor + https://github.com/user-attachments/assets/e4897391-c5a8-4391-93c3-9f8b76155f11 [![GitHub Tag](https://img.shields.io/github/v/tag/av/harbor)](https://github.com/av/harbor/releases) diff --git a/app/bun.lockb b/app/bun.lockb index 69cc3812314ee4ff66b515c4756c367142899866..b1f0abb6cfa6504003ff932cda38316752f9cc4d 100755 GIT binary patch delta 2115 zcmZuy3p7+~6h7xTq%e%38hOoC(U6S1N_r>HqD-m@NiN;!D&$c)W6T(jifQ7Qs~EaU z4_2Wip~qcOic*)lN)joTTZrU!x&Po~(*4)k>)Zdg_y7I-{Ohc}GZJQHB+N=S)*Tf* z%wN*H&%%49XZJtck`&JmX78^19UWA4sE*HUpr>8iv{sQh#DyR|2x2z?qya1es0&au ziID(xz@9aUHUPE3US|>!fLdVxJ_dp`0agRlC~Q-tC~og7S-Rh@ak%+)p)F-6#W20; zcB$r7{$0D8E3#Ch*9v_td?@f*y&Gw3;0|{1=j79#Sw@}Nuev;Zoc~Di)>IOi&gyMe z4?DSc-e3-rrFFJD?X61VIuwz1l_=wVP*=gzzI^ZmA@8&%v(c5Vm0sy(Xe^RItU8SiVLde7dm z1dBd6oKIt;Y3Z(`Cl*}lFiGuPE<6*JbrFUj7(yTw@J<}y6APtfHDo5AMa!>e*`JHw zdaC|WPaL@-fGYER=I!CLoct;tz(t-3-fVZ6k>x)xiEwg1w&{`(|X>mW1j=n1;-0gC^g}< z0NJj0>2^H{j}zDreH)|G+LK!9HC1+fT&Cw@1+R@jJ=#FBRtH8GaIL<~xLCcC=BtZY@4W&0)LszUuFa(4w7pGT4&s;`L-v zUBM$+|M3bTdC8l`Nmn@3-IA-S*7m2ogL1dUm#^v@i+ePYO%kRPw&WLeD)d;3XK2hFMo!dVhyu zDagC>xUKl+`(RJTbAG-`4{s2u6IayDR}bj)i7BJg^4wlkpeMq0Lae^X4?49dk4Whz zeD@PHxH<3ivQm57m+t>l+%nQjEfr69#RYAn)yaSBiDYOHqvMG<+@q`YZn#od)sdBQ zjy)b?#)Xwf%@zF9s72O+v!hn~vc+`YkzY%jmG#0s6n71C9WblL0>qFd1O7z(xT# z1`Gv00t}KV))2u_s<2tH=rSDR?5F|S4bfLo*wmQ8FgAlAqL~w&cPc`(d!jc_MRf2d zgYax^aGDqqL_eR(Vd2pr2Ln08SRrP>R1PtCh$%4@Ax0B1N2VeT+=<~uOq!_(G2Vz- zB#EGsk1RGDf)#kM8NM1r)NpYOG7A@Bh$-&EMP}gJ*oX>l!a?LDTNG!oLCPIA*eY@n zc^tz)w3~w{OY)XTJVm@)q5@J>@X&8(qoNUoZ&DPT!9w)$Bo3m4E3v_C>o|xmxE|&p z<~Yb)G~q9ih%5&FT@GR`QAP1{97IbhD2E5Ik(szrG@?0?w)4B-c!gsz$h-;GeBuk< gMk6{>1P%BHV-O4cDu&47?lA~;f^Y$Fh>KkL536dyH2?qr delta 2109 zcmZuy4K!3~7`}6x{QnITW{?p={u)|RF&1fZX2cnTB>x>!(kiL6-7)?qrj${aQ+~=O z;e=*uiflxQ6m7&gm7THG#X1GkYd(L~F?|a|(d*1i^&OPr_lA}_RqjJ)Y zqOm^9d#AO*z@v%$!KMyZk8C?t*Us88-sZA9Ry1R6-+EsUHTF~n1W_P}GYHTaU=u(S zfTaMJ13UuI6ksSoX`U-UX`Tr{Lx73^$pDAbXY;!N8VO&i>8J${-flFk%Wk0$WkU(| zeE}LTgx)$KI@V{SnRiY{8mbq4yy>`${``yhVa-yK%?s6!tc0zceWND}3?}~Ov#|3ve_nX@e!GLpn0Q&ri5Q_DDQ>r5fV`SulnFuGL2($G{Zs{y$|wSaj;|$=9lo5LNoEnIQX97N4Vj*6xFT;~OB0&tvdpTFSIVGi-3?53#z7Dc!b2SJHe9gAKD^N%McW>l zvfeCXNc1F#M75kvSM+2bC~uw)Z_7e{qXjm(H&!(kBjJ&JU#sBiGV$ZTYy=y{b+G4C z-9ybEg8XE}N;2YfdEzMjp6^h-A8*3;D}_E&v2IB}9wT`5D>s~aluUH$?cdTW*b-I# zE)R-UJ;8_#k1Tfd;h%F6oOlpC8q*s1#pj@m7lO1vrx`d1!5W6}4fnci&OCWu9kZ^E zp&pbK@x=MnPwnAGlk@^1qphmSxq$N0?HKF##N8bI9{hM!#nL*en3ZX2y4>o>0mo4v z(k!u(lsHqq;X|7nw_GxJW~mkSp7IvrrN5s5#Py!N0aKI>-oK)yOx^dZY! zYeilV^6cVmV}Fe`{}7#gs;???H5tSaRQ-7PgkX*s58m{cJn@%IQdi^AgJQh94JGB} z$SSo0v(ESJ;)vv=2k{qz3qK2K!)?P^yQX#5DMt;E6ejswr~ajy71~`{lFDql%;}f$ zLP}EJoUeX@Kqvicr!^}bRU3Ls%^3AWW=prYJ6E)!*>vmK|YD>y%uo9PRYP_%mjr;C7!n6zLzu#kg^52h3g5lo&iEm??Q0*0y0LS!mqPU7bD zNE*RQFD+X08K;_wb3ok@n20uWUJi7IR@`6h&ZNbTSS2 zt|73NG+75FaDWe-z@zo^1XgLVsx(;(-N1!4Q7Q+fpad>VMR{qk1^U~z?8-sd^LBB3*Bup;_C4K|YVm2u$}vs?EJa0NI6TtQY1Y^n2kTIeWu SaUn&tJ{=~5S4hf$YyJa?h_jgh diff --git a/app/package-lock.json b/app/package-lock.json index e97b4784f..1248ff9f4 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -32,7 +32,7 @@ "tauri-pty": "^0.2.1" }, "devDependencies": { - "@tauri-apps/cli": "^2.11.2", + "@tauri-apps/cli": "^2.11.4", "@types/react": "^18.3.19", "@types/react-dom": "^18.3.5", "@vitejs/plugin-react": "^4.7.0", @@ -1255,9 +1255,9 @@ } }, "node_modules/@tauri-apps/cli": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.2.tgz", - "integrity": "sha512-bk3HemqvGRoy+5D/dVMUQHKMYLglD0jVnMm/0iGMH6ufZ+p8r14m6BpIixwij3PBvZdvORUp1YifTD8QxVZ1Nw==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.4.tgz", + "integrity": "sha512-R8xGtMpwyetawSqm9kYOuMmEqkhUbvcUy8n0aNXIxollKBLESUu5f4Fx+64hgASYm1H+jSWq6jCW6zqTnH6hqQ==", "dev": true, "license": "Apache-2.0 OR MIT", "bin": { @@ -1271,23 +1271,23 @@ "url": "https://opencollective.com/tauri" }, "optionalDependencies": { - "@tauri-apps/cli-darwin-arm64": "2.11.2", - "@tauri-apps/cli-darwin-x64": "2.11.2", - "@tauri-apps/cli-linux-arm-gnueabihf": "2.11.2", - "@tauri-apps/cli-linux-arm64-gnu": "2.11.2", - "@tauri-apps/cli-linux-arm64-musl": "2.11.2", - "@tauri-apps/cli-linux-riscv64-gnu": "2.11.2", - "@tauri-apps/cli-linux-x64-gnu": "2.11.2", - "@tauri-apps/cli-linux-x64-musl": "2.11.2", - "@tauri-apps/cli-win32-arm64-msvc": "2.11.2", - "@tauri-apps/cli-win32-ia32-msvc": "2.11.2", - "@tauri-apps/cli-win32-x64-msvc": "2.11.2" + "@tauri-apps/cli-darwin-arm64": "2.11.4", + "@tauri-apps/cli-darwin-x64": "2.11.4", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.11.4", + "@tauri-apps/cli-linux-arm64-gnu": "2.11.4", + "@tauri-apps/cli-linux-arm64-musl": "2.11.4", + "@tauri-apps/cli-linux-riscv64-gnu": "2.11.4", + "@tauri-apps/cli-linux-x64-gnu": "2.11.4", + "@tauri-apps/cli-linux-x64-musl": "2.11.4", + "@tauri-apps/cli-win32-arm64-msvc": "2.11.4", + "@tauri-apps/cli-win32-ia32-msvc": "2.11.4", + "@tauri-apps/cli-win32-x64-msvc": "2.11.4" } }, "node_modules/@tauri-apps/cli-darwin-arm64": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.2.tgz", - "integrity": "sha512-+4UZzLt+eOAEQCwgd+TqKgyUJMrvx+BgdXLLaqJYmPqzP+nE6YZr/hY6CWLYGQb8jFn99jEkmC6uA3tNvamA1w==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.4.tgz", + "integrity": "sha512-1ryOF3ZhpZ/nemHV5zVwBQBz9jDGKmKPvWPADOhc83ig0P4bMc2iER4NbC6r9sjeIZ6RVQ4g3RZIYvezhcl4TQ==", "cpu": [ "arm64" ], @@ -1302,9 +1302,9 @@ } }, "node_modules/@tauri-apps/cli-darwin-x64": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.2.tgz", - "integrity": "sha512-VjYYtZUPqDMLutSfJEyxFE3Bz+DPi7c8wC3imckgvciLDZLq4qwKJxBicg0BXGhXjJsl8vKWgWRFNMPELQ+Xyg==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.4.tgz", + "integrity": "sha512-uFsGQAAfuyz1k/yGLmkWfkBlgKAqZfxqlHmLWx81QU27RJWfmbNHCIq8T8w1e+VClleIuZUjpHWfoE4E3DLo3A==", "cpu": [ "x64" ], @@ -1319,9 +1319,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.2.tgz", - "integrity": "sha512-yMemD6f4i95AQriS8EazyOFzbE34yjnP16i3IOzpHGQvBoy2DjypFMFBq0NtPuITURv/cOGguRtHR5d79/9CSA==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.4.tgz", + "integrity": "sha512-IaHZn5CdBL21oUmjiVOS1ctw6Ip1O0pjp70FwOWmYz1myWe0SY96ZIj2FYf7pT0m8bI2h/hrs5ZbEXXh44/MkQ==", "cpu": [ "arm" ], @@ -1336,9 +1336,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm64-gnu": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.2.tgz", - "integrity": "sha512-cgI91D2wL8GSgoWwZXDqt+DwnuZCP2/bz03QAE4TrhgAKIsrB4hX26W/H1EONPUUNkqrsgeCD0wU6pcNjV/5kw==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.4.tgz", + "integrity": "sha512-N41/ukTRVe6XSuUTESuFdGeOW2i7k62tK+6gHK5Kd5/q5RPvvi19GaWAVPPb9u95HSGmTChSolBfzynUsssFaA==", "cpu": [ "arm64" ], @@ -1353,9 +1353,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm64-musl": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.2.tgz", - "integrity": "sha512-X1rm0BERqAAggtYTESSgXrS3sz4Sb/OiPiz54UqISlXW+GkR3vNIGnsy/lejNmoXGVqri3Q53BCfQiclOIyRPw==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.4.tgz", + "integrity": "sha512-v277UnT/fB64xAfSroL5N3Km3tLmvATWqJJw/wRI+g6o+HkeD0slyE7gOhNs1MbjE41R7bQOTxMVoL3aomUJmw==", "cpu": [ "arm64" ], @@ -1370,9 +1370,9 @@ } }, "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.2.tgz", - "integrity": "sha512-usbMLJbT3KtkOrBMDVeGYNM35aTHXx38SJSzTMSqqjeUIOQ+iVPjb2yAGNAE+KqmBbAx4FOFIyMeKXx2M/JKGQ==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.4.tgz", + "integrity": "sha512-qqgNkQ2u1yZHxjhxsZaxUtRDW8dIqIYm33rx/mzwQv0SfY9x1B+iraj8vWeFiXjjSVVhEMepXSOts1TqPzvXNQ==", "cpu": [ "riscv64" ], @@ -1387,9 +1387,9 @@ } }, "node_modules/@tauri-apps/cli-linux-x64-gnu": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.2.tgz", - "integrity": "sha512-Ru4gwJKPG0ctVGchRGpRup4Y4lW2SSfFnrbQcyHhCliKy4g8Qz97TrUgCur4CbWyAgKxvGh3SjrkA0LDYzDGiw==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.4.tgz", + "integrity": "sha512-2VRNWl84FOH0m2giiDkO2h0QXlcMJeX+zJDpI5kDIQAx6s+geF3v48F4DXfJez4GS/FdoDGnPnw1C2iYGbQ7bQ==", "cpu": [ "x64" ], @@ -1404,9 +1404,9 @@ } }, "node_modules/@tauri-apps/cli-linux-x64-musl": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.2.tgz", - "integrity": "sha512-eUm7T6clN1MMmNSRQ9gaWsQdyehQx2Gmn5hht/QUlqZQI/qcP2OJK5dnaxqwFzCr2HdsEo9ydxaqcS1oJzMvUw==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.4.tgz", + "integrity": "sha512-o9GyhYor/nc7xarmwDE3ka2szuW3uuZzXjHWh64Q8YX5AtSgxdQkFWzrY4O8KiGtVNvFBI14H3Q49Qj5TOIP/A==", "cpu": [ "x64" ], @@ -1421,9 +1421,9 @@ } }, "node_modules/@tauri-apps/cli-win32-arm64-msvc": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.2.tgz", - "integrity": "sha512-HeeZW80jU+gVTOEX4X/hC6NVSAdDVXajwP5fxIZ/3z9WvUC7qrudX2GMTilYq6Dg0e0sk0XgsAJD1hZ5wPBXUA==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.4.tgz", + "integrity": "sha512-ld5Ehb598m0VkYyylRPNeCFsBe/km0jxis6KgMpl3IGY6I/i1RwQXO05I1AsXUXO2WC6AvB/Lw4qTf/asiuEiQ==", "cpu": [ "arm64" ], @@ -1438,9 +1438,9 @@ } }, "node_modules/@tauri-apps/cli-win32-ia32-msvc": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.2.tgz", - "integrity": "sha512-YhjQNZcXfbkCLyazSv1nPnJ9iRFE1wm6kc51FDbU10/Dk09io+6PAGMLjkxnX2GdM0qMnDmTjstY8mTDVvtKeA==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.4.tgz", + "integrity": "sha512-12Hxi0XX/H5VFxO/bGgHkFWhml9VMgEOu9CidjeCeTNQ1l6fpUlbiGgSP7CLI3PFtW9/FfbeHieZ+kyWK5H7CA==", "cpu": [ "ia32" ], @@ -1455,9 +1455,9 @@ } }, "node_modules/@tauri-apps/cli-win32-x64-msvc": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.2.tgz", - "integrity": "sha512-d2JchlFIpZevZVReyqhQOekJmb1UH3rhZ5VX6sH3ty9ETE0TKQavpihvoScUXfKKpW6HZC0MrFGRU0ZtD+w3gA==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.4.tgz", + "integrity": "sha512-+vDiqBIU5dMISg/wNvX3sF+ZHfgJGJ5T0AcO+EHNXV9GGAG+P5fzodlDXD3QdKCRgZxMoCm5PPvj3BqLNjBthw==", "cpu": [ "x64" ], diff --git a/app/package.json b/app/package.json index d79954b3a..7545863cf 100644 --- a/app/package.json +++ b/app/package.json @@ -40,6 +40,6 @@ "@vitejs/plugin-react": "^4.7.0", "typescript": "^5.8.2", "vite": "^5.4.21", - "@tauri-apps/cli": "^2.11.2" + "@tauri-apps/cli": "^2.11.4" } } \ No newline at end of file From 0b6c33597859dc8eb9eb007d7d0597961705840f Mon Sep 17 00:00:00 2001 From: av Date: Sat, 24 Oct 2026 12:11:17 +0200 Subject: [PATCH 2/4] ci(app): validate AppImages on pull requests without publishing --- .facts | 1 + .github/workflows/app-release.yml | 68 +++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/.facts b/.facts index 188baf7a7..75d9f4300 100644 --- a/.facts +++ b/.facts @@ -1463,6 +1463,7 @@ - Harbor App Profiles loads profiles under a dot-prefixed Harbor home without a Tauri forbidden-path error @spec @issue-64 @implemented - Harbor AppImage builds use Tauri CLI 2.11.4 or later so AppDir icon and desktop symlinks remain valid after mounting @appimage @implemented - Harbor README starts with the application name before any shell examples @appimage @implemented +- App pull requests build an AppImage and run the catalog test without creating a release @spec @appimage # boost - label: Boost is a FastAPI LLM proxy that exposes OpenAI chat completions and optional Anthropic and Responses compat layers diff --git a/.github/workflows/app-release.yml b/.github/workflows/app-release.yml index 1f874fa95..c485ad245 100644 --- a/.github/workflows/app-release.yml +++ b/.github/workflows/app-release.yml @@ -2,6 +2,10 @@ name: Harbor App Release on: workflow_dispatch: + pull_request: + paths: + - app/** + - .github/workflows/app-release.yml push: branches: - "main" @@ -11,11 +15,75 @@ on: types: [published] jobs: + check-appimage: + if: github.event_name == 'pull_request' + runs-on: ubuntu-22.04 + timeout-minutes: 30 + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: 1.3.9 + - uses: dtolnay/rust-toolchain@stable + - name: Install build and catalog test dependencies + run: | + sudo apt-get update + sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev appstream gawk jq gnupg2 sudo imagemagick libasound2-dev pulseaudio-utils alsa-utils alsa-oss libjack0 desktop-file-utils xmlstarlet xsel xterm xvfb icewm x11-utils x11-apps netpbm xdotool libgl1-mesa-dri libgl1-mesa-dev mesa-utils libosmesa6 libsdl1.2-dev libsdl2-2.0-0 fonts-wqy-microhei libfile-mimeinfo-perl tesseract-ocr tesseract-ocr-eng tesseract-ocr-chi-sim tesseract-ocr-ara tesseract-ocr-rus tesseract-ocr-ell libfuse2 stalonetray + sudo gem install dupervisor -v 1.0.5 --no-document + sudo npm install -g asar + - name: Build AppImage + run: | + bun ./.scripts/docs-to-app.ts + cd app + bun install --frozen-lockfile + bun tauri build --bundles appimage -- --locked + - uses: actions/checkout@v4 + with: + repository: AppImage/appimage.github.io + ref: 2c518882fd364ad4e1c4148a1b1c1a2fa5fc5e31 + path: .appimage-catalog + sparse-checkout: code + - name: Run catalog test + working-directory: .appimage-catalog + env: + DISPLAY: :99 + IS_PULLREQUEST: true + STRICT: true + run: | + bash code/fetch-deps.sh + cp -a deps/. . + sudo bash code/prep-dummy-soundcard.sh + mkdir -p data apps database "$HOME/.icewm" + printf 'ShowTaskBar = 0\nTaskBarAutoHide = 1\n' > "$HOME/.icewm/preferences" + BUNDLE_DIR="$GITHUB_WORKSPACE/app/src-tauri/target/release/bundle/appimage" + APPIMAGE=$(find "$BUNDLE_DIR" -maxdepth 1 -name '*.AppImage' -printf '%f\n') + printf 'http://127.0.0.1:8765/%s\n' "$APPIMAGE" > data/Harbor + python3 -m http.server 8765 --bind 127.0.0.1 --directory "$BUNDLE_DIR" > http.log 2>&1 & + SERVER_PID=$! + Xvfb :99 -screen 0 800x600x24 > xvfb.log 2>&1 & + XVFB_PID=$! + trap 'kill "$SERVER_PID" "$XVFB_PID" 2>/dev/null || true' EXIT + timeout --kill-after=30 600 bash -e code/worker.sh "$PWD/data/Harbor" 2>&1 | tee log.txt + - uses: actions/upload-artifact@v4 + if: always() + with: + name: appimage-catalog-result + path: | + .appimage-catalog/*.log + .appimage-catalog/log.txt + .appimage-catalog/database/Harbor/ + .appimage-catalog/failure-screens/ + retention-days: 7 + test: + if: github.event_name != 'pull_request' name: Test Matrix uses: ./.github/workflows/test.yml publish-tauri: + if: github.event_name != 'pull_request' needs: test permissions: contents: write From da9a6c4ad7772dc144bae52da222d74e76de9d27 Mon Sep 17 00:00:00 2001 From: av Date: Sat, 24 Oct 2026 12:18:40 +0200 Subject: [PATCH 3/4] fix(app): keep AppImage launcher executable for all users --- .facts | 3 ++- app/scripts/prepare-appimage.sh | 11 +++++++++++ app/src-tauri/tauri.linux.conf.json | 5 +++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 app/scripts/prepare-appimage.sh create mode 100644 app/src-tauri/tauri.linux.conf.json diff --git a/.facts b/.facts index 75d9f4300..b9b50a82c 100644 --- a/.facts +++ b/.facts @@ -1463,7 +1463,8 @@ - Harbor App Profiles loads profiles under a dot-prefixed Harbor home without a Tauri forbidden-path error @spec @issue-64 @implemented - Harbor AppImage builds use Tauri CLI 2.11.4 or later so AppDir icon and desktop symlinks remain valid after mounting @appimage @implemented - Harbor README starts with the application name before any shell examples @appimage @implemented -- App pull requests build an AppImage and run the catalog test without creating a release @spec @appimage +- App pull requests build an AppImage and run the catalog test without creating a release @appimage @implemented +- Harbor AppImage builds make the cached AppRun launcher executable for every user before bundling @appimage @implemented # boost - label: Boost is a FastAPI LLM proxy that exposes OpenAI chat completions and optional Anthropic and Responses compat layers diff --git a/app/scripts/prepare-appimage.sh b/app/scripts/prepare-appimage.sh new file mode 100644 index 000000000..e728570d5 --- /dev/null +++ b/app/scripts/prepare-appimage.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/tauri" +launcher="$cache_dir/AppRun-$(uname -m)" +mkdir -p "$cache_dir" +if [ ! -f "$launcher" ]; then + curl -fL "https://github.com/tauri-apps/binary-releases/releases/download/apprun-old/$(basename "$launcher")" -o "$launcher.download" + mv "$launcher.download" "$launcher" +fi +chmod 755 "$launcher" diff --git a/app/src-tauri/tauri.linux.conf.json b/app/src-tauri/tauri.linux.conf.json new file mode 100644 index 000000000..68e30a1ac --- /dev/null +++ b/app/src-tauri/tauri.linux.conf.json @@ -0,0 +1,5 @@ +{ + "build": { + "beforeBundleCommand": "bash scripts/prepare-appimage.sh" + } +} From 75a906ec4a897fa030804cfdd2e8c71aa79f353d Mon Sep 17 00:00:00 2001 From: av Date: Sat, 24 Oct 2026 12:25:04 +0200 Subject: [PATCH 4/4] fix(app): initialize React before Markdown in production bundles --- .facts | 1 + app/vite.config.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/.facts b/.facts index b9b50a82c..8506109cb 100644 --- a/.facts +++ b/.facts @@ -1465,6 +1465,7 @@ - Harbor README starts with the application name before any shell examples @appimage @implemented - App pull requests build an AppImage and run the catalog test without creating a release @appimage @implemented - Harbor AppImage builds make the cached AppRun launcher executable for every user before bundling @appimage @implemented +- Harbor App production bundles initialize React before Markdown components @appimage @implemented # boost - label: Boost is a FastAPI LLM proxy that exposes OpenAI chat completions and optional Anthropic and Responses compat layers diff --git a/app/vite.config.ts b/app/vite.config.ts index db793a2c8..20283e980 100644 --- a/app/vite.config.ts +++ b/app/vite.config.ts @@ -34,6 +34,7 @@ export default defineConfig(async () => ({ rollupOptions: { output: { manualChunks(id: string) { + if (id.includes("commonjsHelpers.js")) return "react"; if (!id.includes("node_modules")) return; if (id.includes("refractor") || id.includes("highlight.js")) return "syntax"; if (