Skip to content

Bump to c2pa-rs 0.91.0-rc.1 (build from source, adapt to breaking changes) - #325

Draft
scouten-adobe wants to merge 4 commits into
mainfrom
test/c2pa-rs-0.91.0-rc.1
Draft

scouten-adobe wants to merge 4 commits into
mainfrom
test/c2pa-rs-0.91.0-rc.1

Conversation

@scouten-adobe

@scouten-adobe scouten-adobe commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

c2pa-rs c2pa-rc-v0.91.0-rc.1 is out. It isn't published to crates.io and has no GitHub release with prebuilt native libraries, so this pins c2pa-native-version.txt to that tag and teaches CI to build the FFI library from source instead of downloading a release asset.

  • CI: tests-unix/tests-windows in build.yml now check out c2pa-rs at the pinned tag and build via the existing scripts/build_local_artifacts.py. Wheel-build jobs (which need a prebuilt binary per architecture) are skipped while the pin is an -rc. tag.
  • Also added .github/workflows/test-c2pa-rs-source-build.yml, a standalone workflow_dispatch tool for building against any c2pa-rs ref on demand, independent of the pinned version — useful for probing future RCs without a bump.

I built locally against the RC (universal2 + native-arch) and ran the full 444-test suite to see what actually breaks, then fixed what I found rather than just wiring up CI and hoping:

  • Trust settings schema changed: trust.trust_anchors / trust.trust_config moved under a new trust.anchors[] array (each entry carries its own trust_kind). The old flat shape still loads without error but silently stops conferring "Trusted" validation state (downgrades to "Valid") — no exception, just a quieter security-relevant result. Migrated tests/trust_config_test_settings.json to the new schema.
  • Stricter first-action validation: signing now requires the first c2pa.actions/c2pa.actions.v2 entry to be c2pa.created or c2pa.opened. Several ingredient-archive tests had empty or c2pa.placed-only action lists that used to be tolerated; added an explicit leading created/opened action (or reordered where one already existed) to match the new rule.
  • Builder.add_ingredient() now validates ingredient bytes against the declared MIME type: a few tests were declaring a JPEG fixture as "image/png" and only got away with it because the mismatch used to be ignored.
  • Pointer-identity assumption in a white-box test broke: an internal c2pa-rs refactor (untrack_or_return! now moves the value out and drops the wrapper Box immediately) means the native allocator can legally reuse a just-freed builder's address for its replacement. test_swapped_builder_is_freed_exactly_once assumed the two addresses would always differ; relaxed it to check the actually-meaningful invariant (freed exactly once) instead.

Everything else — including the ownership-semantics changes in c2pa_c_ffi/src/c_api.rs where several with_* functions now consume their input pointer on any failure, not just on success — was already handled correctly by the existing ManagedResource error-tag-based recovery logic in c2pa.py, with no changes needed.

All 444 tests pass locally against the RC build (macOS, native arm64).

Test plan

  • Local build from c2pa-rc-v0.91.0-rc.1 source (macOS arm64) + full unit test suite: 444 passed
  • CI (tests-unix/tests-windows matrix) builds from source and passes on macOS/Linux/Windows
  • Once c2pa-rs 0.91.0 is fully released with prebuilt artifacts, drop the source-build detour and go back to download_artifacts.py through the normal version-bump process

🤖 Generated with Claude Code

c2pa-rs 0.91.0-rc.1 (tag c2pa-rc-v0.91.0-rc.1) has no crates.io
publish and no GitHub release with prebuilt native libraries, so the
usual download_artifacts.py path can't fetch it. This workflow checks
out c2pa-rs at a given git ref and builds the FFI library from source
via build_local_artifacts.py, then runs the unit tests against it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@scouten-adobe scouten-adobe changed the title Test against c2pa-rs 0.91.0-rc.1 (built from source) DO NOT MERGE: Test against c2pa-rs 0.91.0-rc.1 (built from source) Sep 14, 2026
@scouten-adobe scouten-adobe changed the title DO NOT MERGE: Test against c2pa-rs 0.91.0-rc.1 (built from source) Test against c2pa-rs 0.91.0-rc.1 (built from source) Sep 14, 2026
c2pa-rs 0.91.0-rc.1 is not published to crates.io and has no GitHub
release with prebuilt native libraries, so CI now builds the FFI
library from the c2pa-rs git tag via build_local_artifacts.py instead
of downloading a release asset (build.yml). Wheel-build jobs are
skipped while the pin is an "-rc." tag, since there's nothing to
publish per-architecture yet.

Building locally against the RC and running the full unit test suite
surfaced three real behavior changes to adapt to:

- Trust settings schema: `trust.trust_anchors`/`trust.trust_config`
  moved under `trust.anchors[]` (with a `trust_kind`). The old flat
  shape no longer confers "Trusted" validation state (silently
  downgrades to "Valid", no error), so
  tests/trust_config_test_settings.json now uses the new schema.
- Builder validation is stricter about the first action: signing now
  requires the first `c2pa.actions`/`c2pa.actions.v2` entry to be
  `c2pa.created` or `c2pa.opened`. Ingredient-archive tests with empty
  or "placed"-only action lists needed an explicit leading
  created/opened action.
- `Builder.add_ingredient()` now validates ingredient bytes against
  the declared MIME type; a few tests were passing a JPEG fixture
  under "image/png" and only got away with it because that mismatch
  used to be ignored.

