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
15 changes: 15 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,18 @@ If this PR changes any of these human-readable contract snapshots, reviewers mus
- [ ] No snapshot files changed in those directories.
- [ ] Snapshot files changed, and the PR description explains the intended storage/event diff.
- [ ] Snapshot files changed, and a reviewer has explicitly confirmed the JSON diff is expected.

## Fixture diff review

If this PR regenerated any XDR or JSON event-schema fixture files under
`contracts/tipjar/tests/fixtures/` (i.e. `UPDATE_FIXTURES=1` was used), the
companion `.json` files must be reviewed before merging. The JSON diff shows
exactly which fields, types, or field ordering changed in the on-chain event
schema — a change that is invisible in the binary `.xdr` diff.

**Before ticking any box below, open the "Files changed" tab and read every
changed `.json` file in `contracts/tipjar/tests/fixtures/`.**

- [ ] No fixture files changed in this PR.
- [ ] Fixture files changed, and the JSON companion diff was reviewed. The changes are intentional and described in the summary above.
- [ ] Fixture files changed, and a reviewer has explicitly confirmed the JSON diff matches the intended event-schema change.
72 changes: 72 additions & 0 deletions .github/workflows/fixture-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Fixture Review Gate

# This workflow triggers on any PR that touches an XDR or JSON event-fixture
# file under contracts/tipjar/tests/fixtures/. Its sole job is to ensure that
# the PR body contains an explicit reviewer acknowledgment before the PR can
# be merged.
#
# Why this exists:
# Binary XDR golden files are not human-readable in a standard `git diff`.
# The companion .json files decode the same payload into a reviewable form,
# but only if someone actually looks at them. This gate makes that look
# mandatory — the CI check goes red until the PR body contains a checked
# checkbox from the fixture review section of the PR template.
#
# To pass this check:
# 1. Review the diff of every changed .json companion file.
# 2. Tick the appropriate checkbox in the "Fixture diff review" section of
# the PR description (see .github/pull_request_template.md).

on:
pull_request:
branches: [main, develop]
paths:
- 'contracts/tipjar/tests/fixtures/*.xdr'
- 'contracts/tipjar/tests/fixtures/*.json'
- '.github/workflows/fixture-review.yml'

jobs:
require-fixture-review-acknowledgment:
name: Require fixture-diff review acknowledgment
runs-on: ubuntu-latest
Comment thread
Christopherdominic marked this conversation as resolved.
steps:
- name: Check PR body for fixture review checkbox
env:
PR_BODY: ${{ github.event.pull_request.body }}
run: |
set -eu

# Accept either of these checked-box patterns:
# [x] Fixture files changed, and the JSON companion diff was reviewed.
# [X] No fixture files changed in this PR.
# The second option is included so a PR that only touches
# fixture-review.yml itself (workflow change, no fixture diff) can
# still pass by ticking the "no fixtures changed" box.
if printf '%s\n' "$PR_BODY" | grep -Eiq '\[[xX]\].*(fixture|no fixture)'; then
Comment thread
Christopherdominic marked this conversation as resolved.
echo "Fixture review acknowledgment found. ✓"
exit 0
fi

cat <<'MSG'
──────────────────────────────────────────────────────────────────────
FIXTURE REVIEW GATE FAILED
──────────────────────────────────────────────────────────────────────
This PR modifies one or more XDR or JSON fixture files under
contracts/tipjar/tests/fixtures/

Those files are golden event-schema fixtures. The companion .json
files exist precisely so that reviewers can see "the token field
moved from position 2 to position 3" in a readable diff, rather than
staring at an opaque binary blob.

Before this PR can be merged:
1. Open the "Fixture diff review" section of the PR description.
2. Review every changed .json file in the PR diff.
3. Tick the checkbox that describes what changed and confirm you
reviewed it.

