Skip to content

feat: add easy-paging-demo (first runnable example)#2

Merged
jlc488 merged 1 commit into
mainfrom
feat/easy-paging-demo
May 23, 2026
Merged

feat: add easy-paging-demo (first runnable example)#2
jlc488 merged 1 commit into
mainfrom
feat/easy-paging-demo

Conversation

@jlc488
Copy link
Copy Markdown
Contributor

@jlc488 jlc488 commented May 23, 2026

Summary

First demo in this repo. Showcases the basic offset-pagination path of `easy-paging-spring-boot-starter` (0.4.0): one `@AutoPaginate` annotation on a controller, plain MyBatis mapper with no `LIMIT`/`OFFSET`, and a Spring Data-shaped JSON envelope in the response.

Also doubles as the template every future demo in this repo will copy from — independent Gradle build, standalone wrapper, self-contained DB.

Stack

  • Spring Boot 3.5.3 on Java 21 (matches the starter's tested baseline)
  • MyBatis (transitive via the starter)
  • H2 in-memory DB with 137 seeded report rows applied on startup
  • Standalone Gradle build (own `settings.gradle.kts` + `gradlew`) — does not share a root build with other demos

What's in the diff

File Why
`easy-paging-demo/build.gradle.kts` only meaningful dependency beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:0.4.0`
`easy-paging-demo/src/.../ReportController.java` the whole pagination contract: `@AutoPaginate(maxSize = 50)` + `PageResponse` return type
`easy-paging-demo/src/.../ReportMapper.{java,xml}` plain `SELECT` — the aspect injects pagination at runtime
`easy-paging-demo/src/.../schema.sql` + `data.sql` 137 rows, applied on startup
`easy-paging-demo/src/test/.../ReportControllerTest.java` smoke test: boots the app, hits `/reports`, asserts envelope shape and `maxSize` clamping
`README.md` top-level table updated to list this demo and its Maven Central coordinates

Verification

  • `./gradlew build` locally: BUILD SUCCESSFUL, 2/2 tests passing
    • `firstPageReturnsExpectedPaginationMetadata()` — verifies content size, totalElements=137, totalPages=28, envelope keys
    • `oversizedPageSizeIsClampedByMaxSize()` — verifies `?size=9999` clamps to 50
  • `gradlew` script committed with executable bit (`100755`) so the Linux CI runner can invoke it.

CI expectation

The `detect` job from the CI workflow added in #1 should:

  1. Detect this PR touches files under `easy-paging-demo/` (which contains a `build.gradle.kts`)
  2. Spawn one `build` job for `easy-paging-demo`
  3. Run `./gradlew build` from that directory

If the matrix detection or path-filtering misbehaves, this PR will surface it.

What's next (not in this PR)

The starter has more features that each deserve their own demo rather than crowding this one:

  • `@KeysetPaginate` (cursor pagination)
  • Custom response envelope via `PageResponseFactory`
  • Reactive variant using `kr.devslab:easy-paging-spring-boot-starter-reactive`

Follow-up PRs.

Test plan

  • CI `detect` job correctly identifies `easy-paging-demo` as the only changed demo
  • CI `build` job runs `./gradlew build` from `easy-paging-demo/` and passes (both unit tests green)
  • After merge, README on `main` renders the new demo row with working links

jlc488 added a commit that referenced this pull request May 23, 2026
Two bugs in the workflow from #1 conspired to make path-filtered builds
silently skip on every PR. Discovered while opening #2, the first demo PR,
where the build job was reported as 'skipping' even though
easy-paging-demo/ was clearly the changed directory.

Bug 1 — GitHub Actions ternary trap on fetch-depth
    fetch-depth: ${{ github.event_name == 'pull_request' && 0 || 1 }}
The intent was "0 (full history) on PRs, 1 (shallow) otherwise". But in
Actions expressions, `0` is falsy, so `0 || 1` short-circuits to `1`.
The expression evaluated to `1` on both PRs and main pushes, leaving PR
checkouts with no history beyond the merge commit.

Bug 2 — silent failure on git diff
    mapfile -t changed_files < <(git diff --name-only "$base" HEAD)
With bug 1 in effect, `git diff` exited with "fatal: bad object" because
the base SHA wasn't fetched. But process substitution does not propagate
the subshell's exit status under `set -e`, so the script kept going with
an empty `changed_files` array — and therefore an empty matrix and a
"skipped" build job. CI looked green, but it had built nothing.

Fix:
- fetch-depth: 0 unconditionally. Cost is negligible for this repo and
  removes the ternary footgun entirely.
- Run git diff in a separate statement so `set -e` actually catches a
  non-zero exit, with an explicit ::error:: pointer to the likely cause
  (shallow checkout) so the next person debugging this gets a head start.

Verification will happen on the next PR (the rebase of #2) — the matrix
should populate with easy-paging-demo and the build job should actually
execute ./gradlew build instead of skipping.
First demo in this repo. Showcases the basic offset-pagination path of
easy-paging-spring-boot-starter (0.4.0): one @AutoPaginate annotation
on a controller method, plain MyBatis mapper with no LIMIT/OFFSET, and
a Spring Data-shaped JSON envelope in the response.

Stack:
- Spring Boot 3.5.3 on Java 21
- MyBatis (transitive via the starter)
- H2 in-memory DB, schema + 137 seeded report rows applied on startup
- Standalone Gradle build (own settings.gradle.kts + gradlew)

Includes a smoke test (ReportControllerTest) that boots the app and
asserts the pagination envelope shape and maxSize clamping, so CI proves
the starter wires up correctly end-to-end.

Intentionally minimal — keyset/cursor pagination, custom response
shapes, and the reactive starter will each get their own demos under
this repo rather than bloating this one. Top-level README updated to
link this demo and its Maven Central coordinates.
@jlc488 jlc488 force-pushed the feat/easy-paging-demo branch from 2b4d455 to e4724e1 Compare May 23, 2026 05:04
@jlc488 jlc488 merged commit 5fbdf57 into main May 23, 2026
2 checks passed
@jlc488 jlc488 deleted the feat/easy-paging-demo branch May 23, 2026 05:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant