mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-14 19:27:01 -04:00
Signed release pipeline (macOS/Windows/Linux/Web); README community note
Ports photocraft's release workflow + packaging (signing, notarization, MSI/DMG/deb/rpm/AppImage/web), adds `cargo xtask version`. File-type associations omitted (route B); app keeps its own .desktop. Fresh WiX UpgradeCode. README 'about' note updated. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
75e4e3ced0
commit
453f97b549
24 files changed
+1633
-3
No files matched your search
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- AppStream metadata (software centres, Flathub). Template: package.sh and the Flatpak
|
||||
manifest substitute @VERSION@ and @DATE@ from Cargo.toml and the build date. -->
|
||||
<component type="desktop-application">
|
||||
<id>ai.storyteller.lightcraft</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>MIT OR Apache-2.0</project_license>
|
||||
<name>LightCraft</name>
|
||||
<summary>Organise photos and develop raw files, non-destructively</summary>
|
||||
<developer id="ai.storyteller">
|
||||
<name>Learning Machines LLC</name>
|
||||
</developer>
|
||||
<description>
|
||||
<p>
|
||||
LightCraft is a photo library and raw developer. Organise photos and develop raw files, non-destructively
|
||||
</p>
|
||||
</description>
|
||||
<launchable type="desktop-id">ai.storyteller.lightcraft.desktop</launchable>
|
||||
<icon type="stock">ai.storyteller.lightcraft</icon>
|
||||
<!-- Only url types known to appstream 0.15 (Ubuntu 22.04, where CI validates): no vcs-browser. -->
|
||||
<url type="homepage">https://getartcraft.com/apps/lightcraft</url>
|
||||
<url type="bugtracker">https://github.com/storytold/lightcraft/issues</url>
|
||||
<url type="help">https://github.com/storytold/lightcraft</url>
|
||||
<url type="contact">https://discord.gg/artcraft</url>
|
||||
<categories>
|
||||
<category>Graphics</category>
|
||||
<category>RasterGraphics</category>
|
||||
<category>Photography</category>
|
||||
</categories>
|
||||
<keywords>
|
||||
<keyword>photo</keyword>
|
||||
<keyword>image editor</keyword>
|
||||
<keyword>psd</keyword>
|
||||
<keyword>layers</keyword>
|
||||
</keywords>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Editing The Great Wave off Kanagawa with type layers and adjustment layers</caption>
|
||||
<image>https://raw.githubusercontent.com/storytold/lightcraft/main/docs/images/lightcraft-demo.jpg</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<branding>
|
||||
<color type="primary" scheme_preference="light">#9fd0ff</color>
|
||||
<color type="primary" scheme_preference="dark">#1f64ba</color>
|
||||
</branding>
|
||||
<requires>
|
||||
<display_length compare="ge">760</display_length>
|
||||
</requires>
|
||||
<supports>
|
||||
<control>keyboard</control>
|
||||
<control>pointing</control>
|
||||
<control>tablet</control>
|
||||
</supports>
|
||||
<provides>
|
||||
<binary>lightcraft</binary>
|
||||
</provides>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="@VERSION@" date="@DATE@"/>
|
||||
</releases>
|
||||
</component>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
</mime-info>
|
||||
@@ -0,0 +1,56 @@
|
||||
# Flatpak manifest for LightCraft, ready for a Flathub submission.
|
||||
#
|
||||
# Flatpak builds run offline, so the crate sources must be vendored first. From the repo root:
|
||||
#
|
||||
# curl -fsSLO https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/cargo/flatpak-cargo-generator.py
|
||||
# python3 flatpak-cargo-generator.py Cargo.lock -o packaging/linux/flatpak/cargo-sources.json
|
||||
# flatpak-builder --user --install --force-clean build-flatpak packaging/linux/flatpak/ai.storyteller.lightcraft.yml
|
||||
# flatpak run ai.storyteller.lightcraft
|
||||
#
|
||||
# For Flathub, replace the `dir` source with a `git` source pinned to a release tag and commit.
|
||||
id: ai.storyteller.lightcraft
|
||||
runtime: org.freedesktop.Platform
|
||||
runtime-version: '25.08'
|
||||
sdk: org.freedesktop.Sdk
|
||||
sdk-extensions:
|
||||
- org.freedesktop.Sdk.Extension.rust-stable
|
||||
command: lightcraft
|
||||
finish-args:
|
||||
- --share=ipc
|
||||
- --socket=wayland
|
||||
- --socket=fallback-x11
|
||||
- --device=dri
|
||||
# Open/Save dialogs use the file-chooser portal (rfd), and drag-and-drop uses the document
|
||||
# portal, so broad filesystem access isn't needed. Pictures is granted for opening files by
|
||||
# path from the command line.
|
||||
- --filesystem=xdg-pictures
|
||||
build-options:
|
||||
append-path: /usr/lib/sdk/rust-stable/bin
|
||||
modules:
|
||||
- name: lightcraft
|
||||
buildsystem: simple
|
||||
build-options:
|
||||
env:
|
||||
CARGO_HOME: /run/build/lightcraft/cargo
|
||||
CARGO_NET_OFFLINE: 'true'
|
||||
build-commands:
|
||||
- cargo --offline build --release --locked -p lightcraft
|
||||
- install -Dm755 target/release/lightcraft /app/bin/lightcraft
|
||||
- install -Dm644 packaging/linux/ai.storyteller.lightcraft.desktop /app/share/applications/ai.storyteller.lightcraft.desktop
|
||||
- install -Dm644 packaging/linux/ai.storyteller.lightcraft.mime.xml /app/share/mime/packages/ai.storyteller.lightcraft.xml
|
||||
- mkdir -p /app/share/icons && cp -R assets/app-icon/hicolor /app/share/icons/
|
||||
- >-
|
||||
version=$(awk '/^\[/{p=($0=="[workspace.package]");next} p&&$1=="version"{gsub(/[" ]/,"",$3);print $3;exit}' Cargo.toml);
|
||||
install -d /app/share/metainfo;
|
||||
sed -e "s/@VERSION@/$version/" -e "s/@DATE@/$(date -u +%Y-%m-%d)/"
|
||||
packaging/linux/ai.storyteller.lightcraft.metainfo.xml.in > /app/share/metainfo/ai.storyteller.lightcraft.metainfo.xml
|
||||
sources:
|
||||
- type: dir
|
||||
path: ../../..
|
||||
skip:
|
||||
- target
|
||||
- dist
|
||||
- corpus
|
||||
- build-flatpak
|
||||
- .flatpak-builder
|
||||
- cargo-sources.json
|
||||
@@ -0,0 +1,70 @@
|
||||
# .deb and .rpm packages (nfpm: https://nfpm.goreleaser.com). Run by package.sh, which stages
|
||||
# the file tree, substitutes its path for ${STAGE} (nfpm doesn't expand env vars in `src`) and
|
||||
# exports VERSION and NFPM_ARCH.
|
||||
#
|
||||
# nfpm package -f packaging/linux/nfpm.yaml -p deb -t dist/release/
|
||||
name: lightcraft
|
||||
arch: ${NFPM_ARCH}
|
||||
platform: linux
|
||||
version: ${VERSION}
|
||||
# semver: 0.2.0-rc.1 becomes 0.2.0~rc.1 in deb/rpm, so pre-releases sort before the release.
|
||||
version_schema: semver
|
||||
release: 1
|
||||
section: graphics
|
||||
priority: optional
|
||||
maintainer: ${LIGHTCRAFT_MAINTAINER}
|
||||
vendor: Learning Machines LLC
|
||||
homepage: https://getartcraft.com/apps/lightcraft
|
||||
license: MIT OR Apache-2.0
|
||||
description: |-
|
||||
Open-source, native image editor that works the way Photoshop users expect.
|
||||
Layers, masks, adjustment layers, layer styles, type and brushes; opens and
|
||||
saves layered PSD/PSB files; 8/16/32-bit documents; GPU compositing (wgpu).
|
||||
Includes lightcraft-cli, a headless converter and command runner.
|
||||
|
||||
# The binaries link only glibc and libgcc_s directly. Windowing (X11/Wayland, xkbcommon) and the
|
||||
# GPU (Vulkan, EGL/GL) are loaded at runtime, so they are dependencies/recommendations here
|
||||
# rather than ELF NEEDED entries.
|
||||
overrides:
|
||||
deb:
|
||||
depends:
|
||||
- libc6 (>= 2.35)
|
||||
- libgcc-s1
|
||||
- libxkbcommon0
|
||||
- libvulkan1 | libegl1
|
||||
recommends:
|
||||
- libwayland-client0
|
||||
- libx11-6
|
||||
- libx11-xcb1
|
||||
- libxcursor1
|
||||
- libxi6
|
||||
- libxrandr2
|
||||
- mesa-vulkan-drivers
|
||||
- xdg-desktop-portal
|
||||
rpm:
|
||||
depends:
|
||||
- libxkbcommon
|
||||
- (vulkan-loader or libglvnd-egl)
|
||||
recommends:
|
||||
- libwayland-client
|
||||
- libX11
|
||||
- libXcursor
|
||||
- libXi
|
||||
- libXrandr
|
||||
- mesa-vulkan-drivers
|
||||
- xdg-desktop-portal
|
||||
|
||||
contents:
|
||||
- src: ${STAGE}/usr/bin/lightcraft
|
||||
dst: /usr/bin/lightcraft
|
||||
file_info: { mode: 0755 }
|
||||
- src: ${STAGE}/usr/bin/lightcraft-cli
|
||||
dst: /usr/bin/lightcraft-cli
|
||||
file_info: { mode: 0755 }
|
||||
- src: ${STAGE}/usr/share/
|
||||
dst: /usr/share/
|
||||
type: tree
|
||||
|
||||
scripts:
|
||||
postinstall: packaging/linux/postinst.sh
|
||||
postremove: packaging/linux/postinst.sh
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build and package LightCraft for Linux (<arch> is x86_64 or aarch64):
|
||||
#
|
||||
# $DIST/lightcraft-<version>-linux-<arch>.AppImage any distro with glibc >= the build host's
|
||||
# $DIST/lightcraft-<version>-linux-<arch>.deb Debian, Ubuntu, Mint, Pop!_OS, ...
|
||||
# $DIST/lightcraft-<version>-linux-<arch>.rpm Fedora, openSUSE, RHEL, ...
|
||||
# $DIST/lightcraft-<version>-linux-<arch>.tar.gz plain FHS-style tree (bin/, share/)
|
||||
#
|
||||
# Usage: packaging/linux/package.sh [--skip-build] [--formats "appimage deb rpm tar"]
|
||||
#
|
||||
# Needs: cargo; nfpm for deb/rpm (https://nfpm.goreleaser.com); appimagetool for the AppImage
|
||||
# (downloaded into $CARGO_TARGET_DIR if missing). Build on an old distro (CI: Ubuntu 22.04,
|
||||
# glibc 2.35) so the binaries run on newer ones. Optional: desktop-file-validate, appstreamcli.
|
||||
set -euo pipefail
|
||||
# shellcheck source=../env.sh
|
||||
. "$(dirname "${BASH_SOURCE[0]}")/../env.sh"
|
||||
HERE="$ROOT/packaging/linux"
|
||||
APP_ID=ai.storyteller.lightcraft
|
||||
|
||||
SKIP_BUILD=0
|
||||
FORMATS="appimage deb rpm tar"
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--skip-build) SKIP_BUILD=1; shift ;;
|
||||
--formats) FORMATS="$2"; shift 2 ;;
|
||||
-h | --help) sed -n '2,15p' "$0"; exit 0 ;;
|
||||
*) echo "unknown argument: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
ARCH="$(uname -m)"
|
||||
case "$ARCH" in
|
||||
x86_64) DEB_ARCH=amd64 ;;
|
||||
aarch64 | arm64) ARCH=aarch64; DEB_ARCH=arm64 ;;
|
||||
*) echo "unsupported architecture $ARCH" >&2; exit 2 ;;
|
||||
esac
|
||||
export LIGHTCRAFT_MAINTAINER="${LIGHTCRAFT_MAINTAINER:-LightCraft maintainers <[email protected]>}"
|
||||
BASENAME="lightcraft-$VERSION-linux-$ARCH"
|
||||
|
||||
echo "==> LightCraft $VERSION for Linux $ARCH ($FORMATS)"
|
||||
|
||||
if [ "$SKIP_BUILD" = 0 ]; then
|
||||
(cd "$ROOT" && cargo build --release --locked -p lightcraft -p lightcraft-cli)
|
||||
fi
|
||||
BIN="$CARGO_TARGET_DIR/release"
|
||||
WORK="$CARGO_TARGET_DIR/linux-package"
|
||||
STAGE="$WORK/root"
|
||||
rm -rf "$WORK"
|
||||
|
||||
# ---- stage an FHS tree (shared by every format) -------------------------------------------------
|
||||
install -Dm755 "$BIN/lightcraft" "$STAGE/usr/bin/lightcraft"
|
||||
install -Dm755 "$BIN/lightcraft-cli" "$STAGE/usr/bin/lightcraft-cli"
|
||||
strip "$STAGE/usr/bin/lightcraft" "$STAGE/usr/bin/lightcraft-cli" 2>/dev/null || true
|
||||
install -Dm644 "$HERE/$APP_ID.desktop" "$STAGE/usr/share/applications/$APP_ID.desktop"
|
||||
install -Dm644 "$HERE/$APP_ID.mime.xml" "$STAGE/usr/share/mime/packages/$APP_ID.xml"
|
||||
mkdir -p "$STAGE/usr/share/metainfo"
|
||||
sed -e "s/@VERSION@/$VERSION/g" -e "s/@DATE@/$LIGHTCRAFT_BUILD_DATE/g" \
|
||||
"$HERE/$APP_ID.metainfo.xml.in" >"$STAGE/usr/share/metainfo/$APP_ID.metainfo.xml"
|
||||
mkdir -p "$STAGE/usr/share/icons"
|
||||
cp -R "$ROOT/assets/app-icon/hicolor" "$STAGE/usr/share/icons/"
|
||||
mkdir -p "$STAGE/usr/share/doc/lightcraft"
|
||||
copy_docs "$STAGE/usr/share/doc/lightcraft"
|
||||
|
||||
if command -v desktop-file-validate >/dev/null; then
|
||||
desktop-file-validate "$STAGE/usr/share/applications/$APP_ID.desktop"
|
||||
fi
|
||||
if command -v appstreamcli >/dev/null; then
|
||||
appstreamcli validate --no-net --explain "$STAGE/usr/share/metainfo/$APP_ID.metainfo.xml"
|
||||
fi
|
||||
|
||||
has() { case " $FORMATS " in *" $1 "*) return 0 ;; *) return 1 ;; esac; }
|
||||
|
||||
# ---- .tar.gz ------------------------------------------------------------------------------------
|
||||
if has tar; then
|
||||
mkdir -p "$WORK/tar"
|
||||
cp -R "$STAGE/usr" "$WORK/tar/$BASENAME"
|
||||
tar -C "$WORK/tar" -czf "$DIST/$BASENAME.tar.gz" "$BASENAME"
|
||||
echo "wrote $DIST/$BASENAME.tar.gz"
|
||||
fi
|
||||
|
||||
# ---- .deb / .rpm --------------------------------------------------------------------------------
|
||||
if has deb || has rpm; then
|
||||
command -v nfpm >/dev/null || { echo "error: nfpm not found (https://nfpm.goreleaser.com/install/)" >&2; exit 1; }
|
||||
export VERSION
|
||||
export NFPM_ARCH="$DEB_ARCH"
|
||||
# nfpm expands env vars in fields like `version` and `arch`, but not in `contents[].src`.
|
||||
sed "s|\${STAGE}|$STAGE|g" "$HERE/nfpm.yaml" >"$WORK/nfpm.yaml"
|
||||
for fmt in deb rpm; do
|
||||
if has "$fmt"; then (cd "$ROOT" && nfpm package -f "$WORK/nfpm.yaml" -p "$fmt" -t "$DIST/$BASENAME.$fmt"); fi
|
||||
done
|
||||
fi
|
||||
|
||||
# ---- AppImage -----------------------------------------------------------------------------------
|
||||
if has appimage; then
|
||||
APPDIR="$WORK/LightCraft.AppDir"
|
||||
cp -R "$STAGE" "$APPDIR"
|
||||
mv "$APPDIR/usr/share/doc" "$WORK/doc-unused"
|
||||
ln -s usr/bin/lightcraft "$APPDIR/AppRun"
|
||||
cp "$HERE/$APP_ID.desktop" "$APPDIR/$APP_ID.desktop"
|
||||
cp "$ROOT/assets/app-icon/hicolor/256x256/apps/$APP_ID.png" "$APPDIR/$APP_ID.png"
|
||||
ln -s "$APP_ID.png" "$APPDIR/.DirIcon"
|
||||
|
||||
TOOL="${APPIMAGETOOL:-$(command -v appimagetool || true)}"
|
||||
if [ -z "$TOOL" ]; then
|
||||
TOOL="$CARGO_TARGET_DIR/appimagetool-$ARCH.AppImage"
|
||||
if [ ! -x "$TOOL" ]; then
|
||||
curl -fsSL -o "$TOOL" "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$ARCH.AppImage"
|
||||
chmod +x "$TOOL"
|
||||
fi
|
||||
fi
|
||||
OUT="$DIST/$BASENAME.AppImage"
|
||||
# Extract-and-run: works without FUSE (containers, CI). The output embeds the static runtime,
|
||||
# so users don't need libfuse2 either.
|
||||
ARCH="$ARCH" APPIMAGE_EXTRACT_AND_RUN=1 "$TOOL" --no-appstream "$APPDIR" "$OUT"
|
||||
echo "wrote $OUT"
|
||||
fi
|
||||
|
||||
"$STAGE/usr/bin/lightcraft-cli" --version
|
||||
echo "==> done"
|
||||
ls -lh "$DIST"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
# deb/rpm post-install and post-remove: refresh the desktop, MIME and icon caches.
|
||||
# Every tool is optional; missing ones are skipped.
|
||||
if command -v update-desktop-database >/dev/null 2>&1; then
|
||||
update-desktop-database -q /usr/share/applications || true
|
||||
fi
|
||||
if command -v update-mime-database >/dev/null 2>&1; then
|
||||
update-mime-database /usr/share/mime || true
|
||||
fi
|
||||
if command -v gtk-update-icon-cache >/dev/null 2>&1; then
|
||||
gtk-update-icon-cache -q -t -f /usr/share/icons/hicolor || true
|
||||
fi
|
||||
exit 0
|
||||
Reference in new issue
Block a user