From 0dbe5d7b626dfbbf1ca91fadcb4293ee4cf8e569 Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Sun, 2 Aug 2026 20:02:44 -0500 Subject: [PATCH] CI: Build and deploy a Flatpak --- .github/workflows/flatpak.yml | 200 +++++++++++++++++++++++++ README.md | 8 +- flatpak/com.igalia.wig.WPE.yaml | 72 +++++++++ flatpak/com.igalia.wig.yaml | 61 ++++++++ flatpak/webkit-empty-linked-into.patch | 12 ++ 5 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/flatpak.yml create mode 100644 flatpak/com.igalia.wig.WPE.yaml create mode 100644 flatpak/com.igalia.wig.yaml create mode 100644 flatpak/webkit-empty-linked-into.patch diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml new file mode 100644 index 0000000..67efaa6 --- /dev/null +++ b/.github/workflows/flatpak.yml @@ -0,0 +1,200 @@ +name: Flatpak + +on: + push: + branches: + - main + pull_request: + +jobs: + check-wpe-inputs: + runs-on: ubuntu-latest + outputs: + oci-repository: ${{ steps.repository.outputs.oci-repository }} + pages-url: ${{ steps.repository.outputs.pages-url }} + wpe: ${{ steps.filter.outputs.wpe }} + steps: + - uses: actions/checkout@v6 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + wpe: + - 'flatpak/com.igalia.wig.WPE.yaml' + - 'flatpak/webkit-empty-linked-into.patch' + + - name: Resolve repository names + id: repository + shell: bash + run: | + repository="${GITHUB_REPOSITORY,,}" + owner="${GITHUB_REPOSITORY_OWNER,,}" + echo "oci-repository=$owner/wig-flatpak" >> "$GITHUB_OUTPUT" + echo "pages-url=https://$owner.github.io/${repository#*/}" >> "$GITHUB_OUTPUT" + + build-wpe-flatpak: + runs-on: [self-hosted, x64] + needs: check-wpe-inputs + # Never run a fork's pull request on the self-hosted runner. Skipping this + # is handled by build-wig-flatpak, which then builds against the published + # base app instead of one built here. + if: >- + needs.check-wpe-inputs.outputs.wpe == 'true' && + (github.event_name == 'push' || + github.event.pull_request.head.repo.full_name == github.repository) + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + + - name: Install build dependencies + run: | + flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + flatpak-builder --user --install-deps-from=flathub --install-deps-only \ + _flatpak-build flatpak/com.igalia.wig.WPE.yaml + + - name: Build WPE + run: | + flatpak-builder --user --force-clean --repo=_flatpak-repo \ + _flatpak-build flatpak/com.igalia.wig.WPE.yaml + + - name: Create bundle + run: | + flatpak build-bundle _flatpak-repo wpe-base.flatpak \ + --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo \ + com.igalia.wig.WPE master + + - name: Upload bundle + uses: actions/upload-artifact@v4 + with: + name: wpe-base-x86_64.flatpak + path: wpe-base.flatpak + if-no-files-found: error + + build-wig-flatpak: + runs-on: ubuntu-latest + container: + image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-50 + options: --privileged + volumes: + # Workaround cross-device hardlinks + - /var/lib/flatpak + needs: + - check-wpe-inputs + - build-wpe-flatpak + if: >- + always() && + needs.check-wpe-inputs.result == 'success' && + (needs.build-wpe-flatpak.result == 'success' || needs.build-wpe-flatpak.result == 'skipped') + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + + - name: Download WPE bundle + if: needs.build-wpe-flatpak.result == 'success' + uses: actions/download-artifact@v4 + with: + name: wpe-base-x86_64.flatpak + + - name: Install WPE base app + if: needs.build-wpe-flatpak.result == 'success' + run: flatpak install --system --noninteractive --assumeyes --bundle wpe-base.flatpak + + - name: Install published WPE base app + if: needs.build-wpe-flatpak.result == 'skipped' + env: + PAGES_URL: ${{ needs.check-wpe-inputs.outputs.pages-url }} + run: | + flatpak remote-add --system --if-not-exists --from wig "$PAGES_URL/wig.flatpakrepo" + flatpak install --system --noninteractive --assumeyes wig com.igalia.wig.WPE//50 + + - name: Build Wig + uses: flatpak/flatpak-github-actions/flatpak-builder@v6 + with: + manifest-path: flatpak/com.igalia.wig.yaml + bundle: wig.flatpak + cache: false + + publish-flatpaks: + runs-on: ubuntu-latest + needs: + - check-wpe-inputs + - build-wig-flatpak + if: github.event_name == 'push' + permissions: + contents: read + packages: write + pages: write + id-token: write + concurrency: + group: aetherpak-publish-${{ github.repository }} + cancel-in-progress: false + env: + # FIXME: This should be picked up already. + AETHERPAK_GPG_KEY_PASSPHRASE: ${{ secrets.GPG_KEY_PASSPHRASE }} + environment: + name: github-pages + url: ${{ steps.deploy.outputs.page_url }} + steps: + - uses: actions/checkout@v6 + + - name: Download Flatpak bundles + uses: actions/download-artifact@v4 + with: + pattern: '*.flatpak' + path: bundles + merge-multiple: true + + # FIXME: aetherpak/actions/publish wrapper references its sub-actions with + # relative paths, which a composite action can only resolve inside its own + # checkout, so call publish-oci and publish-site directly instead. + - name: Push Flatpaks to the OCI registry + uses: aetherpak/actions/publish-oci@v3.11.2 + with: + bundle-path: bundles/*.flatpak + oci-repository: ${{ needs.check-wpe-inputs.outputs.oci-repository }} + records-dir: _records + signing: gpg + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg-private-key-passphrase: ${{ secrets.GPG_KEY_PASSPHRASE }} + + - name: Build the Flatpak repository site + uses: aetherpak/actions/publish-site@v3.11.2 + with: + records-dir: _records + oci-repository: ${{ needs.check-wpe-inputs.outputs.oci-repository }} + pages-url: ${{ needs.check-wpe-inputs.outputs.pages-url }} + site-dir: _site + landing-page: false + remote-name: wig + signing: gpg + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg-private-key-passphrase: ${{ secrets.GPG_KEY_PASSPHRASE }} + # Upload the site ourselves, once the refs below are corrected. + upload-pages-artifact: false + + # FIXME: aetherpak points each .flatpakref at the registry (oci+https://ghcr.io/…), + # but flatpak enumerates an OCI remote through an index endpoint that only + # Pages serves, so installing a ref fails with "No such ref". The generated + # .flatpakrepo already uses the Pages URL; make the refs agree. + - name: Point the flatpakrefs at the Pages index + env: + PAGES_URL: ${{ needs.check-wpe-inputs.outputs.pages-url }} + run: | + set -euo pipefail + shopt -s nullglob + for ref in _site/refs/*.flatpakref; do + sed -i "s|^Url=oci+.*|Url=oci+$PAGES_URL|" "$ref" + echo "--- $ref" + grep '^Url=' "$ref" + done + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v5 + with: + path: _site + + - name: Deploy GitHub Pages + id: deploy + uses: actions/deploy-pages@v5 diff --git a/README.md b/README.md index 160216f..98a14bc 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The user interface is implemented using GTK and Libadwaita and includes common w - wpe-webkit-2.0 (>= 2.51.3) - libadwaita-1 (>= 1.6) -## Building and Installation +## Building This project uses the [Meson](https://mesonbuild.com) build system and follows standard workflow: @@ -33,6 +33,12 @@ meson compile -C builddir meson install -C builddir ``` +## Installing the Flatpak + +```sh +flatpak install --user https://igalia.github.io/wig/refs/com.igalia.wig-master.flatpakref +``` + ## Usage ```sh diff --git a/flatpak/com.igalia.wig.WPE.yaml b/flatpak/com.igalia.wig.WPE.yaml new file mode 100644 index 0000000..a808f58 --- /dev/null +++ b/flatpak/com.igalia.wig.WPE.yaml @@ -0,0 +1,72 @@ +id: com.igalia.wig.WPE +branch: master +runtime: org.gnome.Platform +runtime-version: '50' +sdk: org.gnome.Sdk +separate-locales: false +sdk-extensions: + - org.freedesktop.Sdk.Extension.llvm22 +build-options: + append-path: /usr/lib/sdk/llvm22/bin + prepend-ld-library-path: /usr/lib/sdk/llvm22/lib + strip: true + no-debuginfo: true +command: /app/libexec/wpe-webkit-2.0/MiniBrowser + +modules: + - name: unifdef + no-autogen: true + build-options: + cflags: -std=gnu17 + make-install-args: [prefix=/app] + cleanup: + - '*' + sources: + - type: archive + url: https://dotat.at/prog/unifdef/unifdef-2.12.tar.gz + sha256: fba564a24db7b97ebe9329713ac970627b902e5e9e8b14e19e024eb6e278d10b + + - name: libevent + config-opts: + - --disable-static + cleanup: + - /bin + - /lib/pkgconfig + - /lib/*.la + - /include + sources: + - type: archive + url: https://github.com/libevent/libevent/releases/download/release-2.1.13-stable/libevent-2.1.13-stable.tar.gz + sha256: f7e9383b8c0baa81b687e5b5eecc01beefaf1b19b64151d95ed61647fe7a315c + + - name: webkitwpe + buildsystem: cmake-ninja + config-opts: + - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_C_COMPILER=clang + - -DCMAKE_CXX_COMPILER=clang++ + - -DCMAKE_LINKER_TYPE=LLD + - -DPORT=WPE + + - -DENABLE_WPE_LEGACY_API=OFF + - -DENABLE_WPE_PLATFORM=ON + - -DENABLE_WPE_PLATFORM_DRM=OFF + - -DENABLE_WPE_PLATFORM_HEADLESS=OFF + + # These are marked experimental but we want to test them. + - -DENABLE_WEB_RTC=ON + - -DENABLE_WK_WEB_EXTENSIONS=ON + + # Unbuilt dependencies. + - -DENABLE_SPEECH_SYNTHESIS=OFF + - -DUSE_LIBBACKTRACE=OFF + + - -DENABLE_INTROSPECTION=OFF + + - -DENABLE_MINIBROWSER=ON + sources: + - type: git + url: https://github.com/WebKit/WebKit.git + commit: 2f66f5ed23f9a3ce154e7b5745861f76eeda67f0 + - type: patch + path: webkit-empty-linked-into.patch diff --git a/flatpak/com.igalia.wig.yaml b/flatpak/com.igalia.wig.yaml new file mode 100644 index 0000000..fb221e1 --- /dev/null +++ b/flatpak/com.igalia.wig.yaml @@ -0,0 +1,61 @@ +id: com.igalia.wig +branch: master +runtime: org.gnome.Platform +runtime-version: '50' +sdk: org.gnome.Sdk +base: com.igalia.wig.WPE +base-version: master +command: wig + +finish-args: + - --device=dri + - --filesystem=xdg-download + - --share=ipc + - --share=network + - --socket=fallback-x11 + - --socket=pulseaudio + - --socket=wayland + +cleanup: + - /include + - /lib/pkgconfig + +modules: + - name: template-glib + buildsystem: meson + cleanup: + - /include + - /lib/pkgconfig + config-opts: + - --buildtype=release + - -Dintrospection=disabled + - -Dvapi=false + sources: + - type: archive + url: https://github.com/GNOME/template-glib/archive/d853e3fcf16838993d2de4ce5fc213edfe63818d.tar.gz + sha256: 91a4670a2039f4db735f2b2218debf680d41a9d5001efa3e25f146f23edb2f7d + + - name: wpe-platform-gtk + buildsystem: meson + cleanup: + - /include + - /lib/pkgconfig + config-opts: + - --buildtype=release + sources: + - type: git + url: https://github.com/Igalia/wpe-platform-gtk.git + branch: main + commit: be2f50845a1bb4d55b4a2e20142b84a32974d585 + + - name: wig + buildsystem: meson + config-opts: + - --buildtype=release + sources: + - type: dir + path: .. + skip: + - subprojects/template-glib + - subprojects/wpe-platform-gtk + diff --git a/flatpak/webkit-empty-linked-into.patch b/flatpak/webkit-empty-linked-into.patch new file mode 100644 index 0000000..c59e32a --- /dev/null +++ b/flatpak/webkit-empty-linked-into.patch @@ -0,0 +1,12 @@ +diff --git a/Source/cmake/WebKitMacros.cmake b/Source/cmake/WebKitMacros.cmake +--- a/Source/cmake/WebKitMacros.cmake ++++ b/Source/cmake/WebKitMacros.cmake +@@ -551,7 +551,7 @@ macro(_WEBKIT_TARGET_LINK_FRAMEWORK _target) + get_property(_linked_into GLOBAL PROPERTY ${framework}_LINKED_INTO) + + # See if the target is linking a framework that the specified framework is already linked into +- if ((NOT _linked_into) OR (${framework} STREQUAL ${_linked_into}) OR (NOT ${_linked_into} IN_LIST ${_target}_FRAMEWORKS)) ++ if ((NOT _linked_into) OR ("${framework}" STREQUAL "${_linked_into}") OR (NOT "${_linked_into}" IN_LIST ${_target}_FRAMEWORKS)) + list(APPEND ${_target}_PRIVATE_LIBRARIES WebKit::${framework}) + + # The WebKit:: alias targets do not propagate OBJECT libraries so the