Also relaxed test_swapped_builder_is_freed_exactly_once: a c2pa-rs
internal refactor (untrack_or_return! now moves the value out and
drops the wrapper Box immediately) means the native allocator can
legally reuse a just-freed builder's address for its replacement, so
the test no longer assumes the two pointers differ.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@scouten-adobe scouten-adobe changed the title Test against c2pa-rs 0.91.0-rc.1 (built from source) Bump to c2pa-rs 0.91.0-rc.1 (build from source, adapt to breaking changes) Sep 14, 2026

@tmathern tmathern left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread .github/workflows/build.yml Outdated
rm -rf dist/* build/*

- name: Download native artifacts
# c2pa-rs ${{ needs.read-version.outputs.c2pa-native-version }} is a

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of reverting, maybe put it behind a label or a manually triggered workflow that takes the version number as param? So you don't need to repeat the workflow exercise for every pre-release

Comment thread tests/test_unit_tests.py
ingredient_json = '{"test": "ingredient2"}'
with open(self.testPath2, 'rb') as f:
builder.add_ingredient(ingredient_json, "image/png", f)
builder.add_ingredient(ingredient_json, "image/jpeg", f)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is weird. Was the format in the tests wrong? Why is it changing here?

scouten-adobe and others added 2 commits September 16, 2026 15:20
Per Tania's review feedback: rather than hacking a temporary
source-build detour into build.yml (which would need manually
reverting once c2pa-rs 0.91.0 GA ships with prebuilt artifacts), keep
build.yml and c2pa-native-version.txt pointed at the real released
c2pa-rs (0.90.19) and rely solely on
test-c2pa-rs-source-build.yml (workflow_dispatch, takes a
c2pa-rs-ref input) for RC preflights going forward. It now covers the
same OS/arch matrix as build.yml's tests-unix/tests-windows and
builds for the runner's own arch instead of a universal2 macOS binary.

Reverted tests/trust_config_test_settings.json to the old flat
trust.trust_anchors/trust.trust_config shape: the new trust.anchors[]
schema (needed for 0.91.0-rc.1 to report "Trusted") isn't understood
by the currently-pinned 0.90.19, so keeping it broke 17 tests when
run against the real release.

The other adaptations from the previous commit (stricter first-action
validation, ingredient MIME-type fix, the pointer-identity test
relaxation) are backward compatible and still pass against 0.90.19,
so they stay.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
workflow_dispatch alone can't give a PR real CI signal while iterating
on adaptation commits: it has to be re-triggered by hand on every
push, so reviewers can't just trust the PR's check list.

Add a resolve-ref job that reads the target ref from a new
c2pa-rs-preflight-ref.txt file when present, falling back to the
workflow_dispatch input for one-off runs with nothing committed. The
file's mere presence is what opts a PR in, so test-c2pa-rs-source-build.yml
now reruns on every push to a PR that carries it -- same as any other
check -- and downstream jobs quietly skip on ordinary PRs that don't.
Kept the existing "safe to test" label as the trust fallback for
non-collaborator authors, matching build.yml's own convention (a
dedicated label would have been cleaner but this token can't create
new repo labels).

Populated c2pa-rs-preflight-ref.txt with c2pa-rc-v0.91.0-rc.1 so this
PR exercises the mechanism it's introducing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment on lines +98 to +104
- name: Install project dependencies
working-directory: c2pa-python
run: |
python -m pip install -r requirements.txt
python -m pip install -r requirements-dev.txt

- name: Build native library from c2pa-rs source
Comment on lines +104 to +114
- name: Build native library from c2pa-rs source
working-directory: c2pa-python
env:
C2PA_RS_PATH: ${{ github.workspace }}/c2pa-rs
# Build for the runner's own arch rather than the universal2 macOS
# default: it's what a local `pip install -e .` picks up anyway,
# and skips the slow cross-compiled second-arch OpenSSL build.
C2PA_LIBS_PLATFORM: ${{ matrix.os == 'macos-latest' && 'aarch64-apple-darwin' || (matrix.os == 'ubuntu-24.04-arm' && 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu') }}
run: python scripts/build_local_artifacts.py --clean

- name: Install package in development mode
Comment on lines +114 to +120
- name: Install package in development mode
working-directory: c2pa-python
run: |
pip uninstall -y c2pa
pip install -e .

- name: Verify installation
Comment on lines +124 to +128
- name: Run tests
working-directory: c2pa-python
run: python ./tests/test_unit_tests.py

tests-windows:
Comment on lines +181 to +187
- name: Install project dependencies
working-directory: c2pa-python
run: |
python -m pip install -r requirements.txt
python -m pip install -r requirements-dev.txt

- name: Build native library from c2pa-rs source
Comment on lines +187 to +193
- name: Build native library from c2pa-rs source
working-directory: c2pa-python
env:
C2PA_RS_PATH: ${{ github.workspace }}\c2pa-rs
run: python scripts\build_local_artifacts.py --clean

- name: Install package in development mode
Comment on lines +193 to +199
- name: Install package in development mode
working-directory: c2pa-python
run: |
pip uninstall -y c2pa
pip install -e .

- name: Verify installation
Comment on lines +203 to +205
- name: Run tests
working-directory: c2pa-python
run: python .\tests\test_unit_tests.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants