diff --git a/.github/workflows/flatpak-test.yml b/.github/workflows/flatpak-test.yml new file mode 100644 index 00000000..0c228438 --- /dev/null +++ b/.github/workflows/flatpak-test.yml @@ -0,0 +1,74 @@ +name: flatpak-test + +on: + workflow_dispatch: + +permissions: + contents: read + +jobs: + build-flatpak: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + lfs: true + + - name: Checkout Flathub manifest repo + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: Open-VCS/flathub + path: flathub + + - name: Setup Node + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: '24' + cache: 'npm' + cache-dependency-path: Frontend/package-lock.json + + - name: Install frontend deps + working-directory: Frontend + run: npm ci + + - name: Build frontend + working-directory: Frontend + run: npm run build + + - name: Install Linux build deps + shell: bash + run: | + set -euxo pipefail + sudo apt-get update + sudo apt-get install -y libappindicator3-dev librsvg2-dev patchelf + sudo apt-get install -y libwebkit2gtk-4.1-dev || sudo apt-get install -y libwebkit2gtk-4.0-dev + + - name: Install Flatpak tooling + shell: bash + run: | + set -euxo pipefail + sudo apt-get update + sudo apt-get install -y --no-install-recommends flatpak flatpak-builder appstream elfutils + flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + flatpak install --user -y flathub org.gnome.Platform//49 org.gnome.Sdk//49 + flatpak install --user -y flathub org.freedesktop.Sdk.Extension.rust-stable//25.08 \ + || flatpak install --user -y flathub org.freedesktop.Sdk.Extension.rust-stable//24.08 \ + || flatpak install --user -y flathub org.freedesktop.Sdk.Extension.rust-stable + flatpak install --user -y flathub org.freedesktop.Sdk.Extension.node24//25.08 \ + || flatpak install --user -y flathub org.freedesktop.Sdk.Extension.node24//24.08 + + - name: Build Flatpak bundle + shell: bash + run: | + set -euxo pipefail + flatpak-builder \ + --env=OPENVCS_OFFICIAL_RELEASE=1 \ + --user --force-clean --repo=repo build-flatpak flathub/io.github.jordonbc.OpenVCS.yml + flatpak build-bundle repo OpenVCS-test.flatpak io.github.jordonbc.OpenVCS + + - name: Upload Flatpak artifact + uses: actions/upload-artifact@v7 + with: + name: OpenVCS-flatpak-test + path: OpenVCS-test.flatpak diff --git a/.github/workflows/publish-stable.yml b/.github/workflows/publish-stable.yml index deb637e4..d89ce846 100644 --- a/.github/workflows/publish-stable.yml +++ b/.github/workflows/publish-stable.yml @@ -34,6 +34,13 @@ jobs: lfs: true fetch-depth: 0 + - name: Checkout Flathub manifest repo + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: Open-VCS/flathub + path: flathub + - name: Compute version tag id: version shell: bash @@ -86,7 +93,7 @@ jobs: # ---------- Flatpak (Linux only; artifact) ---------- - name: Install Flatpak tooling - if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('packaging/flatpak/io.github.jordonbc.OpenVCS.yml') != '' + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('flathub/io.github.jordonbc.OpenVCS.yml') != '' shell: bash run: | set -euxo pipefail @@ -103,25 +110,27 @@ jobs: || flatpak install --user -y flathub org.freedesktop.Sdk.Extension.node24//24.08 - name: Verify Flatpak manifest exists - if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('packaging/flatpak/io.github.jordonbc.OpenVCS.yml') != '' + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('flathub/io.github.jordonbc.OpenVCS.yml') != '' shell: bash run: | set -euxo pipefail - ls -la packaging/flatpak - test -f packaging/flatpak/io.github.jordonbc.OpenVCS.yml + ls -la flathub + test -f flathub/io.github.jordonbc.OpenVCS.yml - name: Build Flatpak bundle - if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('packaging/flatpak/io.github.jordonbc.OpenVCS.yml') != '' + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('flathub/io.github.jordonbc.OpenVCS.yml') != '' shell: bash run: | set -euxo pipefail # Stable production builds should report the plain package version (not git metadata). - export OPENVCS_OFFICIAL_RELEASE='1' - flatpak-builder --user --force-clean --repo=repo build-flatpak packaging/flatpak/io.github.jordonbc.OpenVCS.yml + # --env is required because flatpak-builder sandboxes don't inherit host env vars. + flatpak-builder \ + --env=OPENVCS_OFFICIAL_RELEASE=1 \ + --user --force-clean --repo=repo build-flatpak flathub/io.github.jordonbc.OpenVCS.yml flatpak build-bundle repo OpenVCS.flatpak io.github.jordonbc.OpenVCS - name: Upload Flatpak bundle (artifact) - if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('packaging/flatpak/io.github.jordonbc.OpenVCS.yml') != '' + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('flathub/io.github.jordonbc.OpenVCS.yml') != '' uses: actions/upload-artifact@v7 with: name: OpenVCS-flatpak-stable @@ -174,7 +183,47 @@ jobs: # bundles: '' # e.g. 'deb,appimage,msi,nsis' if you want to restrict output - name: Upload Flatpak bundle to GitHub Release - if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('packaging/flatpak/io.github.jordonbc.OpenVCS.yml') != '' + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('flathub/io.github.jordonbc.OpenVCS.yml') != '' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh release upload "${{ steps.version.outputs.tag }}" OpenVCS.flatpak --clobber + + # ---------- Update Flathub repo for next PR ---------- + - name: Install flatpak generator tools + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('flathub/io.github.jordonbc.OpenVCS.yml') != '' + shell: bash + run: | + set -euxo pipefail + pip install flatpak-cargo-generator flatpak-node-generator + + - name: Regenerate Flatpak vendor sources + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('flathub/io.github.jordonbc.OpenVCS.yml') != '' + shell: bash + run: | + set -euxo pipefail + # cargo-sources.json from workspace Cargo.lock + CARGO_GEN="$(python3 -c 'import flatpak_cargo_generator.script; print(flatpak_cargo_generator.script.__file__)')" + python3 "$CARGO_GEN" Cargo.lock -o flathub/cargo-sources.json + # npm-sources for Frontend + python3 -m flatpak_node_generator npm Frontend/package-lock.json -o flathub/npm-sources-frontend.json + echo "Vendor sources regenerated." + + - name: Update Flathub manifest and metadata + if: matrix.platform == 'ubuntu-24.04' && env.OPENVCS_ENABLE_FLATPAK == '1' && hashFiles('flathub/io.github.jordonbc.OpenVCS.yml') != '' + shell: bash + run: | + set -euxo pipefail + node scripts/update-flathub.js flathub \ + "${{ steps.version.outputs.version }}" \ + "$(git rev-parse HEAD)" + + # Git operations must run inside the flathub checkout, not the main repo. + cd flathub + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + set +x # avoid leaking the PAT in logs + git remote set-url origin "https://x-access-token:${{ secrets.FLATHUB_REPO_PAT }}@github.com/Open-VCS/flathub.git" + set -x + git add io.github.jordonbc.OpenVCS.yml io.github.jordonbc.OpenVCS.metainfo.xml cargo-sources.json npm-sources-frontend.json + git diff --staged --quiet || git commit -m "chore: bump to openvcs-v${{ steps.version.outputs.version }}" + git push diff --git a/AGENTS.md b/AGENTS.md index 77526b82..9831357f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,7 +7,7 @@ - `Frontend/`: TypeScript + Vite UI code (`src/scripts/`, `src/styles/`, `src/modals/`), with Vitest tests colocated as `*.test.ts` files. - OpenVCS is desktop-only: there is no web app, no standalone browser mode, and no supported web browser/WebView deployment target. - `docs/`: UX docs, plugin architecture notes, and plugin/theme packaging guides referenced by contributors. -- `packaging/flatpak/`: Flatpak manifests and Flatpak-specific build notes. +- Flatpak packaging is maintained in the sibling [`Open-VCS/flathub`](https://github.com/Open-VCS/flathub) repository. - Supporting files at the repo root include the workspace `Cargo.toml`, `Justfile`, `README.md`, `ARCHITECTURE.md`, `SECURITY.md`, and installer scripts. ## Build, test, and development commands diff --git a/Justfile b/Justfile index 1bdbb5d6..51a1ebd4 100644 --- a/Justfile +++ b/Justfile @@ -27,14 +27,15 @@ test: tauri-build channel="stable": FRONTEND_SKIP_BUILD=1 NO_STRIP=true OPENVCS_UPDATE_CHANNEL={{channel}} node scripts/tauri-build.js +# Requires Open-VCS/flathub cloned as a sibling directory: git clone git@github.com:Open-VCS/flathub.git ../flathub build-flatpak install="": @if [ "{{install}}" = "-i" ]; then \ - flatpak-builder --force-clean --user --install build-flatpak packaging/flatpak/io.github.jordonbc.OpenVCS.yml; \ + flatpak-builder --force-clean --user --install build-flatpak ../flathub/io.github.jordonbc.OpenVCS.yml; \ elif [ -n "{{install}}" ]; then \ echo "Usage: just build-flatpak [-i]"; \ exit 2; \ else \ - flatpak-builder --force-clean --user build-flatpak packaging/flatpak/io.github.jordonbc.OpenVCS.yml; \ + flatpak-builder --force-clean --user build-flatpak ../flathub/io.github.jordonbc.OpenVCS.yml; \ fi fix: diff --git a/README.md b/README.md index 30a7aad5..a9a4e3a7 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ cargo tauri dev ### Flatpak -Flatpak packaging exists under `packaging/flatpak/`. Stable-channel Flatpak builds may be published, but they are provided as experimental test builds rather than a recommended install path. See the [Flatpak](#flatpak) section before relying on it for regular use. +Flatpak packaging lives in the sibling [`Open-VCS/flathub`](https://github.com/Open-VCS/flathub) repo. Stable-channel Flatpak builds may be published, but they are provided as experimental test builds rather than a recommended install path. > [!NOTE] > Desktop builds currently continue to use the legacy shared `OpenVCS` configuration and plugin directories. @@ -245,7 +245,6 @@ flowchart LR ├── Backend/ # Rust + Tauri backend, native logic, and app entry point ├── Frontend/ # TypeScript + Vite frontend ├── docs/ # UX, plugin, architecture, and packaging documentation -├── packaging/flatpak/ # Experimental Flatpak manifests and notes ├── scripts/ # Build and plugin-materialisation helpers ├── Cargo.toml # Rust workspace manifest ├── Justfile # Common build/test/fix commands @@ -306,11 +305,7 @@ These commands wrap the Tauri build flow and set `NO_STRIP=true` to avoid AppIma ## Flatpak -A Flatpak manifest exists under: - -```text -packaging/flatpak/ -``` +A Flatpak manifest is maintained in the [`Open-VCS/flathub`](https://github.com/Open-VCS/flathub) repository. The stable release pipeline builds and deploys updates automatically. | Limitation | Impact | | ------------------------------------------ | ----------------------------------------------------------------------- | @@ -320,9 +315,7 @@ packaging/flatpak/ In short: Flatpak users are helping test the packaging path. Expect rough edges. -For local Flatpak build notes, see: - -[packaging/flatpak/README.md](packaging/flatpak/README.md) +For local Flatpak builds, clone `Open-VCS/flathub` as a sibling directory and run `just build-flatpak` from this directory. --- diff --git a/packaging/flatpak/README.md b/packaging/flatpak/README.md deleted file mode 100644 index a2db0002..00000000 --- a/packaging/flatpak/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Flatpak (local builds) - -This repo includes a starter Flatpak manifest for local development builds: - -- `packaging/flatpak/io.github.jordonbc.OpenVCS.yml` - -## Build + run - -From the repo root: - -```bash -flatpak install -y flathub org.gnome.Platform//49 org.gnome.Sdk//49 -flatpak install -y flathub org.freedesktop.Sdk.Extension.rust-stable//25.08 -flatpak install -y flathub org.freedesktop.Sdk.Extension.rust-stable//24.08 -flatpak install -y flathub org.freedesktop.Sdk.Extension.node24//25.08 - -cd Frontend && npm ci && npm run build && cd .. - -flatpak-builder --force-clean --user --install build-flatpak packaging/flatpak/io.github.jordonbc.OpenVCS.yml -flatpak run io.github.jordonbc.OpenVCS -``` - -## Notes - -- Flatpak packaging remains stable-only and intentionally keeps the plain `OpenVCS` app identity. -- The manifest expects the frontend to already be built at `Frontend/dist`. -- It exports `OPENVCS_FLATPAK=1` so `Backend/build.rs` disables the in-app updater (Flatpak apps update via Flatpak). -- It uses `org.freedesktop.Sdk.Extension.rust-stable` for `cargo`/`rustc` and `org.freedesktop.Sdk.Extension.node24` for `npm` inside the Flatpak build environment. On Flathub, `node24` is currently published for the `24.08` and `25.08` branches. -- The manifest's build-commands run `ensure-built-in-plugins.js` to materialize built-in plugin directories from `openvcs.plugins.json` and bundle the Node runtime, then install them into the Flatpak. -- For Flathub, you should pin sources (tag/commit) and vendor/pin dependencies so builds don't require network access. diff --git a/packaging/flatpak/io.github.jordonbc.OpenVCS.desktop b/packaging/flatpak/io.github.jordonbc.OpenVCS.desktop deleted file mode 100644 index f0ea051b..00000000 --- a/packaging/flatpak/io.github.jordonbc.OpenVCS.desktop +++ /dev/null @@ -1,9 +0,0 @@ -[Desktop Entry] -Type=Application -Name=OpenVCS -Comment=A simple, cross-platform GUI for Git. -Exec=openvcs -Icon=io.github.jordonbc.OpenVCS -Terminal=false -Categories=Development;RevisionControl; -Keywords=git;vcs;version control; diff --git a/packaging/flatpak/io.github.jordonbc.OpenVCS.metainfo.xml b/packaging/flatpak/io.github.jordonbc.OpenVCS.metainfo.xml deleted file mode 100644 index 4ca2915f..00000000 --- a/packaging/flatpak/io.github.jordonbc.OpenVCS.metainfo.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - io.github.jordonbc.OpenVCS - OpenVCS - A simple, cross-platform GUI for Git. - CC0-1.0 - GPL-3.0-or-later - - Jordon Brooks - - https://bbgames.dev - https://github.com/Jordonbc/OpenVCS/issues - - OpenVCS is a lightweight, highly customizable Git GUI built with Rust and Tauri. - - io.github.jordonbc.OpenVCS.desktop - - openvcs - - diff --git a/packaging/flatpak/io.github.jordonbc.OpenVCS.yml b/packaging/flatpak/io.github.jordonbc.OpenVCS.yml deleted file mode 100644 index 80ca3cdb..00000000 --- a/packaging/flatpak/io.github.jordonbc.OpenVCS.yml +++ /dev/null @@ -1,51 +0,0 @@ -app-id: io.github.jordonbc.OpenVCS -runtime: org.gnome.Platform -runtime-version: "49" -sdk: org.gnome.Sdk -sdk-extensions: - - org.freedesktop.Sdk.Extension.rust-stable - - org.freedesktop.Sdk.Extension.node24 - -command: openvcs - -finish-args: - - --share=ipc - - --share=network - - --socket=wayland - - --socket=fallback-x11 - - --device=dri - - --talk-name=org.freedesktop.portal.Desktop - - --talk-name=org.freedesktop.portal.FileChooser - - --talk-name=org.freedesktop.portal.OpenURI - -modules: - - name: openvcs - buildsystem: simple - build-options: - append-path: /usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/node24/bin - env: - OPENVCS_FLATPAK: "1" - build-args: - - --share=network - sources: - - type: dir - path: ../.. - skip: - - .flatpak-builder - - Frontend/node_modules - - target - build-commands: - - test -f Frontend/dist/index.html - - cargo build --release --features tauri/custom-protocol --manifest-path Backend/Cargo.toml - - node Backend/scripts/ensure-built-in-plugins.js - - install -Dm755 target/release/openvcs /app/bin/openvcs - - install -d /app/bin/built-in-plugins - - cp -a target/openvcs/built-in-plugins/. /app/bin/built-in-plugins/ - - install -d /app/bin/node-runtime - - install -Dm755 target/openvcs/node-runtime/node /app/bin/node-runtime/ - - install -Dm644 packaging/flatpak/io.github.jordonbc.OpenVCS.desktop /app/share/applications/io.github.jordonbc.OpenVCS.desktop - - install -Dm644 packaging/flatpak/io.github.jordonbc.OpenVCS.metainfo.xml /app/share/metainfo/io.github.jordonbc.OpenVCS.metainfo.xml - - install -Dm644 Backend/icons/32x32.png /app/share/icons/hicolor/32x32/apps/io.github.jordonbc.OpenVCS.png - - install -Dm644 Backend/icons/64x64.png /app/share/icons/hicolor/64x64/apps/io.github.jordonbc.OpenVCS.png - - install -Dm644 Backend/icons/128x128.png /app/share/icons/hicolor/128x128/apps/io.github.jordonbc.OpenVCS.png - - install -Dm644 Backend/icons/128x128@2x.png /app/share/icons/hicolor/256x256/apps/io.github.jordonbc.OpenVCS.png diff --git a/scripts/update-flathub.js b/scripts/update-flathub.js new file mode 100644 index 00000000..5c8254d0 --- /dev/null +++ b/scripts/update-flathub.js @@ -0,0 +1,113 @@ +#!/usr/bin/env node +// Copyright © 2025-2026 OpenVCS Contributors +// SPDX-License-Identifier: GPL-3.0-or-later + +/** + * Updates the Flathub manifest repo for a new release. + * + * Usage: + * node scripts/update-flathub.js + * + * Path to the checked-out flathub repo + * Semver string, e.g. "0.5.0" + * Full git commit hash of the release + * + * What it does: + * 1. Bumps tag + commit in the main repo git sources in the YAML manifest. + * 2. Adds a release entry to the AppStream metainfo XML. + * 3. Prints a summary of changes. + */ + +const fs = require('fs'); +const path = require('path'); + +// ---- config ---- + +const MAIN_REPO_URL = 'https://github.com/Open-VCS/OpenVCS.git'; + +// ---- helpers ---- + +function parseArgs() { + const [, , flathubDir, version, commit] = process.argv; + if (!flathubDir || !version || !commit) { + console.error('Usage: node scripts/update-flathub.js '); + process.exit(1); + } + return { flathubDir, version, commit, tag: `openvcs-v${version}` }; +} + +function updateManifest(path, { tag, commit }) { + let yaml = fs.readFileSync(path, 'utf8'); + + // Track whether any replacements were made. + let matched = false; + yaml = yaml.replace( + new RegExp( + `(\\s+url: ${escapeRegex(MAIN_REPO_URL)}\\n)(\\s+)tag: .*\\n(\\s+)commit: .*\\n(\\s+)dest: \\.`, + 'g' + ), + (...args) => { + matched = true; + const [, urlLine, ws1, ws2, ws3] = args; + return `${urlLine}${ws1}tag: ${tag}\n${ws2}commit: ${commit}\n${ws3}dest: .`; + } + ); + + if (!matched) { + console.error(`ERROR: no match for "${MAIN_REPO_URL}" in manifest — manifest format may have changed`); + process.exit(1); + } + + fs.writeFileSync(path, yaml, 'utf8'); + console.log(` → Bumped tag → ${tag}, commit → ${commit.slice(0, 12)}…`); +} + +function updateMetainfo(path, { version }) { + const today = new Date().toISOString().slice(0, 10); + let xml = fs.readFileSync(path, 'utf8'); + + // Skip if a release for this version already exists (re-run safety). + if (new RegExp(`release version="${escapeRegex(version)}"`).test(xml)) { + console.log(` → Release v${version} already in metainfo, skipping`); + return; + } + + const releaseEntry = [ + ` `, + ` `, + ` Release ${version}`, + ` `, + ` `, + ].join('\n'); + + // Insert after the opening tag (newest first) + const before = xml; + xml = xml.replace( + /(\s*\s*\n)/, + `$1${releaseEntry}\n` + ); + + if (xml === before) { + console.error('ERROR: element not found in metainfo XML — cannot insert release entry'); + process.exit(1); + } + + fs.writeFileSync(path, xml, 'utf8'); + console.log(` → Added metainfo release entry for v${version} (${today})`); +} + +function escapeRegex(s) { + return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +// ---- main ---- + +const args = parseArgs(); +const { flathubDir, version } = args; + +console.log(`Updating Flathub manifest in ${flathubDir}:`); + +updateManifest(path.join(flathubDir, 'io.github.jordonbc.OpenVCS.yml'), args); +updateMetainfo(path.join(flathubDir, 'io.github.jordonbc.OpenVCS.metainfo.xml'), { version }); + +console.log('Done.');
OpenVCS is a lightweight, highly customizable Git GUI built with Rust and Tauri.
Release ${version}