perf(desktop): ship a .deb instead of an 80MB AppImage
ci / api / api (push) Successful in 50s
ci / db / db (push) Successful in 50s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Failing after 49s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m13s
ci / ts / ts (packages + web) (push) Canceled after 2m4s
ci / desktop / rust (desktop proxy) (push) Successful in 5m33s
release / release (версия и заметки) (push) Successful in 9s
release / android (APK в релиз) (push) Failing after 4m6s
release / desktop (Linux и Windows в релиз) (push) Successful in 17m20s
ci / api / api (push) Successful in 50s
ci / db / db (push) Successful in 50s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Failing after 49s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m13s
ci / ts / ts (packages + web) (push) Canceled after 2m4s
ci / desktop / rust (desktop proxy) (push) Successful in 5m33s
release / release (версия и заметки) (push) Successful in 9s
release / android (APK в релиз) (push) Failing after 4m6s
release / desktop (Linux и Windows в релиз) (push) Successful in 17m20s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
73ad61e7a5
commit
83b604437c
14 files changed
+27
-34
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
# Rust-часть десктопа: прокси и проверки URL. Установщики — в release.yml
|
# Rust-часть десктопа: прокси и проверки URL. Установщики — в release.yml
|
||||||
# (Linux AppImage/deb и Windows NSIS через cargo-xwin на ubuntu-latest).
|
# (Linux .deb и Windows NSIS через cargo-xwin на ubuntu-latest).
|
||||||
name: ci / desktop
|
name: ci / desktop
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|||||||
@@ -217,7 +217,6 @@ jobs:
|
|||||||
PUBLIC_URL: ${{ vars.PUBLIC_URL || 'https://gitea.hsrv.site' }}
|
PUBLIC_URL: ${{ vars.PUBLIC_URL || 'https://gitea.hsrv.site' }}
|
||||||
TAG: ${{ github.ref_name }}
|
TAG: ${{ github.ref_name }}
|
||||||
VERSION: ${{ needs.release.outputs.version }}
|
VERSION: ${{ needs.release.outputs.version }}
|
||||||
APPIMAGE_EXTRACT_AND_RUN: "1"
|
|
||||||
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
||||||
CARGO_BUILD_JOBS: "2"
|
CARGO_BUILD_JOBS: "2"
|
||||||
XWIN_CACHE_DIR: /opt/ci-cache/xwin
|
XWIN_CACHE_DIR: /opt/ci-cache/xwin
|
||||||
@@ -235,7 +234,7 @@ jobs:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file \
|
sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file \
|
||||||
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev \
|
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev \
|
||||||
libdbus-1-dev libsecret-1-dev patchelf libfuse2 \
|
libdbus-1-dev libsecret-1-dev patchelf \
|
||||||
nsis lld llvm clang
|
nsis lld llvm clang
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
@@ -250,7 +249,7 @@ jobs:
|
|||||||
key: cargo-desktop-${{ hashFiles('apps/desktop/src-tauri/Cargo.toml') }}
|
key: cargo-desktop-${{ hashFiles('apps/desktop/src-tauri/Cargo.toml') }}
|
||||||
restore-keys: cargo-desktop-
|
restore-keys: cargo-desktop-
|
||||||
- run: pnpm install --frozen-lockfile
|
- run: pnpm install --frozen-lockfile
|
||||||
- name: Сборка AppImage и deb
|
- name: Сборка deb
|
||||||
id: linux
|
id: linux
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
run: |
|
run: |
|
||||||
@@ -258,27 +257,21 @@ jobs:
|
|||||||
pnpm bundle:linux
|
pnpm bundle:linux
|
||||||
bundle=src-tauri/target/release/bundle
|
bundle=src-tauri/target/release/bundle
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
for f in "$bundle"/appimage/*.AppImage; do
|
|
||||||
cp "$f" "$GITHUB_WORKSPACE/pipu-music-${PIPU_VERSION}-linux.AppImage"
|
|
||||||
done
|
|
||||||
for f in "$bundle"/deb/*.deb; do
|
for f in "$bundle"/deb/*.deb; do
|
||||||
cp "$f" "$GITHUB_WORKSPACE/pipu-music-${PIPU_VERSION}-linux.deb"
|
cp "$f" "$GITHUB_WORKSPACE/pipu-music-${PIPU_VERSION}-linux.deb"
|
||||||
done
|
done
|
||||||
ls -lh "$GITHUB_WORKSPACE"/pipu-music-${PIPU_VERSION}-linux.*
|
ls -lh "$GITHUB_WORKSPACE/pipu-music-${PIPU_VERSION}-linux.deb"
|
||||||
rm -rf src-tauri/target/release
|
rm -rf src-tauri/target/release
|
||||||
- name: Linux в релиз
|
- name: Linux в релиз
|
||||||
id: linux-upload
|
id: linux-upload
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
files=()
|
f="pipu-music-${PIPU_VERSION}-linux.deb"
|
||||||
for f in pipu-music-${PIPU_VERSION}-linux.AppImage pipu-music-${PIPU_VERSION}-linux.deb; do
|
if [ ! -f "$f" ]; then
|
||||||
[ -f "$f" ] && files+=("$f")
|
echo "::error::нет $f после сборки"
|
||||||
done
|
|
||||||
if [ ${#files[@]} -eq 0 ]; then
|
|
||||||
echo "::error::нет AppImage и deb после сборки"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
node scripts/release.mjs desktop linux success "${files[@]}"
|
node scripts/release.mjs desktop linux success "$f"
|
||||||
- name: Windows toolchain
|
- name: Windows toolchain
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+1
-1
@@ -1549,7 +1549,7 @@ paths:
|
|||||||
security: [] # публично: страница /download без входа
|
security: [] # публично: страница /download без входа
|
||||||
summary: Клиенты последнего релиза (Android и десктоп)
|
summary: Клиенты последнего релиза (Android и десктоп)
|
||||||
description: |
|
description: |
|
||||||
Тот же релиз Gitea, что и для Android: APK, установщик Windows, AppImage/deb, DMG.
|
Тот же релиз Gitea, что и для Android: APK, установщик Windows, .deb, DMG.
|
||||||
Нет настроек Gitea или файлов клиентов — `404 app.update_unavailable`.
|
Нет настроек Gitea или файлов клиентов — `404 app.update_unavailable`.
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tauri dev",
|
"dev": "tauri dev",
|
||||||
"bundle": "node inject-version.mjs && tauri build --config src-tauri/tauri.release.json",
|
"bundle": "node inject-version.mjs && tauri build --config src-tauri/tauri.release.json",
|
||||||
"bundle:linux": "node inject-version.mjs && tauri build --config src-tauri/tauri.release.json --bundles appimage,deb",
|
"bundle:linux": "node inject-version.mjs && tauri build --config src-tauri/tauri.release.json --bundles deb",
|
||||||
"bundle:windows": "node inject-version.mjs && tauri build --config src-tauri/tauri.release.json --bundles nsis",
|
"bundle:windows": "node inject-version.mjs && tauri build --config src-tauri/tauri.release.json --bundles nsis",
|
||||||
"bundle:windows:cross": "node inject-version.mjs && tauri build --config src-tauri/tauri.release.json --runner cargo-xwin --target x86_64-pc-windows-msvc --bundles nsis",
|
"bundle:windows:cross": "node inject-version.mjs && tauri build --config src-tauri/tauri.release.json --runner cargo-xwin --target x86_64-pc-windows-msvc --bundles nsis",
|
||||||
"tauri": "tauri",
|
"tauri": "tauri",
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export function fakeApi(initial: FakeUser[]) {
|
|||||||
notes_md: '',
|
notes_md: '',
|
||||||
clients: [
|
clients: [
|
||||||
{ client: 'windows', filename: 'pipu-music_1.3.0_x64-setup.exe', size: 20_000_000, download_url: '/api/v1/app/download/windows/1.3.0' },
|
{ client: 'windows', filename: 'pipu-music_1.3.0_x64-setup.exe', size: 20_000_000, download_url: '/api/v1/app/download/windows/1.3.0' },
|
||||||
{ client: 'linux', filename: 'pipu-music_1.3.0_amd64.AppImage', size: 18_000_000, download_url: '/api/v1/app/download/linux/1.3.0' },
|
{ client: 'linux', filename: 'pipu-music_1.3.0_amd64.deb', size: 4_000_000, download_url: '/api/v1/app/download/linux/1.3.0' },
|
||||||
{ client: 'macos', filename: 'pipu-music_1.3.0_aarch64.dmg', size: 22_000_000, download_url: '/api/v1/app/download/macos/1.3.0' },
|
{ client: 'macos', filename: 'pipu-music_1.3.0_aarch64.dmg', size: 22_000_000, download_url: '/api/v1/app/download/macos/1.3.0' },
|
||||||
{ client: 'android', filename: 'pipu-music-1.3.0.apk', size: 12_000_000, sha256: 'ab'.repeat(32), download_url: '/api/v1/app/download/android/1.3.0' },
|
{ client: 'android', filename: 'pipu-music-1.3.0.apk', size: 12_000_000, sha256: 'ab'.repeat(32), download_url: '/api/v1/app/download/android/1.3.0' },
|
||||||
],
|
],
|
||||||
|
|||||||
+1
-1
@@ -104,7 +104,7 @@
|
|||||||
Android-приложение обновляется само: при запуске оно сверяется с сервером и предлагает новый APK.
|
Android-приложение обновляется само: при запуске оно сверяется с сервером и предлагает новый APK.
|
||||||
Раздать приложение — ссылка `https://<ваш-домен>/download` (без входа; `/android` перенаправляет сюда):
|
Раздать приложение — ссылка `https://<ваш-домен>/download` (без входа; `/android` перенаправляет сюда):
|
||||||
сборка под систему посетителя, остальные платформы ниже, адрес сервера для копирования и короткая инструкция.
|
сборка под систему посетителя, остальные платформы ниже, адрес сервера для копирования и короткая инструкция.
|
||||||
APK, Linux (AppImage, deb) и Windows (NSIS) прикладываются к релизу Gitea автоматически. Та же страница — внизу экрана входа
|
APK, Linux (`.deb`) и Windows (NSIS) прикладываются к релизу Gitea автоматически. Та же страница — внизу экрана входа
|
||||||
и в меню профиля.
|
и в меню профиля.
|
||||||
|
|
||||||
## 7. Наблюдение
|
## 7. Наблюдение
|
||||||
|
|||||||
+2
-2
@@ -12,6 +12,6 @@ pnpm --filter @pipu/desktop dev
|
|||||||
pnpm --filter @pipu/desktop bundle
|
pnpm --filter @pipu/desktop bundle
|
||||||
```
|
```
|
||||||
|
|
||||||
На Windows получается NSIS-установщик, на Linux — AppImage, deb и rpm. Зависимости Linux: WebKitGTK 4.1, AppIndicator, libsecret, GStreamer (плеер идёт через WebKit, в AppImage GStreamer не упаковываем — иначе файл раздувается на десятки мегабайт).
|
На Windows получается NSIS-установщик (~3 МБ). На Linux в релиз идёт только `.deb` (~4 МБ): AppImage тащит WebKitGTK и раздувается до ~80 МБ. Зависимости пакета: WebKitGTK 4.1, AppIndicator, libsecret, GStreamer.
|
||||||
|
|
||||||
Релиз по тегу собирает всё на Linux-раннере: AppImage/`.deb` и Windows NSIS через `cargo-xwin` (`pipu-music-<версия>-windows-setup.exe`). Подпись Windows-установщика на Linux нет. Страница `/download` на сервере отдаёт те файлы, что есть в последнем релизе Gitea.
|
Релиз по тегу собирает Linux `.deb` и Windows NSIS через `cargo-xwin` (`pipu-music-<версия>-windows-setup.exe`). Подпись Windows-установщика на Linux нет. Страница `/download` на сервере отдаёт те файлы, что есть в последнем релизе Gitea.
|
||||||
@@ -1336,7 +1336,7 @@ export interface paths {
|
|||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Клиенты последнего релиза (Android и десктоп)
|
* Клиенты последнего релиза (Android и десктоп)
|
||||||
* @description Тот же релиз Gitea, что и для Android: APK, установщик Windows, AppImage/deb, DMG.
|
* @description Тот же релиз Gitea, что и для Android: APK, установщик Windows, .deb, DMG.
|
||||||
* Нет настроек Gitea или файлов клиентов — `404 app.update_unavailable`.
|
* Нет настроек Gitea или файлов клиентов — `404 app.update_unavailable`.
|
||||||
*/
|
*/
|
||||||
get: operations["getAppClients"];
|
get: operations["getAppClients"];
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
"download": {
|
"download": {
|
||||||
"android": "Download APK",
|
"android": "Download APK",
|
||||||
"windows": "Download for Windows",
|
"windows": "Download for Windows",
|
||||||
"linux": "Download AppImage",
|
"linux": "Download .deb",
|
||||||
"macos": "Download for macOS"
|
"macos": "Download for macOS"
|
||||||
},
|
},
|
||||||
"version": "version {{version}}",
|
"version": "version {{version}}",
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
"step_install": {
|
"step_install": {
|
||||||
"android": "Open the downloaded file. If Android asks, allow installs from this source.",
|
"android": "Open the downloaded file. If Android asks, allow installs from this source.",
|
||||||
"windows": "Run the installer and follow the steps. pipu will appear in the Start menu.",
|
"windows": "Run the installer and follow the steps. pipu will appear in the Start menu.",
|
||||||
"linux": "Make the file executable and open it. For a .deb, install the package.",
|
"linux": "Install the package: sudo apt install ./pipu-music-….deb. Needs WebKitGTK 4.1 and GStreamer.",
|
||||||
"macos": "Open the disk image and drag pipu into Applications."
|
"macos": "Open the disk image and drag pipu into Applications."
|
||||||
},
|
},
|
||||||
"step_server": "Launch pipu and enter the server address:",
|
"step_server": "Launch pipu and enter the server address:",
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
"download": {
|
"download": {
|
||||||
"android": "Скачать APK",
|
"android": "Скачать APK",
|
||||||
"windows": "Скачать для Windows",
|
"windows": "Скачать для Windows",
|
||||||
"linux": "Скачать AppImage",
|
"linux": "Скачать .deb",
|
||||||
"macos": "Скачать для macOS"
|
"macos": "Скачать для macOS"
|
||||||
},
|
},
|
||||||
"version": "версия {{version}}",
|
"version": "версия {{version}}",
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
"step_install": {
|
"step_install": {
|
||||||
"android": "Откройте скачанный файл. Если Android спросит — разрешите установку из этого источника.",
|
"android": "Откройте скачанный файл. Если Android спросит — разрешите установку из этого источника.",
|
||||||
"windows": "Запустите установщик и следуйте шагам. pipu появится в меню Пуск.",
|
"windows": "Запустите установщик и следуйте шагам. pipu появится в меню Пуск.",
|
||||||
"linux": "Сделайте файл исполняемым и откройте его. Для .deb — установите пакет.",
|
"linux": "Установите пакет: sudo apt install ./pipu-music-….deb. Нужны WebKitGTK 4.1 и GStreamer.",
|
||||||
"macos": "Откройте образ и перетащите pipu в Программы."
|
"macos": "Откройте образ и перетащите pipu в Программы."
|
||||||
},
|
},
|
||||||
"step_server": "Запустите pipu и введите адрес сервера:",
|
"step_server": "Запустите pipu и введите адрес сервера:",
|
||||||
|
|||||||
+2
-2
@@ -85,7 +85,7 @@ export function renderAndroidStatus({ status, runUrl, versionCode, apk, signing
|
|||||||
/** Блок статуса сборки десктопа в тексте релиза (отдельный для linux и windows). */
|
/** Блок статуса сборки десктопа в тексте релиза (отдельный для linux и windows). */
|
||||||
export function renderDesktopStatus({ platform, status, runUrl, files }) {
|
export function renderDesktopStatus({ platform, status, runUrl, files }) {
|
||||||
const label = platform === 'windows' ? 'Windows' : 'Linux';
|
const label = platform === 'windows' ? 'Windows' : 'Linux';
|
||||||
const pending = platform === 'windows' ? 'NSIS-установщик' : 'AppImage и .deb';
|
const pending = platform === 'windows' ? 'NSIS-установщик' : '.deb';
|
||||||
const lines =
|
const lines =
|
||||||
status === 'success'
|
status === 'success'
|
||||||
? [
|
? [
|
||||||
@@ -185,7 +185,7 @@ export function renderNotes({
|
|||||||
'',
|
'',
|
||||||
`- **Android:** \`pipu-music-${version}.apk\` — откройте на телефоне; Android попросит разрешить установку из этого источника.`,
|
`- **Android:** \`pipu-music-${version}.apk\` — откройте на телефоне; Android попросит разрешить установку из этого источника.`,
|
||||||
`- **Windows:** \`pipu-music-${version}-windows-setup.exe\`.`,
|
`- **Windows:** \`pipu-music-${version}-windows-setup.exe\`.`,
|
||||||
`- **Linux:** \`pipu-music-${version}-linux.AppImage\` (сделайте исполняемым) или \`.deb\`.`,
|
`- **Linux:** \`pipu-music-${version}-linux.deb\` — \`sudo apt install ./pipu-music-${version}-linux.deb\` (нужны WebKitGTK 4.1 и GStreamer).`,
|
||||||
`- **Проверка APK:** \`sha256sum pipu-music-${version}.apk\` должен совпасть с \`pipu-music-${version}.apk.sha256\`.`,
|
`- **Проверка APK:** \`sha256sum pipu-music-${version}.apk\` должен совпасть с \`pipu-music-${version}.apk.sha256\`.`,
|
||||||
'',
|
'',
|
||||||
`Первая установка сервера — [инструкция](${repoUrl}/src/tag/${tag}/docs/install-guide.md).`,
|
`Первая установка сервера — [инструкция](${repoUrl}/src/tag/${tag}/docs/install-guide.md).`,
|
||||||
|
|||||||
@@ -89,9 +89,9 @@ test('desktop status blocks', () => {
|
|||||||
const ok = renderDesktopStatus({
|
const ok = renderDesktopStatus({
|
||||||
platform: 'linux',
|
platform: 'linux',
|
||||||
status: 'success',
|
status: 'success',
|
||||||
files: [{ name: 'pipu-music-1.4.0-linux.AppImage', size: 40 * 1024 * 1024 }],
|
files: [{ name: 'pipu-music-1.4.0-linux.deb', size: 4 * 1024 * 1024 }],
|
||||||
});
|
});
|
||||||
assert.match(ok, /`pipu-music-1\.4\.0-linux\.AppImage` \(40,0 МБ\)/);
|
assert.match(ok, /`pipu-music-1\.4\.0-linux\.deb` \(4,0 МБ\)/);
|
||||||
assert.equal(replaceDesktopStatus(`a\n\n${building}\n\nb`, 'linux', ok).includes(building), false);
|
assert.equal(replaceDesktopStatus(`a\n\n${building}\n\nb`, 'linux', ok).includes(building), false);
|
||||||
|
|
||||||
const winBuilding = renderDesktopStatus({ platform: 'windows', status: 'building', runUrl: 'https://run' });
|
const winBuilding = renderDesktopStatus({ platform: 'windows', status: 'building', runUrl: 'https://run' });
|
||||||
@@ -126,7 +126,7 @@ test('release notes', () => {
|
|||||||
assert.match(notes, /"version":"0\.2\.0"/);
|
assert.match(notes, /"version":"0\.2\.0"/);
|
||||||
assert.match(notes, /pipu-music-0\.2\.0\.apk/);
|
assert.match(notes, /pipu-music-0\.2\.0\.apk/);
|
||||||
assert.match(notes, /pipu-music-0\.2\.0-windows-setup\.exe/);
|
assert.match(notes, /pipu-music-0\.2\.0-windows-setup\.exe/);
|
||||||
assert.match(notes, /pipu-music-0\.2\.0-linux\.AppImage/);
|
assert.match(notes, /pipu-music-0\.2\.0-linux\.deb/);
|
||||||
assert.match(notes, /src\/tag\/v0\.2\.0\/docs\/install-guide\.md/);
|
assert.match(notes, /src\/tag\/v0\.2\.0\/docs\/install-guide\.md/);
|
||||||
assert.doesNotMatch(notes, /Предварительная версия/);
|
assert.doesNotMatch(notes, /Предварительная версия/);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -161,9 +161,9 @@ func assetRank(kind, name string) int {
|
|||||||
return 1
|
return 1
|
||||||
case "linux":
|
case "linux":
|
||||||
switch {
|
switch {
|
||||||
case strings.HasSuffix(n, ".appimage"):
|
|
||||||
return 3
|
|
||||||
case strings.HasSuffix(n, ".deb"):
|
case strings.HasSuffix(n, ".deb"):
|
||||||
|
return 3
|
||||||
|
case strings.HasSuffix(n, ".rpm"):
|
||||||
return 2
|
return 2
|
||||||
default:
|
default:
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func TestPickClientFiles(t *testing.T) {
|
|||||||
assert.Equal(t, "pipu-music-1.3.0.apk", files["android"].Name)
|
assert.Equal(t, "pipu-music-1.3.0.apk", files["android"].Name)
|
||||||
assert.Equal(t, "https://gitea/sum", files["android"].ChecksumURL)
|
assert.Equal(t, "https://gitea/sum", files["android"].ChecksumURL)
|
||||||
assert.Equal(t, "pipu-music_1.3.0_x64-setup.exe", files["windows"].Name)
|
assert.Equal(t, "pipu-music_1.3.0_x64-setup.exe", files["windows"].Name)
|
||||||
assert.Equal(t, "pipu-music_1.3.0_amd64.AppImage", files["linux"].Name)
|
assert.Equal(t, "pipu-music_1.3.0_amd64.deb", files["linux"].Name)
|
||||||
assert.Equal(t, "pipu-music_1.3.0_aarch64.dmg", files["macos"].Name)
|
assert.Equal(t, "pipu-music_1.3.0_aarch64.dmg", files["macos"].Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user