Skip to content

ci: run Next.js adapter integration suite against harper PRs (downstream gate) - #1385

Merged
kriszyp merged 10 commits into
mainfrom
kris/nextjs-caller-ci
Jul 18, 2026
Merged

kriszyp merged 10 commits into
mainfrom
kris/nextjs-caller-ci

Conversation

@kriszyp

@kriszyp kriszyp commented Jun 18, 2026 •

Copy link
Copy Markdown
Member

What

Adds .github/workflows/integration-tests-nextjs.yml, an advisory downstream check that runs the @harperfast/nextjs Playwright suite against the harper build from the current PR whenever adapter-relevant paths change.

The workflow explicitly checks out HarperFast/nextjs@main, packs the current harper PR, installs that tarball into the adapter test workspace, installs fixture dependencies, and runs the suite on Node 20, 22, and 24. Keeping the checkout in this caller avoids reusable-workflow checkout context selecting the harper repository and looking for adapter scripts in the wrong package.json.

Current harper and rocksdb-js require Node 22.18 or newer. The Node 20 matrix job therefore keeps Next.js and Playwright on Node 20 while building and spawning the harper child process with Node 22 via the integration harness HARPER_RUNTIME override.

Advisory, non-blocking

This deliberately tracks Next.js main, so a Next.js-side regression is visible on the next relevant harper PR. Because the result can depend on downstream health, this workflow must remain advisory and must not be configured as a required branch-protection check.

Verification

  • Downstream run 29547153563: all Node 20/22/24 jobs passed, with 21 Playwright tests per job.
  • Repository format, lint, unit, build, and caller-workflow validation checks passed on the final head.

Updated by Codex (OpenAI).

Closes the regression loop from the nextjs side: when a harper PR touches the
HTTP/cache/resource/server paths, call HarperFast/nextjs's reusable integration
workflow with harper_ref = this PR's head SHA, so the adapter's Playwright suite
runs against the in-PR harper build.

Depends on HarperFast/nextjs#49 (the workflow_call + harper_ref input). Pin the
@main ref to the #49 merge SHA before merging.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

Comment thread .github/workflows/integration-tests-nextjs.yml Outdated
@claude

claude Bot commented Jun 18, 2026 •

Copy link
Copy Markdown
Contributor

Reviewed; no blockers found.

kriszyp added a commit to HarperFast/nextjs that referenced this pull request Jun 19, 2026
- next-16-secrets.pw.ts: use auto-retrying toHaveText assertion instead of
  innerText() + toBe (avoids hydration/render-delay flakiness)
- rename next-16-{coexist,secrets}/next.config.ts -> .mjs (pure-JS fixtures;
  avoids TypeScript install prompt, matches next-16-caching convention)
- remove .github/workflows/CALLER-SNIPPET.md: the caller workflow now lives in
  HarperFast/harper#1385

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kriszyp added a commit to HarperFast/nextjs that referenced this pull request Jul 14, 2026
)

* test: add framework-hosting §5.3 coverage gaps + parameterized CI harper_ref

Deliverable 1 — test coverage:
- fixtures/next-16-secrets: startup secrets injection via Harper's built-in
  loadEnv plugin. The .env.secrets file is read before @harperfast/nextjs boots,
  injecting MOCK_API_KEY into process.env. Next.js Server Component reads the
  value at render time (force-dynamic). Covers §5.3 sub-case (a).
- fixtures/next-16-coexist: Harper REST API (rest: true + jsResource Greeting)
  and Next.js app sharing port 9926. Test asserts both GET /Greeting (Harper REST)
  and GET / (Next.js page) return expected responses on the same URL base.
  Covers §5.3 sub-case (c).
- Sub-case (b) tag-based cache invalidation is already covered by the existing
  revalidateTag test in integrationTests/next-16-caching.pw.ts — not duplicated.

Deliverable 2 — parameterized CI:
- Adds workflow_call trigger to integration-tests.yml with harper_ref and
  node-version inputs. When harper_ref is non-empty, clones HarperFast/harper at
  that ref, builds it, npm-packs it, and installs the tarball over the pinned
  harper devDependency — ensuring both the test harness (require.resolve('harper'))
  and the fixtures pick up the override build.
- Fixes the matrix node-version expression to use inputs.node-version (works for
  both workflow_call and workflow_dispatch) instead of github.event.inputs.
- Raises test timeout from 5 to 15 minutes to match actual fixture boot costs.
- Adds .github/workflows/CALLER-SNIPPET.md with a ready-to-drop snippet for
  HarperFast/harper to trigger this workflow on cache/HTTP PRs via workflow_call.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: address PR #49 review comments

