Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ jobs:
cmake --build --preset ${{ matrix.preset }}
ctest --preset ${{ matrix.preset }}

# The Debian package the release publishes: packed, installed, found by a consumer.
- name: Check the Debian package
if: matrix.preset == 'linux-gcc'
run: sh tools/check_deb.sh

# The plugin as released (minipsd-vips-X.Y.Z.zip, tools/package_vips.cmake): built from the
# zip alone, outside the repository, its example run, its SBOM fragment checked against its
# files; libvips as fetched above. The release builds it again on Linux before publishing.
Expand Down
19 changes: 15 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Release: a pushed tag X.Y.Z (bare semver) checks that CI already passed on its commit on master,
# checks the tag against the header version and the changelog, and publishes minipsd.h (include/ joined into one file by
# tools/amalgamate.cmake) + minipsd.h.sha256, and the libvips plugin as a CMake project that builds as it is
# (minipsd-vips-X.Y.Z.zip, tools/package_vips.cmake, built and run here first) + its .sha256, as a GitHub Release
# with build-provenance attestations. "Run workflow" (workflow_dispatch) does everything except publish,
# (minipsd-vips-X.Y.Z.zip, tools/package_vips.cmake, built and run here first) + its .sha256, and the
# Debian package (libminipsd-dev_X.Y.Z_all.deb, tools/check_deb.sh, installed and found here first) + its
# .sha256, as a GitHub Release with build-provenance attestations. "Run workflow" (workflow_dispatch) does everything except publish,
# so it is a dry run. See docs/GITHUB-RELEASE.md.
name: Release

Expand Down Expand Up @@ -78,17 +79,25 @@ jobs:
sudo apt-get update && sudo apt-get install -y --no-install-recommends libvips-dev ninja-build
mkdir "$RUNNER_TEMP/plugin" && cd "$RUNNER_TEMP/plugin"
cmake -E tar xf "$GITHUB_WORKSPACE"/dist/minipsd-vips-*.zip
cmake -DSPDX="$(echo minipsd-vips-*)/minipsd-vips.spdx.json" -DBASE="$(echo minipsd-vips-*)" -DCOMPLETE=ON -P "$GITHUB_WORKSPACE"/tools/check_spdx.cmake
cmake -DSPDX="$(echo minipsd-vips-*)/minipsd-vips.spdx.json" -DBASE="$(echo minipsd-vips-*)" -DCOMPLETE=ON \
-P "$GITHUB_WORKSPACE"/tools/check_spdx.cmake
cmake -S minipsd-vips-* -B build -G Ninja
cmake --build build
ctest --test-dir build --output-on-failure

# Verifiable with: gh attestation verify minipsd.h --repo ShadobaDev/minipsd (the zip alike)
# The install tree as a Debian package (CPack), installed here and found by a consumer.
- name: Stage the Debian package and its checksum
run: |
sh tools/check_deb.sh
cd dist && for deb in *.deb; do sha256sum "$deb" > "$deb.sha256" && cat "$deb.sha256"; done

# Verifiable with: gh attestation verify minipsd.h --repo ShadobaDev/minipsd (the zip and the .deb alike)
- uses: actions/attest-build-provenance@v4
with:
subject-path: |
dist/minipsd.h
dist/minipsd-vips-*.zip
dist/libminipsd-dev_*_all.deb

- name: Publish the GitHub Release
if: github.ref_type == 'tag'
Expand All @@ -102,3 +111,5 @@ jobs:
dist/minipsd.h.sha256
dist/minipsd-vips-*.zip
dist/minipsd-vips-*.zip.sha256
dist/libminipsd-dev_*_all.deb
dist/libminipsd-dev_*_all.deb.sha256
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ the manual's [PSD in libvips](docs/MANUAL.md#psd-in-libvips-the-plugin).

## Adding it to a project

Copy the `include/` directory, or use CMake (FetchContent, git submodule, `find_package`),
pkg-config, an archive or a `.deb`; see [docs/INSTALL.md](docs/INSTALL.md).
Copy the `include/` directory (or the single `minipsd.h` each GitHub Release attaches), or use
CMake (FetchContent, git submodule, `find_package`), pkg-config, or the release's `.deb`; see
[docs/INSTALL.md](docs/INSTALL.md).

