Move to Gitea: install scripts, links and a release script that builds the DEBs, RPMs, Arch package and a new AppImage

This commit is contained in:
ZacharyZhang-NY committed 2026-10-11 01:40:28 -04:00
1 parent 4c7d98b17f
commit 1fcbec84e9
17 files changed
+169 -124

No files matched your search

-95
View File
@@ -1,95 +0,0 @@
# A version tag builds the four packages, each on its own system, and publishes them.
name: Release
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
version:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
# The tag must name the version each build file carries.
- run: |
v=${GITHUB_REF_NAME#v}
grep -qF "project(omaphoto VERSION $v " CMakeLists.txt || { echo "CMakeLists.txt is not $v"; exit 1; }
grep -qxF "pkgver=$v" packaging/arch/PKGBUILD || { echo "PKGBUILD is not $v"; exit 1; }
grep -qF "version = \"$v\";" flake.nix || { echo "flake.nix is not $v"; exit 1; }
deb:
needs: version
runs-on: ubuntu-24.04
# One DEB per Ubuntu LTS: each names its own libraries.
strategy:
matrix:
include:
- codename: noble
base: ubuntu:24.04
- codename: resolute
base: ubuntu:26.04
steps:
- uses: actions/checkout@v7
# The dev image carries ONNX Runtime, its notices and the model.
- run: docker build -t omaphoto-dev --build-arg BASE=${{ matrix.base }} -f Dockerfile.dev .
- run: |
docker run --rm -u "$(id -u):$(id -g)" -e HOME=/tmp -v "$PWD:/src" -w /src omaphoto-dev sh -c '
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \
-DOMAPHOTO_BUNDLE_ORT=ON -DOMAPHOTO_MODEL=/usr/local/share/omaphoto/u2net.onnx &&
cmake --build build --target omaphoto && cd build && cpack -G DEB'
mv build/omaphoto_*.deb omaphoto-${{ matrix.codename }}_amd64.deb
- uses: actions/upload-artifact@v7
with:
name: deb-${{ matrix.codename }}
path: omaphoto-${{ matrix.codename }}_amd64.deb
rpm:
needs: version
runs-on: ubuntu-24.04
# One RPM per Fedora release: each names its own LibRaw.
strategy:
matrix:
release: [43, 44]
steps:
- uses: actions/checkout@v7
- run: docker build -t omaphoto-fedora --build-arg RELEASE=${{ matrix.release }} scripts/distro/fedora
- run: |
docker run --rm -u "$(id -u):$(id -g)" -e HOME=/tmp -v "$PWD:/src" -w /src omaphoto-fedora sh -c '
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \
-DOMAPHOTO_BUNDLE_ORT=ON -DOMAPHOTO_MODEL=/usr/local/share/omaphoto/u2net.onnx &&
cmake --build build --target omaphoto && cd build && cpack -G RPM'
mv build/omaphoto-*.x86_64.rpm omaphoto-fc${{ matrix.release }}.x86_64.rpm
- uses: actions/upload-artifact@v7
with:
name: rpm-fc${{ matrix.release }}
path: omaphoto-fc${{ matrix.release }}.x86_64.rpm
arch:
needs: version
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- run: docker build -t omaphoto-arch scripts/distro/arch
# makepkg refuses root; a user of the runner's id builds.
- run: |
docker run --rm -v "$PWD:/src" omaphoto-arch sh -c "
useradd -u $(id -u) builder && chown -R builder /src &&
su builder -c 'cd /src/packaging/arch && makepkg -f'"
mv packaging/arch/omaphoto-[0-9]*-x86_64.pkg.tar.zst omaphoto-x86_64.pkg.tar.zst
- uses: actions/upload-artifact@v7
with:
name: arch
path: omaphoto-x86_64.pkg.tar.zst
publish:
needs: [deb, rpm, arch]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- uses: actions/download-artifact@v8
with:
merge-multiple: true
path: packages
- working-directory: packages
run: sha256sum omaphoto-noble_amd64.deb omaphoto-resolute_amd64.deb omaphoto-fc43.x86_64.rpm omaphoto-fc44.x86_64.rpm omaphoto-x86_64.pkg.tar.zst > SHA256SUMS
- env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "$GITHUB_REF_NAME" packages/* --title "OmaPhoto ${GITHUB_REF_NAME#v}" \
--notes "Install with the script for your system: see the README's Install section."
+4
View File
@@ -7,3 +7,7 @@
/packaging/arch/u2net.onnx /packaging/arch/u2net.onnx
/Compositor-Ref/ /Compositor-Ref/
/build-appimage/
/AppDir/
/*.AppImage
/release/
+2 -2
View File
@@ -15,7 +15,7 @@ To make or change an image in a `.comp` project, the source is not needed: read
- The repository root: the app. C++20, Qt 6 Widgets (floor Qt 6.4), CMake, Qt Test. CPU raster only: QPainter plus the C kernels in `kernels/`, copied unchanged from Compositor's `Compositor/Rendering/*.c` and compiled in place. - The repository root: the app. C++20, Qt 6 Widgets (floor Qt 6.4), CMake, Qt Test. CPU raster only: QPainter plus the C kernels in `kernels/`, copied unchanged from Compositor's `Compositor/Rendering/*.c` and compiled in place.
- `packaging/`: the desktop entry, MIME type, icons (Compositor's app icon) and the Arch `PKGBUILD`; `flake.nix` at the root for NixOS. - `packaging/`: the desktop entry, MIME type, icons (Compositor's app icon) and the Arch `PKGBUILD`; `flake.nix` at the root for NixOS.
- `scripts/install/`: one install script per distribution family, each fetching the latest release's package. - `scripts/install/`: one install script per distribution family, each fetching the latest release's package.
- `.github/workflows/release.yml`: a `v*` tag builds the DEBs, the RPMs and the Arch package and publishes them. - `scripts/release.sh`: builds a tag's DEBs, RPMs, Arch package and AppImage in Docker and publishes them as a release on the project's Gitea, https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto (the GitHub repository is gone; GitHub suspended the account in 2026-10).
- `docs/acceptance.md`: the MVP acceptance table, its screenshots in `docs/acceptance/`. - `docs/acceptance.md`: the MVP acceptance table, its screenshots in `docs/acceptance/`.
- `TASKS.md`: ordered task list and progress truth. Its entries before 11.4b speak of the port's old home, `linux/` inside Compositor's repository. - `TASKS.md`: ordered task list and progress truth. Its entries before 11.4b speak of the port's old home, `linux/` inside Compositor's repository.
@@ -202,7 +202,7 @@ Deliberate name breaks: `MetalBrushCoverage` → `BrushCoverage`, `MetalLayerEff
- Omarchy theme: `src/UI/OmarchyTheme` reads `~/.local/state/omarchy/current/theme/colors.toml` (Omarchy 4.x: flat `key = "value"` lines, `mode` dark or light, the twenty-two stock themes' keys required, `orange` optional and `yellow` its stand-in) into `OmarchyColors`, applies them as the application palette (Window and Text from `background` and `foreground`, Base from `darker_background`, Button from `lighter_background`, Highlight and Link from `accent` with the background as highlighted text, PlaceholderText from `dark_foreground`, BrightText from `orange` or `yellow`, Mid from `muted`, the disabled roles from `muted`) and sets the Fusion style, which follows a palette on every desktop where a platform style does not; no stylesheet is needed. Keys and values read in double or single quotes. A missing key, or a recognised key whose value is bare or half-quoted or no `#rrggbb`, refuses the file with the key's name; a file that exists but cannot be opened, or sits behind a folder that cannot be searched (`stat` fails other than `ENOENT`), is refused too; either way the app keeps the palette it has and logs a warning, where an absent file means the built-in dark, Swift's grays, installed before the first load. `omarchy-theme-set` removes `current/theme`, moves `next-theme` in and writes `theme.name`, so the watcher holds `current/`, `current/theme` and the file, adds them back after each load (a removed path leaves a `QFileSystemWatcher`) and renews the file's watch every load (it follows the inode, which an atomic replacement swaps), watches the nearest ancestor the watcher accepts while `current/` is missing or barred, letting it go once the directory is watched, and loads once 100 ms after the last event. A read that stops short (an error, or fewer bytes than the file holds) is refused like a malformed file. Each load logs the theme's name and mode on `omaphoto.app`. `main` makes the theme before the window. Widgets take colours from the palette, never from literals; the canvas keeps Swift's document grays. The UI font stays Qt's default: `omarchy font current` is not followed. - Omarchy theme: `src/UI/OmarchyTheme` reads `~/.local/state/omarchy/current/theme/colors.toml` (Omarchy 4.x: flat `key = "value"` lines, `mode` dark or light, the twenty-two stock themes' keys required, `orange` optional and `yellow` its stand-in) into `OmarchyColors`, applies them as the application palette (Window and Text from `background` and `foreground`, Base from `darker_background`, Button from `lighter_background`, Highlight and Link from `accent` with the background as highlighted text, PlaceholderText from `dark_foreground`, BrightText from `orange` or `yellow`, Mid from `muted`, the disabled roles from `muted`) and sets the Fusion style, which follows a palette on every desktop where a platform style does not; no stylesheet is needed. Keys and values read in double or single quotes. A missing key, or a recognised key whose value is bare or half-quoted or no `#rrggbb`, refuses the file with the key's name; a file that exists but cannot be opened, or sits behind a folder that cannot be searched (`stat` fails other than `ENOENT`), is refused too; either way the app keeps the palette it has and logs a warning, where an absent file means the built-in dark, Swift's grays, installed before the first load. `omarchy-theme-set` removes `current/theme`, moves `next-theme` in and writes `theme.name`, so the watcher holds `current/`, `current/theme` and the file, adds them back after each load (a removed path leaves a `QFileSystemWatcher`) and renews the file's watch every load (it follows the inode, which an atomic replacement swaps), watches the nearest ancestor the watcher accepts while `current/` is missing or barred, letting it go once the directory is watched, and loads once 100 ms after the last event. A read that stops short (an error, or fewer bytes than the file holds) is refused like a malformed file. Each load logs the theme's name and mode on `omaphoto.app`. `main` makes the theme before the window. Widgets take colours from the palette, never from literals; the canvas keeps Swift's document grays. The UI font stays Qt's default: `omarchy font current` is not followed.
- No updater. Distro packages own updates. - No updater. Distro packages own updates.
- Custom cursors (`QCursor` pixmaps) come out garbled on the hardware cursor path with NVIDIA and Hyprland at a fractional scale; theme cursors render correctly (issue #9, hyprwm/Hyprland#16413). README gives the software-cursor setting; the app keeps its cursors and does not guess at drivers (the user's decision, 13.1). - Custom cursors (`QCursor` pixmaps) come out garbled on the hardware cursor path with NVIDIA and Hyprland at a fractional scale; theme cursors render correctly (issue #9, hyprwm/Hyprland#16413). README gives the software-cursor setting; the app keeps its cursors and does not guess at drivers (the user's decision, 13.1).
- Distribution (11.4b): releases live on GitHub under fixed asset names (`omaphoto-noble_amd64.deb`, `omaphoto-resolute_amd64.deb`, `omaphoto-fc43.x86_64.rpm`, `omaphoto-fc44.x86_64.rpm`, `omaphoto-x86_64.pkg.tar.zst`; 1.0.0 had one DEB, `omaphoto_amd64.deb`, and 1.0.0 to 1.2.3 one RPM, `omaphoto.x86_64.rpm`) with `SHA256SUMS`, so `releases/latest/download/<name>` always reaches the newest. `scripts/install/arch.sh` reads `/etc/os-release` (`ID` or `ID_LIKE`; Omarchy says `ID_LIKE=arch`), `fedora.sh` its `ID` or `ID_LIKE` and `VERSION_ID`, taking the RPM of release 43 or 44 and refusing any other, since each names its release's LibRaw (`libraw_r.so.23` on 43, `.25` on 44; found in 12.16, when 1.2.3's single RPM from Fedora 43 would not install on 44), and `ubuntu.sh` its `UBUNTU_CODENAME`, which Ubuntu's derivatives set to their base: each DEB names its release's Qt libraries (24.04's carry a `t64` suffix that 26.04's drop, and Debian 13 has neither), so the release carries one DEB per LTS, built on it (`Dockerfile.dev` takes the base as `BASE`), and the script takes the one whose codename matches, `noble` or `resolute`, refusing any other. Each refuses another system or another machine than x86_64, verify the package against the sums and install it with apt, dnf or pacman under sudo, so the package manager resolves dependencies; apt reads the file as its own user, so the download folder is opened to it. Fedora's script names RPM Fusion's `libheif-freeworld` when it is missing, since Fedora's libheif decodes no HEVC, and adds no repository itself. `nixos.sh` installs the flake at the newest release's tag, which GitHub's `releases/latest` redirect names, into the user's profile (`nix profile install`, the name every Nix still takes), so no user builds unreleased work from `main`. The README runs each script after downloading it, so the package manager's questions read the terminal and fish runs it too. `release.yml` builds each package with the command the distro checks use, the DEBs on the dev image over each base, the RPMs on Fedora 43 and 44 (`scripts/distro/fedora/Dockerfile` takes the release as `RELEASE`, 43 by default), the Arch package through `makepkg` as a user; the version is CMake's `project` version, the PKGBUILD's and the flake's, kept equal by hand, and the workflow's first job refuses a tag that names another. - Distribution (11.4b): releases live on Gitea (git.zacharyzhang.com) under fixed asset names (`omaphoto-noble_amd64.deb`, `omaphoto-resolute_amd64.deb`, `omaphoto-fc43.x86_64.rpm`, `omaphoto-fc44.x86_64.rpm`, `omaphoto-x86_64.pkg.tar.zst`, `omaphoto-x86_64.AppImage` since 1.4.5; 1.0.0 had one DEB, `omaphoto_amd64.deb`, and 1.0.0 to 1.2.3 one RPM, `omaphoto.x86_64.rpm`) with `SHA256SUMS`. Gitea has no `releases/latest/download`, so each script asks the API for the newest release's tag (`/api/v1/repos/ZacharyZhang-NY/OmaPhoto/releases/latest`) and downloads from `releases/download/<tag>/<name>`. `scripts/install/arch.sh` reads `/etc/os-release` (`ID` or `ID_LIKE`; Omarchy says `ID_LIKE=arch`), `fedora.sh` its `ID` or `ID_LIKE` and `VERSION_ID`, taking the RPM of release 43 or 44 and refusing any other, since each names its release's LibRaw (`libraw_r.so.23` on 43, `.25` on 44; found in 12.16, when 1.2.3's single RPM from Fedora 43 would not install on 44), and `ubuntu.sh` its `UBUNTU_CODENAME`, which Ubuntu's derivatives set to their base: each DEB names its release's Qt libraries (24.04's carry a `t64` suffix that 26.04's drop, and Debian 13 has neither), so the release carries one DEB per LTS, built on it (`Dockerfile.dev` takes the base as `BASE`), and the script takes the one whose codename matches, `noble` or `resolute`, refusing any other. Each refuses another system or another machine than x86_64, verify the package against the sums and install it with apt, dnf or pacman under sudo, so the package manager resolves dependencies; apt reads the file as its own user, so the download folder is opened to it. Fedora's script names RPM Fusion's `libheif-freeworld` when it is missing, since Fedora's libheif decodes no HEVC, and adds no repository itself. `nixos.sh` installs the flake at the newest release's tag (`git+https://…?ref=refs/tags/<tag>`) into the user's profile (`nix profile install`, the name every Nix still takes), so no user builds unreleased work from `main`. The README runs each script after downloading it, so the package manager's questions read the terminal and fish runs it too. `scripts/release.sh vX.Y.Z` (with `GITEA_TOKEN` set, the tag already pushed) builds each package from `git archive` of the tag with the command the distro checks use, the DEBs on the dev image over each base, the RPMs on Fedora 43 and 44 (`scripts/distro/fedora/Dockerfile` takes the release as `RELEASE`, 43 by default), the Arch package through `makepkg` as a user, the AppImage on the noble dev image (`scripts/distro/appimage`, linuxdeploy and its Qt plugin pinned by checksum; `scripts/appimage.sh` adds Qt's Wayland shell, decoration and graphics plugins and libheif's HEVC plugin, and `packaging/appimage/omaphoto.sh`, an AppRun hook, puts the AppImage's `usr/share` first on `XDG_DATA_DIRS` so the model is found, and sets `LIBHEIF_PLUGIN_PATH`), then writes `SHA256SUMS`, creates the release and uploads every file; the version is CMake's `project` version, the PKGBUILD's and the flake's, kept equal by hand, and the script refuses a tag that names another.
- Remove Background runs an open-licensed model on ONNX Runtime. - Remove Background runs an open-licensed model on ONNX Runtime.
- A `.comp` project is a directory on Linux; its layout matches the macOS package. - A `.comp` project is a directory on Linux; its layout matches the macOS package.
- Shortcuts map ⌘ to Ctrl and ⌥ to Alt. - Shortcuts map ⌘ to Ctrl and ⌥ to Alt.
+1 -1
View File
@@ -293,7 +293,7 @@ set(CPACK_PACKAGE_NAME omaphoto)
set(CPACK_PACKAGE_VENDOR "ZacharyZhang-NY") set(CPACK_PACKAGE_VENDOR "ZacharyZhang-NY")
set(CPACK_PACKAGE_CONTACT "ZacharyZhang-NY") set(CPACK_PACKAGE_CONTACT "ZacharyZhang-NY")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Layered image editing for Linux, a port of Compositor") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Layered image editing for Linux, a port of Compositor")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/ZacharyZhang-NY/OmaPhoto") set(CPACK_PACKAGE_HOMEPAGE_URL "https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto")
set(CPACK_PACKAGING_INSTALL_PREFIX /usr) set(CPACK_PACKAGING_INSTALL_PREFIX /usr)
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_SECTION graphics) set(CPACK_DEBIAN_PACKAGE_SECTION graphics)
+6 -6
View File
@@ -35,13 +35,13 @@ Each script installs the newest release. The Arch, Ubuntu and Fedora scripts dow
Arch and Omarchy: Arch and Omarchy:
```sh ```sh
curl -fsSLO https://raw.githubusercontent.com/ZacharyZhang-NY/OmaPhoto/main/scripts/install/arch.sh && bash arch.sh curl -fsSLO https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto/raw/branch/main/scripts/install/arch.sh && bash arch.sh
``` ```
Ubuntu 24.04 or 26.04 LTS and systems built on them (Linux Mint 22, Pop!_OS 24.04): Ubuntu 24.04 or 26.04 LTS and systems built on them (Linux Mint 22, Pop!_OS 24.04):
```sh ```sh
curl -fsSLO https://raw.githubusercontent.com/ZacharyZhang-NY/OmaPhoto/main/scripts/install/ubuntu.sh && bash ubuntu.sh curl -fsSLO https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto/raw/branch/main/scripts/install/ubuntu.sh && bash ubuntu.sh
``` ```
Each DEB names its Ubuntu release's libraries, so other Ubuntu releases and Debian build from source (below). Each DEB names its Ubuntu release's libraries, so other Ubuntu releases and Debian build from source (below).
@@ -49,7 +49,7 @@ Each DEB names its Ubuntu release's libraries, so other Ubuntu releases and Debi
Fedora 43 or 44: Fedora 43 or 44:
```sh ```sh
curl -fsSLO https://raw.githubusercontent.com/ZacharyZhang-NY/OmaPhoto/main/scripts/install/fedora.sh && bash fedora.sh curl -fsSLO https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto/raw/branch/main/scripts/install/fedora.sh && bash fedora.sh
``` ```
Fedora's own libheif decodes no HEVC. For HEIC import, add [RPM Fusion](https://rpmfusion.org/Configuration) and install `libheif-freeworld`; the script reminds you. Fedora's own libheif decodes no HEVC. For HEIC import, add [RPM Fusion](https://rpmfusion.org/Configuration) and install `libheif-freeworld`; the script reminds you.
@@ -57,12 +57,12 @@ Fedora's own libheif decodes no HEVC. For HEIC import, add [RPM Fusion](https://
NixOS installs the release's flake into your profile: NixOS installs the release's flake into your profile:
```sh ```sh
curl -fsSLO https://raw.githubusercontent.com/ZacharyZhang-NY/OmaPhoto/main/scripts/install/nixos.sh && bash nixos.sh curl -fsSLO https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto/raw/branch/main/scripts/install/nixos.sh && bash nixos.sh
``` ```
Or add `github:ZacharyZhang-NY/OmaPhoto/<tag>`, a release tag, as a flake input and put its `packages.x86_64-linux.default` in your configuration. Or add `git+https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto?ref=refs/tags/<tag>`, a release tag, as a flake input and put its `packages.x86_64-linux.default` in your configuration.
The packages themselves sit on the [releases page](https://github.com/ZacharyZhang-NY/OmaPhoto/releases). The packages themselves sit on the [releases page](https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto/releases). Any other x86_64 system can run the AppImage there, `omaphoto-x86_64.AppImage`: download it, `chmod +x` it and start it.
### Garbled cursors on NVIDIA with Hyprland ### Garbled cursors on NVIDIA with Hyprland
+2 -1
View File
@@ -503,7 +503,8 @@ Reviews for this section ran on codex `gpt-6.1-sol` at `max` (agent `codex-sol`)
- 13.19i review: round 1 PASS (the Qt behaviour probed on 6.4.2, 6.10.2 and 6.11.2, six mutants caught). - 13.19i review: round 1 PASS (the Qt behaviour probed on 6.4.2, 6.10.2 and 6.11.2, six mutants caught).
- 13.19j work: `versionupdate.md` gains 13.19i's blend menu fix; `v1.4.5` tagged on main and pushed; the workflow's run is checked below. - 13.19j work: `versionupdate.md` gains 13.19i's blend menu fix; `v1.4.5` tagged on main and pushed; the workflow's run is checked below.
- [ ] 13.19j Tag `v1.4.5`; the release workflow publishes every package. - [ ] 13.19j Tag `v1.4.5`; the release workflow publishes every package.
- [ ] 13.19k Live installs from GitHub in fresh containers. - 2026-10-11: GitHub suspended the account; the project moved to Gitea (git.zacharyzhang.com), the workflow became `scripts/release.sh`, and releases gain an AppImage.
- [ ] 13.19k Live installs from Gitea in fresh containers.
- [ ] 13.19l The acceptance checklist. - [ ] 13.19l The acceptance checklist.
## Skills by phase ## Skills by phase
+1 -1
View File
@@ -32,7 +32,7 @@ The screenshots come from Qt's offscreen platform, so floating panels appear wit
| Reload a project changed on disk | With unsaved edits open, another program renames a layer on disk. The app's alert asks, Revert is chosen, and the saved state shows with the new name. | [15](acceptance/15-shortcuts.png) | `ExternalChangeTests` | pass | | Reload a project changed on disk | With unsaved edits open, another program renames a layer on disk. The app's alert asks, Revert is chosen, and the saved state shows with the new name. | [15](acceptance/15-shortcuts.png) | `ExternalChangeTests` | pass |
| Follows the Omarchy theme | Starts in the built-in dark. A Catppuccin Latte `colors.toml` written while the app runs retints the window. | [16](acceptance/16-omarchy-light.png) | `OmarchyThemeTests` | pass | | Follows the Omarchy theme | Starts in the built-in dark. A Catppuccin Latte `colors.toml` written while the app runs retints the window. | [16](acceptance/16-omarchy-light.png) | `OmarchyThemeTests` | pass |
| Builds and tests on each system | The full suite, 334 binaries, passes on Ubuntu 24.04 (Qt 6.4.2), Ubuntu 26.04 (6.10.2), Arch (6.11.2), Fedora 43 and 44, and NixOS (6.11.2). Warnings count as errors. | — | `scripts/distro-check.sh` | pass | | Builds and tests on each system | The full suite, 334 binaries, passes on Ubuntu 24.04 (Qt 6.4.2), Ubuntu 26.04 (6.10.2), Arch (6.11.2), Fedora 43 and 44, and NixOS (6.11.2). Warnings count as errors. | — | `scripts/distro-check.sh` | pass |
| Packages and install scripts | Each install script runs from GitHub in a fresh container. On Ubuntu 24.04 and 26.04, Fedora 43 and 44 and Arch, it checks its package against `SHA256SUMS`, installs it and starts 1.4.5. On NixOS, `nixos.sh` resolves `v1.4.5`, builds its flake and starts 1.4.5. Debian 13 is refused, as intended. | — | `DesktopIntegrationTests`, `.github/workflows/release.yml` | pending | | Packages and install scripts | Each install script runs from Gitea in a fresh container. On Ubuntu 24.04 and 26.04, Fedora 43 and 44 and Arch, it checks its package against `SHA256SUMS`, installs it and starts 1.4.5. On NixOS, `nixos.sh` resolves `v1.4.5`, builds its flake and starts 1.4.5. Debian 13 is refused, as intended. | — | `DesktopIntegrationTests`, `scripts/release.sh` | pending |
## New in 1.4.5 ## New in 1.4.5
+1 -1
View File
@@ -7,7 +7,7 @@ An OmaPhoto project (`.comp`) is a folder of PNG layer images plus a `manifest.j
1. Open a project in OmaPhoto 1.3 or later (save a new canvas somewhere, e.g. `~/Pictures/demo.comp`), and keep it open. 1. Open a project in OmaPhoto 1.3 or later (save a new canvas somewhere, e.g. `~/Pictures/demo.comp`), and keep it open.
2. Ask an AI agent that can edit files on your computer (Claude Code, Codex and the like): 2. Ask an AI agent that can edit files on your computer (Claude Code, Codex and the like):
> Read docs/writing-comp-files.md in github.com/ZacharyZhang-NY/OmaPhoto, then design a moody night scene in ~/Pictures/demo.comp. Work in steps, one or two layers at a time. > Read docs/writing-comp-files.md in git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto, then design a moody night scene in ~/Pictures/demo.comp. Work in steps, one or two layers at a time.
3. Watch the canvas. Each time the agent writes the project, OmaPhoto reloads it, usually within half a second. 3. Watch the canvas. Each time the agent writes the project, OmaPhoto reloads it, usually within half a second.
+3
View File
@@ -0,0 +1,3 @@
# The AppImage's model, MIME data and HEVC decoder come first.
export XDG_DATA_DIRS="$APPDIR/usr/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
export LIBHEIF_PLUGIN_PATH="$APPDIR/usr/lib/libheif"
+1 -1
View File
@@ -4,7 +4,7 @@ pkgver=1.4.5
pkgrel=1 pkgrel=1
pkgdesc='Layered image editing for Linux, a port of Compositor' pkgdesc='Layered image editing for Linux, a port of Compositor'
arch=('x86_64') arch=('x86_64')
url='https://github.com/ZacharyZhang-NY/OmaPhoto' url='https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto'
license=('MIT') license=('MIT')
depends=('qt6-base' 'qt6-svg' 'qt6-imageformats' 'libheif' 'libraw' 'libde265' 'fontconfig' 'hicolor-icon-theme' 'shared-mime-info') depends=('qt6-base' 'qt6-svg' 'qt6-imageformats' 'libheif' 'libraw' 'libde265' 'fontconfig' 'hicolor-icon-theme' 'shared-mime-info')
makedepends=('cmake' 'ninja') makedepends=('cmake' 'ninja')
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Builds omaphoto-x86_64.AppImage inside the AppImage image.
set -euo pipefail
id=io.github.ZacharyZhang_NY.OmaPhoto
cmake -S . -B build-appimage -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \
-DOMAPHOTO_BUNDLE_ORT=ON -DOMAPHOTO_MODEL=/usr/local/share/omaphoto/u2net.onnx
cmake --build build-appimage --target omaphoto
rm -rf AppDir
DESTDIR="$PWD/AppDir" cmake --install build-appimage
# libheif loads its HEVC decoder as a plugin.
mkdir -p AppDir/usr/lib/libheif AppDir/apprun-hooks
cp /usr/lib/x86_64-linux-gnu/libheif/plugins/libheif-libde265.so AppDir/usr/lib/libheif/
cp packaging/appimage/omaphoto.sh AppDir/apprun-hooks/
# Qt's Wayland client needs its shell and decoration plugins.
qtplugins=/usr/lib/x86_64-linux-gnu/qt6/plugins
mkdir -p AppDir/usr/plugins
for dir in wayland-shell-integration wayland-decoration-client wayland-graphics-integration-client; do
cp -r "$qtplugins/$dir" AppDir/usr/plugins/
done
export QMAKE=/usr/lib/qt6/bin/qmake6 APPIMAGE_EXTRACT_AND_RUN=1 OUTPUT=omaphoto-x86_64.AppImage
export EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so" EXTRA_QT_MODULES=svg
linuxdeploy --appdir AppDir --plugin qt --output appimage \
--desktop-file "AppDir/usr/share/applications/$id.desktop" \
--icon-file "AppDir/usr/share/icons/hicolor/512x512/apps/$id.png" \
--deploy-deps-only AppDir/usr/lib/libheif \
--deploy-deps-only AppDir/usr/plugins/wayland-shell-integration \
--deploy-deps-only AppDir/usr/plugins/wayland-decoration-client \
--deploy-deps-only AppDir/usr/plugins/wayland-graphics-integration-client
+10
View File
@@ -0,0 +1,10 @@
# The dev image plus linuxdeploy, pinned by checksum.
ARG DEV=omaphoto-dev
FROM $DEV
RUN curl -fsSL -o /usr/local/bin/linuxdeploy \
https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20251107-1/linuxdeploy-x86_64.AppImage \
&& curl -fsSL -o /usr/local/bin/linuxdeploy-plugin-qt \
https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/1-alpha-20250213-1/linuxdeploy-plugin-qt-x86_64.AppImage \
&& echo "c20cd71e3a4e3b80c3483cef793cda3f4e990aca14014d23c544ca3ce1270b4d /usr/local/bin/linuxdeploy" | sha256sum -c - \
&& echo "15106be885c1c48a021198e7e1e9a48ce9d02a86dd0a1848f00bdbf3c1c92724 /usr/local/bin/linuxdeploy-plugin-qt" | sha256sum -c - \
&& chmod +x /usr/local/bin/linuxdeploy /usr/local/bin/linuxdeploy-plugin-qt
+9 -2
View File
@@ -1,7 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Installs OmaPhoto's latest package on Arch and Omarchy. # Installs OmaPhoto's newest package on Arch and Omarchy.
set -euo pipefail set -euo pipefail
base=https://github.com/ZacharyZhang-NY/OmaPhoto/releases/latest/download repo=https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto
# The newest release's tag, from Gitea's API.
tag=$(curl -fsSL --proto '=https' https://git.zacharyzhang.com/api/v1/repos/ZacharyZhang-NY/OmaPhoto/releases/latest | grep -o '"tag_name":"v[^"]*"' | cut -d'"' -f4) || tag=
if [ -z "$tag" ]; then
echo "No release found at $repo/releases." >&2
exit 1
fi
base=$repo/releases/download/$tag
package=omaphoto-x86_64.pkg.tar.zst package=omaphoto-x86_64.pkg.tar.zst
. /etc/os-release . /etc/os-release
case " ${ID:-} ${ID_LIKE:-} " in case " ${ID:-} ${ID_LIKE:-} " in
+9 -2
View File
@@ -1,7 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Installs OmaPhoto's latest RPM on Fedora 43 or 44. # Installs OmaPhoto's newest RPM on Fedora 43 or 44.
set -euo pipefail set -euo pipefail
base=https://github.com/ZacharyZhang-NY/OmaPhoto/releases/latest/download repo=https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto
# The newest release's tag, from Gitea's API.
tag=$(curl -fsSL --proto '=https' https://git.zacharyzhang.com/api/v1/repos/ZacharyZhang-NY/OmaPhoto/releases/latest | grep -o '"tag_name":"v[^"]*"' | cut -d'"' -f4) || tag=
if [ -z "$tag" ]; then
echo "No release found at $repo/releases." >&2
exit 1
fi
base=$repo/releases/download/$tag
. /etc/os-release . /etc/os-release
release= release=
case " ${ID:-} ${ID_LIKE:-} " in case " ${ID:-} ${ID_LIKE:-} " in
+7 -10
View File
@@ -9,14 +9,11 @@ if [ "$(uname -m)" != x86_64 ]; then
echo "OmaPhoto's flake builds for x86_64 alone." >&2 echo "OmaPhoto's flake builds for x86_64 alone." >&2
exit 1 exit 1
fi fi
# The newest release's tag, as GitHub redirects to it. repo=https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto
latest=$(curl -fsSLI --proto '=https' -o /dev/null -w '%{url_effective}' https://github.com/ZacharyZhang-NY/OmaPhoto/releases/latest) # The newest release's tag, from Gitea's API.
tag=${latest##*/} tag=$(curl -fsSL --proto '=https' https://git.zacharyzhang.com/api/v1/repos/ZacharyZhang-NY/OmaPhoto/releases/latest | grep -o '"tag_name":"v[^"]*"' | cut -d'"' -f4) || tag=
case "$tag" in if [ -z "$tag" ]; then
v[0-9]*) ;; echo "No release found at $repo/releases." >&2
*)
echo "No release found at $latest." >&2
exit 1 exit 1
;; fi
esac nix --extra-experimental-features "nix-command flakes" profile install "git+$repo?ref=refs/tags/$tag"
nix --extra-experimental-features "nix-command flakes" profile install "github:ZacharyZhang-NY/OmaPhoto/$tag"
+9 -2
View File
@@ -1,7 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Installs OmaPhoto's latest DEB on Ubuntu LTS and derivatives. # Installs OmaPhoto's newest DEB on Ubuntu LTS and derivatives.
set -euo pipefail set -euo pipefail
base=https://github.com/ZacharyZhang-NY/OmaPhoto/releases/latest/download repo=https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto
# The newest release's tag, from Gitea's API.
tag=$(curl -fsSL --proto '=https' https://git.zacharyzhang.com/api/v1/repos/ZacharyZhang-NY/OmaPhoto/releases/latest | grep -o '"tag_name":"v[^"]*"' | cut -d'"' -f4) || tag=
if [ -z "$tag" ]; then
echo "No release found at $repo/releases." >&2
exit 1
fi
base=$repo/releases/download/$tag
. /etc/os-release . /etc/os-release
# Each DEB names its LTS's libraries; derivatives name their base. # Each DEB names its LTS's libraries; derivatives name their base.
case "${UBUNTU_CODENAME:-}" in case "${UBUNTU_CODENAME:-}" in
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
# Builds a tag's packages and publishes a Gitea release.
set -euo pipefail
tag=${1:?"usage: GITEA_TOKEN=... scripts/release.sh vX.Y.Z"}
token=${GITEA_TOKEN:?"GITEA_TOKEN must hold a Gitea access token"}
api=https://git.zacharyzhang.com/api/v1/repos/ZacharyZhang-NY/OmaPhoto
repo=$(cd "$(dirname "$0")/.." && pwd)
cd "$repo"
version=${tag#v}
# The tag must name the version each build file carries.
if ! git show "$tag:CMakeLists.txt" | grep -qF "project(omaphoto VERSION $version "; then
echo "CMakeLists.txt at $tag is not $version" >&2
exit 1
fi
if ! git show "$tag:packaging/arch/PKGBUILD" | grep -qxF "pkgver=$version"; then
echo "The PKGBUILD at $tag is not $version" >&2
exit 1
fi
if ! git show "$tag:flake.nix" | grep -qF "version = \"$version\";"; then
echo "flake.nix at $tag is not $version" >&2
exit 1
fi
out=$repo/release/$tag
rm -rf "$out"
mkdir -p "$out"
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT
user="$(id -u):$(id -g)"
configure="cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DOMAPHOTO_BUNDLE_ORT=ON -DOMAPHOTO_MODEL=/usr/local/share/omaphoto/u2net.onnx && cmake --build build --target omaphoto"
# Each package builds from a fresh copy of the tag.
fresh() {
rm -rf "$work/src"
mkdir "$work/src"
git archive "$tag" | tar -x -C "$work/src"
}
build() {
docker run --rm -u "$user" -e HOME=/tmp -v "$work/src:/src" -w /src "$1" sh -c "$2"
}
# One DEB per Ubuntu LTS: each names its own libraries.
docker build -t omaphoto-dev --build-arg BASE=ubuntu:24.04 -f Dockerfile.dev .
docker build -t omaphoto-resolute --build-arg BASE=ubuntu:26.04 -f Dockerfile.dev .
for pair in noble:omaphoto-dev resolute:omaphoto-resolute; do
fresh
build "${pair#*:}" "$configure && cd build && cpack -G DEB"
mv "$work"/src/build/omaphoto_*.deb "$out/omaphoto-${pair%%:*}_amd64.deb"
done
# One RPM per Fedora release: each names its own LibRaw.
docker build -t omaphoto-fedora --build-arg RELEASE=43 scripts/distro/fedora
docker build -t omaphoto-fedora44 --build-arg RELEASE=44 scripts/distro/fedora
for pair in 43:omaphoto-fedora 44:omaphoto-fedora44; do
fresh
build "${pair#*:}" "$configure && cd build && cpack -G RPM"
mv "$work"/src/build/omaphoto-*.x86_64.rpm "$out/omaphoto-fc${pair%%:*}.x86_64.rpm"
done
# makepkg refuses root; a user of our id builds.
docker build --pull -t omaphoto-arch scripts/distro/arch
fresh
docker run --rm -v "$work/src:/src" omaphoto-arch sh -c "useradd -u $(id -u) builder && chown -R builder /src && su builder -c 'cd /src/packaging/arch && makepkg -f'"
mv "$work"/src/packaging/arch/omaphoto-[0-9]*-x86_64.pkg.tar.zst "$out/omaphoto-x86_64.pkg.tar.zst"
# The AppImage builds on Ubuntu 24.04, the oldest glibc here.
docker build -t omaphoto-appimage --build-arg DEV=omaphoto-dev scripts/distro/appimage
fresh
build omaphoto-appimage scripts/appimage.sh
mv "$work/src/omaphoto-x86_64.AppImage" "$out/"
names="omaphoto-noble_amd64.deb omaphoto-resolute_amd64.deb omaphoto-fc43.x86_64.rpm omaphoto-fc44.x86_64.rpm omaphoto-x86_64.pkg.tar.zst omaphoto-x86_64.AppImage"
(cd "$out" && sha256sum $names > SHA256SUMS)
# The tag must already be on Gitea.
notes="Install with the script for your system, or run the AppImage: see the README's Install section."
body=$(printf '{"tag_name":"%s","name":"OmaPhoto %s","body":"%s"}' "$tag" "$version" "$notes")
release=$(curl -fsS -X POST -H "Authorization: token $token" -H "Content-Type: application/json" -d "$body" "$api/releases")
id=$(echo "$release" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
for name in $names SHA256SUMS; do
echo "Uploading $name"
curl -fsS -o /dev/null -X POST -H "Authorization: token $token" -F "attachment=@$out/$name" "$api/releases/$id/assets?name=$name"
done
echo "Published https://git.zacharyzhang.com/ZacharyZhang-NY/OmaPhoto/releases/tag/$tag"