- next-16-secrets.pw.ts: use auto-retrying toHaveText assertion instead of
  innerText() + toBe (avoids hydration/render-delay flakiness)
- rename next-16-{coexist,secrets}/next.config.ts -> .mjs (pure-JS fixtures;
  avoids TypeScript install prompt, matches next-16-caching convention)
- remove .github/workflows/CALLER-SNIPPET.md: the caller workflow now lives in
  HarperFast/harper#1385

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: fold coexist + secrets coverage into next-16 fixture; use actions/checkout

Per review: rather than dedicated next-16-coexist / next-16-secrets fixtures,
merge both harper-specific checks into the existing plain next-16 fixture —
one fixture boot instead of two.

- next-16/config.yaml: add rest + jsResource(greeting.js) + loadEnv(.env.secrets)
- next-16/app/page.js: force-dynamic, render MOCK_API_KEY for the secrets assertion
- next-16.pw.ts: add REST-coexistence (§5.3c) and secrets-injection (§5.3a) tests
- remove next-16-coexist / next-16-secrets fixtures and their .pw.ts files
- integration-tests.yml: replace raw git clone override with actions/checkout
  (repository + ref handles branch/tag/SHA natively)

Validated locally against system Chrome: all 5 next-16 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kriszyp
kriszyp marked this pull request as ready for review July 14, 2026 21:12
Comment thread .github/workflows/integration-tests-nextjs.yml Outdated
Comment thread .github/workflows/integration-tests-nextjs.yml Outdated
Comment thread .github/workflows/integration-tests-nextjs.yml Outdated
Comment thread .github/workflows/integration-tests-nextjs.yml
- Drop the dead `cache/**` path filter — no top-level cache/ dir exists;
  caching lives under resources/**, already covered.
- Pin the HarperFast/nextjs reusable workflow ref to nextjs#49's merge SHA
  (d4b5ac9) now that it's merged, instead of leaving @main + a pre-merge TODO.
- Add an explicit least-privilege `permissions: contents: read` block.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment thread .github/workflows/integration-tests-nextjs.yml Outdated
kriszyp and others added 2 commits July 14, 2026 20:07
A paths-filtered pull_request trigger cannot back a required status check:
if the paths filter skips the workflow, the required check never reports and
the PR is stuck waiting. Remove the trigger paths filter so the workflow runs
on every PR, and move the path-relevance decision inside the workflow.

- changes job: git diff against the PR base decides whether adapter-relevant
  paths changed (same effective path list the trigger used to filter on).
- nextjs-integration job: runs the reusable suite only when relevant.
- required job: always runs, reports the stable required status -- success
  when the suite passed or was skipped as irrelevant, failure only when it
  actually failed. Mark this job as the required check in branch protection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Org policy requires all actions pinned to a full-length commit SHA;
actions/checkout@v4 was rejected. Use the same pin the other workflows use.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kriszyp and others added 4 commits July 16, 2026 10:35
Track nextjs main instead of a SHA pin so a nextjs-main regression
against harper surfaces on the next harper PR, rather than being frozen
out by the pin. Drop the required gate job since this is now advisory,
non-blocking CI -- it must not be marked as a required status check in
branch protection.

Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Comment thread .github/workflows/integration-tests-nextjs.yml
kriszyp and others added 2 commits July 16, 2026 19:13
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>

@heskew heskew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CI workflow: actions SHA-pinned, permissions: contents: read, no secrets, no PR-controlled interpolation, job timeout set, and it ran green on this PR's own head. The advisory-only design (internal changes job instead of a required paths-filter) resolves the earlier trapped-check concern. LGTM.

🤖 Reviewed via cross-model pipeline; approved by @heskew.

@kriszyp
kriszyp merged commit 8b1c12b into main Jul 18, 2026
98 of 100 checks passed
@kriszyp
kriszyp deleted the kris/nextjs-caller-ci branch July 18, 2026 21:23
dawsontoth added a commit that referenced this pull request Jul 20, 2026
…ency call

Unrelated to the two-phase deploy feature — fixes a pre-existing type error on
main (introduced by #1688's commit-latency analytics) that main's other build
steps swallow via `|| true`/`continue-on-error`, but the newly-added Next.js
adapter integration workflow (#1385) runs the build without that tolerance and
so fails on it (tsc exit 2) for every PR built on current main.

`commitResolution` is declared with the wider `Promise<number | void> | void`
(the abort() branch reassigns it), but at this call site it is the `commit()`
promise already cast to `Promise<void>` on the line above. recordCommitLatency
only awaits it for timing and never reads the resolved value, so the cast is
type-only with no runtime effect — matching the author's existing cast and
safety comment two lines up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

3 participants