Version Packages#213
Open
github-actions[bot] wants to merge 1 commit into
Open
Conversation
226a130 to
954e742
Compare
d7947f1 to
94d25cf
Compare
5244c07 to
cce8b9a
Compare
88c5926 to
ae53d0e
Compare
ae53d0e to
93c6d4c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@kurrent/gaffer@0.5.0
Minor Changes
8aec336: Breaking:
gaffer.tomlgains a[database_config]section for node-level engine settings, and the top-levelcompilation_timeout/execution_timeoutkeys move into it. A file that still sets them at the top level now fails to load, with a message pointing at the new section.[database_config]declares the engine configuration expected on a deployment target:max_state_size(newly exposed) caps a projection's serialized state in bytes, defaulting to the server's 16 MiB. It is enforced on local runs, so a projection that would exceed the cap faults locally, catching state bloat before deploy.compilation_timeoutandexecution_timeoutare declaration only: gaffer records them for deploy-time configuration checks but does not apply them to local runs, since a wall-clock budget measured on a dev machine isn't comparable to the server's. To bound how long a local projection may run before gaffer treats it as hung, set theGAFFER_TIMEOUT_MSenvironment variable (default 5000ms). A per-[[projection]]execution_timeoutis likewise declaration only and no longer affects local runs.331f061: Breaking:
gaffer.tomlnow rejects absoluteentryandfixtures.<name>paths at load time. Previously an absolute path (e.g.entry = "/etc/passwd", or a Windows drive-letter form likeC:\...) slipped past validation while the scaffold write path already rejected it. Both surfaces now enforce the same rule: paths must be relative to the project root and must not escape it.Patch Changes
9b1f7e8: The Go runtime bindings no longer risk a rare fatal crash (
invalid pointer found on stack) under GC pressure. The runtime's integer session handles could appear in pointer-typed stack slots during FFI calls; if the GC moved the stack while a callback was running mid-call, the process aborted. Handles now stay integer-typed end-to-end on the Go side, with all casting done in C shims. The crash could hit anything embedding the bindings, including the CLI.ee1f52e: Projection errors that reach the CLI wrapped in another error now keep their original error code and diagnostics. Previously a wrapped feed error was classified as
unexpected-errorand its diagnostics were dropped.733e9d1:
gaffer deployandgaffer statuswarn when the target node's live engine settings diverge from a declared[database_config]: one line per differing knob, read from the node's options endpoint. Fixtures and local runs assumed the declared values, so a server enforcing a differentmax_state_sizeor timeout is visible before it bites. The check is advisory: a server that doesn't expose its options, or refuses the read, skips it silently, and a non-positivemax_state_sizedeclares the engine default rather than a value.gaffer status --jsonnow emits an object: aprojectionsarray (the previous per-projection entries) plus aconfigDriftarray of{"knob", "server", "local"}when the target diverges. Machine consumers see the divergence without a second call.gaffer deploy --jsonis unchanged; its warning prints on stderr, keeping the stdout payload clean while CI logs still show it.f1c46c3:
gaffer dev --debugno longer hangs when a Restart arrives as the session is tearing down; the restart returns cleanly during shutdown instead of leaving the debug adapter's read goroutine waiting forever.f118249:
gaffer deploygains--dry-runand a stable exit-code contract for CI.--dry-runshows the plan and applies nothing. The exit code is now0succeeded or nothing to do,1an error, and2changes are pending (--dry-runonly). A new3means refused by a guardrail: confirmation was needed but there was no terminal or--yes, or--no-validatewas used against production.--dry-runreuses the same per-projection plan output as a confirmed deploy, and its--jsonis the same array shape, so a pipeline can branch on exit2or parse the would-be outcomes. The guardrail exit code3also applies torecreateand the operate verbs when they can't confirm non-interactively. A production--no-validaterefusal now prints its reason instead of exiting silently.ff67802:
gaffer deploynow measures its per-projection verdict column by terminal display width, so projection names with multi-byte or full-width characters no longer over-pad the column and misalign the verdicts.6ef7402:
gaffer deploycreates or updates projections on an environment fromgaffer.toml: it creates the ones not yet on the server, updates the ones whose definition changed, and skips the ones already in sync (matched by content hash). The emit flag is always sent explicitly, so an update never clears it.With no argument it deploys every projection in
gaffer.toml; name one to deploy just it. A change to engine version or track-emitted-streams can't be applied in place (it would mean recreating the projection and dropping its state), sogaffer deployreports it and leaves the projection untouched. On a terminal it shows live per-projection progress; pass--jsonfor machine-readable output.0614520:
gaffer deploy's interactive view no longer drops the last projection's result line when the run finishes. The final row's commit and the program quit now run as one ordered step, so the verdict is always flushed before the view tears down (a single-projection deploy previously showed only the summary).69aceed:
gaffer deploynow flags a projection whose deployed definition was changed outside gaffer since its last deploy, so a deploy doesn't silently revert an out-of-band change.--yes) apply warnings show a caution ("<name>was changed outside gaffer since its last deploy; deploying overwrites it"), naming the tool when another tool made the change.gaffer deploy --jsoncarriesexternalChange: trueon the affected item, alongsidelogicChange, so CI can alert.Gaffer is the canonical source of truth, so it still deploys - the drift is surfaced, not refused. Degrades silently against a KurrentDB without the deploy-metadata field.
1edbb21:
gaffer deploynow plans the whole run before touching the server and confirms before applying. It shows what would change per projection (created/updated/skipped/refused) against the target's reported cluster name, then asks before writing.--yesskips the prompt; without a terminal (or with--json) it won't apply unconfirmed, so pass--yesin scripts. An update whose deployed projection is currently faulted is flagged, since updating won't clear the fault.A server that reports itself as production gets a louder confirmation and refuses
--no-validate. Production is read from the server's own$server-info, never inferred from the environment name, so a connection that points at production is guarded even if its env is labelled otherwise. Databases that don't report production status are unaffected.36cd18b:
gaffer deploynow records tool metadata on every projection it creates or updates, so a projection carries who deployed it and from where: the tool (Gaffer) and version, the operation, the source revision, and the acting identity. It follows a shared convention that other KurrentDB tools can write and display.revisiondefaults to the project's git commit (suffixed+changeswhen the working tree is dirty); setGAFFER_REVISIONin CI to record the canonical commit.actordefaults to the identity gaffer connects as (the basic-auth user or OAuth client), omitted for an anonymous connection; setGAFFER_ACTORin CI to record the pipeline identity.The metadata rides on the projection's definition event and is best-effort: against a KurrentDB that predates the feature it is silently ignored and deploy behaves exactly as before.
a59afe0:
gaffer deploy's plan preview now lists each projection, not just totals. Every projection that would change shows a verdict -create,update,rebuild,refused, orfailed- and a dimmed detail column carrying the refusal reason or the failure error in full. In-sync projections stay a count only, so unchanged ones don't drown the signal.cc92ece:
gaffer deploynow compiles every projection before sending anything to the server. If any fails to compile, or compiles but carries errors that would fault on the server (such as a quirk that reproduces an upstream engine crash), the whole deploy is refused up front, so a bad projection can't leave the earlier ones already applied. The check runs locally, before connecting, and--no-validateskips it.1206961:
gaffer deploynow treats a changed projection query as a logic change. The new code may read already-processed events differently, so the accumulated state could be wrong. By default deploy keeps the checkpoint, applies the update, and flags the change in the plan. Pass--reset-on-logic-changeto rebuild instead: each logic-changed projection is stopped, updated, reset to the beginning, and restarted so it reprocesses from zero with the new logic. An emitting projection re-emits on a rebuild and may duplicate into its target streams, so the plan warns and points atgaffer recreate --delete-emittedfor a clean-emit rebuild.A continued logic change shows as
logicChange: trueon its--jsonitem, so CI can alert on it. A change to engine version or track-emitted-streams still can't be applied in place; deploy now points atgaffer recreaterather than just refusing.ad83f81:
gaffer diff <projection>compares a projection's local definition against what's deployed on KurrentDB and reports its state: in sync, drifted, not deployed, or untracked.When the query differs, the source is shown in an external diff viewer. By default this is
git diff --no-index; setGAFFER_EXTERNAL_DIFFto override. Pass--jsonfor machine-readable output.b5cbc4e:
gaffer diffrenders the query source diff itself instead of shelling out to an external viewer. Every line of both sides is shown with the changes marked in place: dual line-number gutters, +/- colouring, and the span that changed within a line highlighted. The diff is computed on the same canonical form as the drift verdict, so it always matches the+N -Mstat thatgaffer diffandgaffer statusreport. It now works without git installed, when piped, and in CI.Set
GAFFER_EXTERNAL_DIFFto open an external viewer instead (e.g.git diff,delta,difft); it is no longer the default path.ce0de95: Projection info now reports whether a projection writes events.
ProjectionInfogains anemitsEventsflag, true when the projection callsemit,linkTo,linkStreamTo, orcopyTo. It is detected on every compile from the source, so consumers no longer need to inspect shape counts.gaffer infoshows it ("Emits events: yes");gaffer info --jsonand the MCPget_projection_infoandvalidate_projectiontools includeemitsEvents; the testing library exposes it asinfo.settings.emitsEvents.36ee512:
gaffer rollback <projection> <hash>rolls a deployed projection back to a prior version from its history, stampedoperation: rollbackin the deploy ledger. The target is named by its content hash fromgaffer history; any unique prefix of 4 or more characters works. It confirms first with the current-to-target query diff (--yesskips). The apply is in place: processing continues from the current checkpoint, and local files stay untouched, sogaffer diffshows the rollback as drift until local is reconciled. A version differing in engine version or emitted-stream tracking is refused, pointing atgaffer recreate.The
gaffer historytimeline gainsr: it opens the same confirm as a modal for the selected entry, applies ony, and reloads the timeline so the new rollback entry appears on top.eeaff5f: Event-processing errors under
engine_version 2now carry thequirk.handlerError.wedgesOnV2(error severity) diagnostic. On deployed V2, an exception thrown while processing an event never faults the projection. It wedges silently:statusstaysRunningwhile processing and persistence have stopped, and nothing is logged. Gaffer keeps faulting the event locally, which is the behaviour V2 should have, and the diagnostic rides the error to explain the divergence. It fires for any event-processing throw (handler, state load,$created,$deleted, state serialization, timeout); a throwingpartitionByis exempt because the server computes partition keys on its read loop, which faults properly.15a6296:
gaffer history <projection>shows a deployed projection's history: every operation on it, newest first, with who made it and how.↑/↓(orj/k),g/G,PgUp/PgDn;qorEscquits. Older entries page in as you scroll.edited-externallywhen the definition changed outside gaffer,changed-by(with the tool named) for another tool's write,enabled/disabledfor a lifecycle change,reconfiguredwhen a checkpoint or performance setting moved,rewrittenfor an identical redeploy, orcreated/deleted.--jsonit prints the latest entries instead (--limit, default 100, or--all). Each--jsonentry carries the full content hash, its classification and flags, the tool metadata, and any configuration knobs that moved.Against a KurrentDB without the deploy-metadata field it degrades to the history with timestamps and content hashes only.
bf1f2ef:
gaffer historygainsd: a diff of the selected entry against the version before it, shown in an overlay on the timeline. It answers "what changed at this entry" the waygit showdoes. The previous content version is the baseline (state changes are skipped; their definition is identical), the first version diffs from empty, and a state-change entry reports "no definition change".The diff uses the same aligned renderer and tints as
gaffer diff, with any engine version, emit, or tracking change named above it. The arrow keys keep scrubbing the timeline underneath, so the diff re-renders entry by entry, walking a definition's evolution in place.PgUp/PgDnscroll a long diff;esc,d, orqcloses back to the timeline. A baseline on an older page is fetched automatically.95a5410:
gaffer dev --jsonnow exits non-zero if it fails to write its output stream (for example a broken pipe to the editor), instead of silently finishing with a truncated stream.15602f4:
gaffer statusandgaffer diffare now ledger-aware, reading the tool metadata gaffer stamps on deploy to say more thanuntrackedordrifted.orphan(gaffer deployed it, now gone fromgaffer.toml- a deletion candidate) or plainuntracked, with the deploying tool named when its metadata is present.--jsonreports this asowner, includingforeignfor a projection another tool manages.local ahead(you've edited local since your deploy) orchanged externally(a tool or a direct write changed the server since).--jsonsplits the latter intochanged-by-toolandchanged-server.Both surface in the status table and detail and in
gaffer diff. The status table gains LAST DEPLOY and DEPLOYED VIA columns, and naming a projection (or runninggaffer diff) shows the deploy provenance behind it: when, the tool and version, the deployer, and the source revision. The last-deploy date comes from the event itself, so it shows even for a projection with no tool metadata. In--json:owner,attribution, a top-levellastDeployedtimestamp, andlastWrite(the tool and actor). Against a KurrentDB without the deploy-metadata field it degrades to the previous behaviour.189eebd: The MCP server gains
deploy_apply, so an assistant can deploy projections fromgaffer.tomllikegaffer deploy:gaffer deploy --json, and every write stampedoperation: deployin the ledger.[database_config]divergence.resetOnLogicChangerebuilds destroys state, so it always asks; on production that confirmation requires typing the environment name.33ffb38: The MCP server gains read-only deploy visibility, mirroring the CLI's machine output:
deploy_statusshows each projection's runtime state and drift verdict on an environment, plus any[database_config]divergence, likegaffer status --json.deploy_planpreviews what a deploy would change without applying anything, likegaffer deploy --dry-run --json.deploy_historyreads a projection's per-deploy audit log with paging, likegaffer history --json.All three accept an
envargument and default to the default environment. Applying changes stays in the CLI, behind its confirmation gates.15cc888: The MCP server gains the operate verbs, so an assistant can manage a deployed projection's lifecycle with a human in the loop:
deploy_pause/deploy_resume/deploy_abortmirrorgaffer disable/enable/disable --abort.deploy_recreaterebuilds from local config likegaffer recreate, gated on the compile and diagnostics preflight, and stampsoperation: recreatein the deploy ledger.deploy_rollbackredeploys a prior version by content hash fromdeploy_history, likegaffer rollback, and stampsoperation: rollback.deploy_deletemirrorsgaffer delete, includingdeleteEmitted.Writes against a server that reports itself as production require a confirmation answered through the MCP client (elicitation); the assistant cannot answer it. The prompt front-loads
PRODUCTION [env.<name>]:and states each verb's consequence. Recreate and delete destroy state with no undo, so they ask every time; on production their confirmation requires typing the projection name. A client without elicitation support cannot perform gated writes; the refusal names the CLI command to run instead.deploy_statusanddeploy_plannow also echo the resolved target and production flag.73af704:
gaffer enable,gaffer disable, andgaffer deletemanage deployed projections on an environment, named directly (they need not be ingaffer.toml).gaffer enable <projection>starts a projection so it resumes from its last checkpoint.gaffer disable <projection>stops it, writing a final checkpoint;--abortskips that checkpoint so a later enable replays from the last one. Disabling is recoverable, so it confirms only against production.gaffer delete <projection>removes the projection with its state and checkpoint streams, keeping emitted streams unless--delete-emittedis passed. It always confirms, and disables the projection first since the server won't delete an enabled one.--yesskips the confirmation; without a terminal (or with--json) a guarded verb won't proceed unconfirmed. Production gets a louder confirm and is read from the server's$server-info, never the env label.b2071d0: A per-projection config error (e.g.
track_emitted_streamswithengine_version 2) no longer blocks every command. Previously one misconfigured projection failedgaffer.tomlloading outright, sogaffer info <good-projection>died on an unrelated projection's error. Now config validation splits into structural checks (environments, duplicate names) that stay fatal, and per-projection checks that are deferred; a bad projection only blocks operations on itself. The inspection commands (status,diff,info) show it asinvalidthrough one shared rendering;deployrefuses just that one;recreateand the operate verbs fail only when you name it. Mirrors the per-projection degradation already used for compile errors.6571975:
gaffer recreatenow stamps its rebuild in the deploy ledger, sogaffer historyattributes it to gaffer instead of showing anonymous lifecycle steps. The create carriesoperation: recreatewith the usual tool, actor, and source revision.gaffer historyshows a recreate as a single entry: the disable and delete writes it performs are folded into therecreaterow, and the detail panel notes the projection was reprocessed from zero.--jsonkeeps every write as its own entry, with the create'skindset torecreate.42b7612:
gaffer recreate <projection>destroys and rebuilds a deployed projection from local config: stop it, delete it (with its state and checkpoint streams), and create it fresh, reprocessing from zero. It applies a create-only change that deploy can't make in place (engine version, track-emitted-streams), or rebuilds a wedged projection an in-place reset can't fix. The projection is compiled before anything is deleted, so a broken local definition can't leave you with nothing to rebuild;--no-validateskips that check (production refuses it). It always confirms, more prominently against production, with--yesfor non-interactive use.--delete-emittedalso wipes the emitted streams so the rebuild doesn't re-emit duplicates.6625608:
gaffer statusshows the runtime state of projections on an environment and how they compare to local config: running, stopped or faulted, progress, and whether each is in sync, drifted, not deployed, or untracked.With no argument it lists every local and deployed projection as a table; name a projection for its detail. Pass
--jsonfor machine-readable output.6602c5f:
gaffer statusandgaffer diffno longer abort when a local projection fails to compile. A compile error is now a per-projection condition, not a whole-command failure.gaffer statusshows the broken projection asinvalidand still renders the rest of the table with their real runtime state and drift.gaffer diffstill shows the source diff, engine version, and track-emitted-streams, markingemitunknown because deriving it needs a successful compile. Both exit 0, and the compile error is shown so you know what to fix.e59a851:
track_emitted_streamswithengine_version 2is now reported as a diagnostic rather than a config-load error. The runtime emitsquirk.trackEmittedStreams.unsupportedOnV2(error severity) off the resolved definition, whether the flag comes fromgaffer.tomloroptions({ trackEmittedStreams: true })in the source. This matches how the other V2 incompatibilities (bi-state,outputState) already surface.gaffer info,gaffer dev, andgaffer diffnow compile such a projection and show its full analysis plus the flag, instead of failing with a bare config error.gaffer deployandgaffer recreatestill refuse it at preflight (recreate before deleting anything), and the MCPvalidatetool reports it invalid with the diagnostic. The projection session no longer throws on the combination.@kurrent/gaffer-runtime@0.3.1
Patch Changes
ce0de95: Projection info now reports whether a projection writes events.
ProjectionInfogains anemitsEventsflag, true when the projection callsemit,linkTo,linkStreamTo, orcopyTo. It is detected on every compile from the source, so consumers no longer need to inspect shape counts.gaffer infoshows it ("Emits events: yes");gaffer info --jsonand the MCPget_projection_infoandvalidate_projectiontools includeemitsEvents; the testing library exposes it asinfo.settings.emitsEvents.eeaff5f: Event-processing errors under
engine_version 2now carry thequirk.handlerError.wedgesOnV2(error severity) diagnostic. On deployed V2, an exception thrown while processing an event never faults the projection. It wedges silently:statusstaysRunningwhile processing and persistence have stopped, and nothing is logged. Gaffer keeps faulting the event locally, which is the behaviour V2 should have, and the diagnostic rides the error to explain the divergence. It fires for any event-processing throw (handler, state load,$created,$deleted, state serialization, timeout); a throwingpartitionByis exempt because the server computes partition keys on its read loop, which faults properly.e59a851:
track_emitted_streamswithengine_version 2is now reported as a diagnostic rather than a config-load error. The runtime emitsquirk.trackEmittedStreams.unsupportedOnV2(error severity) off the resolved definition, whether the flag comes fromgaffer.tomloroptions({ trackEmittedStreams: true })in the source. This matches how the other V2 incompatibilities (bi-state,outputState) already surface.gaffer info,gaffer dev, andgaffer diffnow compile such a projection and show its full analysis plus the flag, instead of failing with a bare config error.gaffer deployandgaffer recreatestill refuse it at preflight (recreate before deleting anything), and the MCPvalidatetool reports it invalid with the diagnostic. The projection session no longer throws on the combination.@kurrent/projections-testing@0.2.2
Patch Changes
ce0de95: Projection info now reports whether a projection writes events.
ProjectionInfogains anemitsEventsflag, true when the projection callsemit,linkTo,linkStreamTo, orcopyTo. It is detected on every compile from the source, so consumers no longer need to inspect shape counts.gaffer infoshows it ("Emits events: yes");gaffer info --jsonand the MCPget_projection_infoandvalidate_projectiontools includeemitsEvents; the testing library exposes it asinfo.settings.emitsEvents.Updated dependencies [ce0de95]
Updated dependencies [eeaff5f]
Updated dependencies [e59a851]
@kurrent/gaffer-runtime-darwin-arm64@0.3.1
@kurrent/gaffer-runtime-darwin-x64@0.3.1
@kurrent/gaffer-runtime-linux-arm64@0.3.1
@kurrent/gaffer-runtime-linux-x64@0.3.1
@kurrent/gaffer-runtime-win32-x64@0.3.1
@kurrent/gaffer-darwin-arm64@0.5.0
@kurrent/gaffer-darwin-x64@0.5.0
@kurrent/gaffer-linux-arm64@0.5.0
@kurrent/gaffer-linux-x64@0.5.0
@kurrent/gaffer-win32-x64@0.5.0