## Configuration

Expand Down
7 changes: 7 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
Changes between releases, for users of minipsd. Versioning follows the pre-1.0 rules in
[TODO.md](TODO.md): breaking changes bump the MINOR, additions and fixes the PATCH.

## [Unreleased]

### Added
- Each GitHub Release attaches `libminipsd-dev_X.Y.Z_all.deb` and its `.sha256`, the install tree
as a Debian/Ubuntu package, installed and found by `find_package` and pkg-config before it is
published.

## [0.4.0] — 2026-10-26

**Breaking:** `minipsd_doc.composite_alpha` now says, for every composite (given, composed from
Expand Down
1 change: 1 addition & 0 deletions docs/CODE-ARCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ tools/
amalgamate.cmake joins include/ into one file, a release artifact
package_vips.cmake packs the plugin as released: minipsd-vips-X.Y.Z.zip, its SBOM fragment inside
check_spdx.cmake checks an SPDX fragment against its files (checksums, every file listed)
check_deb.sh packs the .deb the release attaches, installs it, builds a consumer against it
compat_report.py regenerates COMPATIBILITY.md
```

Expand Down
18 changes: 11 additions & 7 deletions docs/GITHUB-RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ Pushing the tag starts the [`Release`](../.github/workflows/release.yml) workflo
(`tools/package_vips.cmake`), with its SBOM fragment, then checked against that fragment
(`tools/check_spdx.cmake`) and built from the zip alone against Ubuntu's libvips, its
example run: a zip that does not build is not published;
5. a build-provenance attestation for `minipsd.h` and the zip;
6. a GitHub Release with `minipsd.h`, the zip and a `.sha256` for each, its notes taken from the
changelog section.
5. the Debian package `libminipsd-dev_X.Y.Z_all.deb` (CPack), installed on the runner and found
by a consumer by `find_package` and pkg-config (`tools/check_deb.sh`): a package that does not
install is not published;
6. a build-provenance attestation for `minipsd.h`, the zip and the `.deb`;
7. a GitHub Release with `minipsd.h`, the zip, the `.deb` and a `.sha256` for each, its notes
taken from the changelog section.

There is nothing to build for consumers: the source tree at the tag *is* the release. `minipsd.h`
is for users who prefer one file to copying `include/`; the zip, for those who want the plugin
without the repository. CI packs and builds the zip on every push too, so it fails there first.
without the repository; the `.deb`, for an install by apt. CI packs and checks the zip and the
`.deb` on every push too, so they fail there first.

## 0. Pre-flight

Expand Down Expand Up @@ -52,10 +56,10 @@ notes come from `docs/CHANGELOG.md`, not from the tag.
## 3. Verify

- **Actions** → the Release run is green.
- **Releases** → `0.1.0` has `minipsd.h`, `minipsd-vips-0.1.0.zip`, a `.sha256` for each, and
the changelog notes.
- **Releases** → `0.1.0` has `minipsd.h`, `minipsd-vips-0.1.0.zip`, `libminipsd-dev_0.1.0_all.deb`,
a `.sha256` for each, and the changelog notes.
- Provenance: `gh attestation verify minipsd.h --repo ShadobaDev/minipsd`, and the same for the
zip.
zip and the `.deb`.
- A FetchContent consumer pinned to `GIT_TAG 0.1.0` configures and builds.

## 4. Then the consumers
Expand Down
16 changes: 8 additions & 8 deletions docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,19 @@ You can get that tree in any of these ways:
cmake -S minipsd -B build -DMINIPSD_BUILD_TESTS=OFF
cmake --install build --prefix /usr/local # Linux: with sudo
```
- **As an archive**, `minipsd-X.Y.Z.tar.gz` or `.zip`: use it unpacked where it is, or extract
it into a prefix. The tree is relocatable, so nothing needs regenerating:
- **As a Debian/Ubuntu package**, `libminipsd-dev_X.Y.Z_all.deb`, attached to each GitHub
Release with its `.sha256` (installed and found by a consumer before it is published):
```bash
sudo tar -xzf minipsd-0.4.0.tar.gz --strip-components=1 -C /usr/local
sudo apt install ./libminipsd-dev_0.4.0_all.deb
```
- **As a Debian/Ubuntu package**, `libminipsd-dev_X.Y.Z_all.deb`:
- **As an archive you pack yourself**, `minipsd-X.Y.Z.tar.gz` or `.zip`, with CPack from the source
([CHEATSHEET.md](CHEATSHEET.md#packages-and-installing)); no release attaches one. Use it
unpacked where it is, or extract it into a prefix. The tree is relocatable, so nothing needs
regenerating:
```bash
sudo apt install ./libminipsd-dev_0.4.0_all.deb
sudo tar -xzf minipsd-0.4.0.tar.gz --strip-components=1 -C /usr/local
```

The archive and the `.deb` are built with CPack, see
[CHEATSHEET.md](CHEATSHEET.md#packages-and-installing).

Then, in CMake (add `-DCMAKE_PREFIX_PATH=<tree>` unless the tree is in a system prefix):

```cmake
Expand Down
17 changes: 17 additions & 0 deletions libvips-plugin/test_vips.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,23 @@ static void check_layers_saved(const uint8_t *rgba, const char *dir)
snprintf(again, sizeof again, "%s/layers-template-minipsd.psd", dir);
check(write_file(&doc, again) && same_files(path, again), "the bytes minipsd_write makes from the same layers", path);

/* compression: the layer's channels ZIP, as Platemaker asks. */
{
uint8_t workspace[WORKSPACE_SIZE], *file;
size_t size = 0;
minipsd_reader *r;
minipsd_info info;
minipsd_layer_view view;
snprintf(again, sizeof again, "%s/layers-template-zip.psd", dir);
file = minipsd_vips_psdsave_layers(pair, 2, again, "composite", template_image, "compression", MINIPSD_VIPS_COMPRESSION_ZIP,
NULL) == 0 ? read_all(again, &size) : NULL;
check(file && minipsd_reader_init(&r, file, size, workspace, sizeof workspace, NULL, &info) == MINIPSD_OK
&& minipsd_reader_next_layer(r, &view) == MINIPSD_MORE && view.channel[0].size >= 2 && view.channel[0].data
&& view.channel[0].data[1] == STORED_ZIP,
"the layer's channels ZIP", again);
free(file);
}

/* Its composite made by libvips from the layers: the template's own pixels. */
snprintf(again, sizeof again, "%s/layers-template-composed.psd", dir);
check(minipsd_vips_psdsave_layers(pair, 2, again, NULL) == 0, "saved, composite composed", again);
Expand Down
26 changes: 26 additions & 0 deletions tools/check_deb.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh
# Packs minipsd as a Debian package, dist/libminipsd-dev_X.Y.Z_all.deb (CPack, CMakeLists.txt's
# rules), installs it, and builds tests/consumer against what it installed, by find_package and by
# pkg-config: a package that does not install, or is not found, is not published. Linux, with
# cmake, pkg-config and sudo; CI's linux-gcc job and the release run it.
#
# sh tools/check_deb.sh
set -eu
root=$(cd "$(dirname "$0")/.." && pwd)
version=$(sed -nE 's/^#define MINIPSD_VERSION_(MAJOR|MINOR|PATCH) +([0-9]+)$/\2/p' "$root/include/minipsd.h" | paste -sd.)
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT

cmake -S "$root" -B "$work/package" -DMINIPSD_BUILD_TESTS=OFF
cpack --config "$work/package/CPackConfig.cmake" -G DEB
deb="$root/dist/libminipsd-dev_${version}_all.deb"
dpkg-deb -I "$deb"
dpkg-deb -c "$deb"
sudo apt-get install -y "$deb"

for mode in package pkgconfig; do
cmake -S "$root/tests/consumer" -B "$work/consumer-$mode" -DMODE="$mode" -DMINIPSD_EXPECTED_VERSION="$version"
cmake --build "$work/consumer-$mode"
"$work/consumer-$mode/minipsd-consumer"
done
echo "$deb: installs, found by find_package and pkg-config"
Loading