Skip to content

ci(Spec): Run the Flagsmith SDK behavioural spec - #430

Merged
talissoncosta merged 8 commits into
mainfrom
feat/sdk-spec
Oct 21, 2026
Merged

talissoncosta merged 8 commits into
mainfrom
feat/sdk-spec

Conversation

@talissoncosta

@talissoncosta talissoncosta commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Contributes to the Flagsmith SDK behavioural spec rollout (same setup as Flagsmith/flagsmith-python-client#263 and Flagsmith/flagsmith-nodejs-client#307).

Runs the spec against this SDK on every pull request and push to main, using the spec's steps-file design (Flagsmith/sdk-spec#3 and Flagsmith/sdk-spec#4).

  • sdk-spec/steps.mts: a function creating the client and one function per When step, each marked with the step's text and implemented with SDK calls. The spec's Node.js harness runs it, and it doubles as a CI-checked usage example.
  • sdk-spec/Dockerfile: builds the SDK from source, packs lib/flagsmith (published as @flagsmith/flagsmith) and installs the tarball, so the spec runs against the package as users get it. Then it runs the steps file under the harness. Dockerfile.dockerignore keeps host node_modules and build output out of the image.
  • .github/workflows/sdk-spec.yml: calls the spec's reusable workflow with language: nodejs. It's pinned to v0.3.0.
  • sdk-spec/tsconfig.json: type-checks steps.mts against the built package. The Dockerfile runs it after the bundle, so a type error fails the spec job.
  • tsconfig.json: excludes sdk-spec, which targets Node 24 rather than the SDK's build settings.

How the steps map onto this client-side SDK:

  • One identity per client. createClient returns a fresh createFlagsmithInstance(). The first flags step calls init(); later ones call identify(), getFlags(), or logout() when getting environment flags after an identity, as an app would. Flags are read back from the client with getAllFlags().
  • Traits are passed to the SDK as plain values, which init() and identify() accept.
  • It runs under Node through the isomorphic entry. Browser-only parts (the localStorage cache, realtime updates, React hooks) aren't covered.

Notes:

  • This repo has no Renovate or Dependabot config, so unlike the Python and Node.js PRs, the spec version in sdk-spec.yml has to be bumped by hand. Keep the uses: ref and spec-ref in sync.
  • The spec gives every SDK a server-side environment key. This client-side SDK passes with one, but real apps use a client-side key, so the spec could miss client-key behaviour. That's for the spec to decide; nothing in this PR depends on it.

How did you test this code?

Ran the spec at v0.3.0 locally, following its README:

# In Flagsmith/sdk-spec: start Flagsmith
docker compose up --detach --wait

# In this repo: build the SDK image with the spec's Node.js harness
docker build -t sdk-spec-sdk -f sdk-spec/Dockerfile --build-context harness=<sdk-spec>/harness/nodejs .

# In Flagsmith/sdk-spec/runner: run the spec
FLAGSMITH_SDK_URL=http://flagsmith:8000 \
SDK_COMMAND="docker run -i --rm --network sdk-spec_default sdk-spec-sdk" \
uv run pytest -v
test_environment_flags_are_returned_as_configured_in_flagsmith PASSED
test_identity_flags_reflect_segment_overrides_matched_by_traits PASSED

No scenario gets identity flags and then environment flags on one client yet, so I checked that by sending the harness those two steps directly, against a fake API that returns different flags for each: environment flags come back after the identity step. Before the logout() change they came back as the identity's flags.

tsc -p sdk-spec passes, and fails on a deliberate type error in the steps file.

talissoncosta and others added 2 commits October 21, 2026 12:02
Runs the Flagsmith SDK behavioural spec (https://github.com/Flagsmith/sdk-spec)
against this SDK on every pull request and push to main.

- spec-adapter/: an HTTP adapter implementing the adapter protocol, plus a
  Dockerfile that builds the SDK from source.
- .github/workflows/sdk-spec.yml: calls the spec's reusable workflow, pinned
  to v0.1.1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Matches the Node.js SDK's adapter: the Dockerfile packs lib/flagsmith and
installs the tarball, so the spec runs against the package as published,
and the adapter is TypeScript run natively by Node 24.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@talissoncosta
talissoncosta requested a review from a team as a code owner October 21, 2026 11:21
@talissoncosta
talissoncosta requested review from kyle-ssg and removed request for a team October 21, 2026 11:21
talissoncosta and others added 2 commits October 21, 2026 12:39
v0.2.0 replaces the HTTP adapter with a steps file run by the spec's
language harness. sdk-spec/steps.mts implements each step with SDK calls,
and sdk-spec/Dockerfile runs it under the Node.js harness against the
packed SDK. Pinned to feat/v0.2.0 until v0.2.0 is tagged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
khvn26
khvn26 previously approved these changes Oct 21, 2026
v0.3.0 renames the client step's marker to "Create the SDK client"; the
runner now creates the client before a scenario's first When step.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the steps file

- "Gets the environment flags" now calls logout() when the client has an
  identity: getFlags() alone fetched the identity's flags again.
- Traits go to init() and identify() as given; both already wrap plain
  values, so the conversion and its `as ITraits` are gone.
- One helper runs init() on the first load and reloads after.
- sdk-spec/tsconfig.json type-checks steps.mts against the built package,
  inside the Docker build, so a type error fails the spec job.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@talissoncosta talissoncosta changed the title ci: Run the Flagsmith SDK behavioural spec ci(Spec): Run the Flagsmith SDK behavioural spec Oct 21, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
khvn26 pushed a commit to Flagsmith/sdk-spec that referenced this pull request Oct 21, 2026
The spec PRs for the nine SDKs merged and their feat/sdk-spec branches were deleted, so the matrix failed checking them out. js-client keeps feat/sdk-spec until Flagsmith/flagsmith-js-client#430 merges.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@talissoncosta
talissoncosta merged commit 94f5485 into main Oct 21, 2026
2 checks passed
@talissoncosta
talissoncosta deleted the feat/sdk-spec branch October 21, 2026 15:41
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.

2 participants