See CONTRIBUTING.md § "Event fixture golden files" for the full
process, including how to regenerate fixtures with UPDATE_FIXTURES=1.
──────────────────────────────────────────────────────────────────────
MSG
exit 1
76 changes: 76 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,82 @@ single PR.
(real SAC test token, `mock_all_auths()`, `try_<fn>()` for expected errors,
`env.events().all().filter_by_contract(...)` for event assertions).

## Event fixture golden files

`contracts/tipjar/tests/fixtures/` holds binary XDR golden files that pin the
exact on-chain encoding of each event's topics and data fields:

```
tip_topics.xdr — VecM<ScVal> for the Tip event's topics
tip_data.xdr — ScVal for the Tip event's data
withdraw_topics.xdr — VecM<ScVal> for the Withdraw event's topics
withdraw_data.xdr — ScVal for the Withdraw event's data
```
Comment thread
Christopherdominic marked this conversation as resolved.

Alongside every `.xdr` file there is a **human-readable `.json` companion**
(e.g. `tip_data.json`). Both files are generated and verified by the
`fixtures::event_schema_golden_fixtures` test in `src/test.rs`.

### What the JSON files contain

The `.json` files decode the same XDR payload into a readable representation
where each `ScVal` variant is wrapped in a one-key JSON object showing the
type:

```json
{
"Vec": [
{ "Address": { "Contract": "692c36..." } },
{ "Address": { "Contract": "000000...06" } },
{ "I128": "250" }
]
}
```

This format is designed for git diffs: if a field moves from position 2 to
position 3, or its type changes from `I128` to `I64`, the JSON diff shows it
immediately — unlike the binary `.xdr` diff which is opaque.

### Regenerating fixtures after an intentional event-schema change

If you intentionally change the topics or data of the `tip` or `withdraw`
event (field order, type, presence, or any other schema detail), you must
regenerate both the `.xdr` and `.json` companion files:

```bash
# Linux / macOS
UPDATE_FIXTURES=1 cargo test -p tipjar fixtures::event_schema_golden_fixtures

# Windows PowerShell
$env:UPDATE_FIXTURES="1"; cargo test -p tipjar fixtures::event_schema_golden_fixtures
```

This overwrites both the `.xdr` binary and the `.json` companion with values
produced by the current code.

**After regenerating:**

1. Run `cargo test -p tipjar` (without `UPDATE_FIXTURES`) and confirm all
tests pass — the freshly written fixtures must round-trip correctly.
2. Open the "Files changed" view in your PR and read the diff of every changed
`.json` file carefully. The JSON diff is the ground truth for what changed
in the event schema.
3. Tick the appropriate checkbox in the **Fixture diff review** section of the
PR description (see `.github/pull_request_template.md`).

### CI gate: fixture-review workflow

`.github/workflows/fixture-review.yml` triggers on any PR that touches
`contracts/tipjar/tests/fixtures/*.xdr` or `*.json`. It fails with a
descriptive error message until the PR body contains a checked checkbox from
the fixture review section.

This gate exists because event-schema changes are part of the contract's
on-chain interface. Off-chain indexers and the frontend SDK both depend on
`tip` and `withdraw` events having specific fields in a specific order. A
silently-absorbed schema regression would break them in production without any
compile-time signal.

## Commit Convention

Use [Conventional Commits](https://www.conventionalcommits.org/):
Expand Down
4 changes: 4 additions & 0 deletions contracts/tipjar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ soroban-sdk = "26.1.0"
[dev-dependencies]
soroban-sdk = { version = "26.1.0", features = ["testutils"] }
proptest = "1.4"
# Used in the `fixtures` test module to produce human-readable JSON companion
# files alongside binary XDR golden fixtures — making event-schema diffs
# reviewable in PRs without decoding opaque binary blobs.
serde_json = "1.0.149"

# `pause_tests` and `partial_pause_tests` live under the repo-root `tests/`
# directory (shared with `tests/common`) rather than `contracts/tipjar/tests/`
Expand Down
Loading
Loading