Skip to content

feat(apps): export ENGINE_VERSION from definition layer#40183

Open
d-gubert wants to merge 2 commits intofeat/apps-engine-splitfrom
feat/apps-engine-split--pr1-engine-version
Open

feat(apps): export ENGINE_VERSION from definition layer#40183
d-gubert wants to merge 2 commits intofeat/apps-engine-splitfrom
feat/apps-engine-split--pr1-engine-version

Conversation

@d-gubert
Copy link
Copy Markdown
Member

@d-gubert d-gubert commented Apr 16, 2026

Proposed changes (including videos or screenshots)

Adds src/definition/version.ts which reads the package version via resolveJsonModule and exports it as ENGINE_VERSION.

Replaces AppPackageParser.getEngineVersion() — which resolved the version by traversing the filesystem relative to __dirname — with a direct import of ENGINE_VERSION. This removes the assumption that package.json lives at a predictable relative path, which will break when AppPackageParser moves to a different package during the
apps-engine split.

Issue(s)

Steps to test or reproduce

Further comments

Related to the "Apps-Engine split" stack:

Summary by CodeRabbit

  • Refactor
    • Version detection mechanism optimized to use compile-time constants instead of dynamic runtime file system access, improving application startup performance and system reliability.
    • Enhanced TypeScript configuration to properly support JSON module imports, improving build process stability and compatibility.

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot Bot commented Apr 16, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 16, 2026

⚠️ No Changeset found

Latest commit: 7664485

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

Walkthrough

The changes refactor Apps Engine version detection from dynamic runtime filesystem operations to a compile-time constant. A new version.ts module exports ENGINE_VERSION by reading package.json, and AppPackageParser.ts is updated to import and use this constant instead of fetching the version at runtime.

Changes

Cohort / File(s) Summary
Version Detection Module
packages/apps-engine/src/definition/version.ts
New module that exports ENGINE_VERSION constant by detecting runtime location and selecting the appropriate package.json path, then extracting the version field via dynamic require().
Version Consumer Update
packages/apps-engine/src/server/compiler/AppPackageParser.ts
Removes filesystem-based version detection logic; now imports ENGINE_VERSION constant and initializes appsEngineVersion directly, eliminating fs dependency and the getEngineVersion() method.
TypeScript Configuration
packages/apps-engine/tsconfig.json
Enables resolveJsonModule compiler option to allow JSON module imports during the build process.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

type: feature

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: exporting ENGINE_VERSION from the definition layer, which is the core objective of this changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.81%. Comparing base (ceefff9) to head (7664485).

Additional details and impacted files

Impacted file tree graph

@@                   Coverage Diff                   @@
##           feat/apps-engine-split   #40183   +/-   ##
=======================================================
  Coverage                   69.81%   69.81%           
=======================================================
  Files                        3296     3296           
  Lines                      119173   119173           
  Branches                    21479    21491   +12     
=======================================================
+ Hits                        83197    83205    +8     
+ Misses                      32668    32652   -16     
- Partials                     3308     3316    +8     
Flag Coverage Δ
e2e 59.72% <ø> (+<0.01%) ⬆️
e2e-api 46.25% <ø> (+0.01%) ⬆️
unit 70.58% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@d-gubert d-gubert changed the title feat(apps-engine): export ENGINE_VERSION from definition layer feat(apps): export ENGINE_VERSION from definition layer Apr 16, 2026
@d-gubert d-gubert force-pushed the feat/apps-engine-split--pr1-engine-version branch from bdb5d73 to 2ab8b32 Compare April 16, 2026 22:05
@d-gubert d-gubert force-pushed the feat/apps-engine-split--pr1-engine-version branch from a4a14c1 to 6ea43b5 Compare April 22, 2026 20:40
Adds `src/definition/version.ts` which reads the package version via
`resolveJsonModule` and exports it as `ENGINE_VERSION`.

Replaces `AppPackageParser.getEngineVersion()` — which resolved the
version by traversing the filesystem relative to `__dirname` — with a
direct import of `ENGINE_VERSION`. This removes the assumption that
`package.json` lives at a predictable relative path, which will break
when `AppPackageParser` moves to a different package during the
apps-engine split.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

fix(apps-engine): fix ENGINE_VERSION runtime path in compiled output

Static `import { version } from '../../package.json'` resolves correctly
during TypeScript compilation (source lives at src/definition/) but the
emitted require('../../package.json') exits the package root at runtime
once compiled to definition/version.js (outDir='.', rootDir='./src').

Switching to require('../package.json') — which is the correct path
relative to the compiled output — and bypassing TypeScript's compile-time
module resolution avoids the path mismatch entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@d-gubert d-gubert force-pushed the feat/apps-engine-split--pr1-engine-version branch from 6ea43b5 to 04703c2 Compare April 27, 2026 11:46
@d-gubert d-gubert changed the base branch from feat/apps-engine-split to develop April 27, 2026 12:00
@d-gubert d-gubert changed the base branch from develop to feat/apps-engine-split April 27, 2026 12:00
@d-gubert d-gubert force-pushed the feat/apps-engine-split--pr1-engine-version branch from 04703c2 to 7664485 Compare April 27, 2026 12:09
@d-gubert d-gubert marked this pull request as ready for review April 27, 2026 22:52
@d-gubert d-gubert requested a review from a team as a code owner April 27, 2026 22:52
@coderabbitai coderabbitai Bot added the type: feature Pull requests that introduces new feature label Apr 27, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/apps-engine/src/definition/version.ts (2)

1-11: Trim the leading doc block per coding guidelines.

The repo guideline for **/*.{ts,tsx,js} is to avoid code comments in the implementation. The rationale here is genuinely non-obvious (compile-time vs runtime path resolution), so consider keeping at most a one-line note next to the require() call and dropping the rest, or moving the explanation to the PR/commit description.

As per coding guidelines: "Avoid code comments in the implementation".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/apps-engine/src/definition/version.ts` around lines 1 - 11, Remove
the long leading doc block and replace it with a single-line comment immediately
adjacent to the require() that reads package.json (e.g. "// Use require() so TS
doesn't resolve the path at compile time"), keeping the actual code (the
require() call and exported version constant) unchanged; move the detailed
explanation into the PR/commit message instead of the source.

16-16: Consider freezing the dependency on a moving package shape.

require(requirePath).version will silently produce undefined (typed as string) if the field is ever missing or the file is renamed. Since the whole point of this module is to fail loudly when version detection breaks, a small assertion would be cheap and would surface misconfiguration immediately at module load:

🛡️ Suggested guard
-// eslint-disable-next-line import/no-dynamic-require, `@typescript-eslint/no-require-imports` -- Paths are bounded, we just need to decide which package.json file to target
-export const ENGINE_VERSION: string = require(requirePath).version;
+// eslint-disable-next-line import/no-dynamic-require, `@typescript-eslint/no-require-imports` -- Paths are bounded, we just need to decide which package.json file to target
+const { version } = require(requirePath) as { version?: string };
+if (typeof version !== 'string') {
+    throw new Error(`Apps-Engine: failed to resolve version from ${requirePath}`);
+}
+export const ENGINE_VERSION: string = version;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/apps-engine/src/definition/version.ts` at line 16, The current
export ENGINE_VERSION uses require(requirePath).version which can silently be
undefined; update the module so after loading the package JSON via
require(requirePath) (using the existing requirePath symbol) you assert that the
loaded object has a non-empty version property and throw a clear error if not
present, then assign that value to ENGINE_VERSION; ensure the runtime check
happens at module load so any missing/renamed field fails loudly with a helpful
message mentioning requirePath and "version".
packages/apps-engine/src/server/compiler/AppPackageParser.ts (1)

10-10: Optional: drop the redundant instance field.

appsEngineVersion is now just a copy of the module-level ENGINE_VERSION constant — the per-instance field, the explicit string annotation, and the indirection at the call sites no longer add value. Using the constant directly makes the dependency more obvious and removes one layer of state on the parser.

♻️ Proposed simplification
-	private appsEngineVersion: string = ENGINE_VERSION;
-
@@
-		if (!semver.satisfies(this.appsEngineVersion, info.requiredApiVersion)) {
-			throw new RequiredApiVersionError(info, this.appsEngineVersion);
+		if (!semver.satisfies(ENGINE_VERSION, info.requiredApiVersion)) {
+			throw new RequiredApiVersionError(info, ENGINE_VERSION);
 		}

Skip if you want to preserve the field as a stable seam for future test injection.

Also applies to: 18-18

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/apps-engine/src/server/compiler/AppPackageParser.ts` at line 10, The
instance field appsEngineVersion on AppPackageParser is redundant because it
just mirrors the module-level ENGINE_VERSION; remove the appsEngineVersion
declaration and any constructor assignment, then change all call sites inside
AppPackageParser that reference this.appsEngineVersion to use ENGINE_VERSION
directly (retain import of ENGINE_VERSION). Ensure you also remove the explicit
string type annotation and any related tests or references that assume the
per-instance field.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/apps-engine/src/definition/version.ts`:
- Around line 12-13: The OS-dependent dirname check using
__dirname.endsWith('src/definition') can fail on Windows; update the
runningFromSource logic to use path utilities instead (import path) — e.g.,
determine runningFromSource by checking path.basename(path.dirname(__dirname))
=== 'src' && path.basename(__dirname) === 'definition' or by normalizing
separators with path.join/normalize, then set requirePath accordingly; modify
the runningFromSource and requirePath calculation (symbols: runningFromSource,
__dirname, requirePath) to use path methods so the correct package.json path is
chosen cross-platform.

---

Nitpick comments:
In `@packages/apps-engine/src/definition/version.ts`:
- Around line 1-11: Remove the long leading doc block and replace it with a
single-line comment immediately adjacent to the require() that reads
package.json (e.g. "// Use require() so TS doesn't resolve the path at compile
time"), keeping the actual code (the require() call and exported version
constant) unchanged; move the detailed explanation into the PR/commit message
instead of the source.
- Line 16: The current export ENGINE_VERSION uses require(requirePath).version
which can silently be undefined; update the module so after loading the package
JSON via require(requirePath) (using the existing requirePath symbol) you assert
that the loaded object has a non-empty version property and throw a clear error
if not present, then assign that value to ENGINE_VERSION; ensure the runtime
check happens at module load so any missing/renamed field fails loudly with a
helpful message mentioning requirePath and "version".

In `@packages/apps-engine/src/server/compiler/AppPackageParser.ts`:
- Line 10: The instance field appsEngineVersion on AppPackageParser is redundant
because it just mirrors the module-level ENGINE_VERSION; remove the
appsEngineVersion declaration and any constructor assignment, then change all
call sites inside AppPackageParser that reference this.appsEngineVersion to use
ENGINE_VERSION directly (retain import of ENGINE_VERSION). Ensure you also
remove the explicit string type annotation and any related tests or references
that assume the per-instance field.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5d087932-7c0a-49de-8a34-c7617688fe4f

📥 Commits

Reviewing files that changed from the base of the PR and between ceefff9 and 7664485.

📒 Files selected for processing (3)
  • packages/apps-engine/src/definition/version.ts
  • packages/apps-engine/src/server/compiler/AppPackageParser.ts
  • packages/apps-engine/tsconfig.json
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • packages/apps-engine/src/definition/version.ts
  • packages/apps-engine/src/server/compiler/AppPackageParser.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 0
File: :0-0
Timestamp: 2026-02-24T19:05:56.710Z
Learning: In Rocket.Chat PRs, keep feature PRs free of unrelated lockfile-only dependency bumps; prefer reverting lockfile drift or isolating such bumps into a separate "chore" commit/PR, and always use yarn install --immutable with the Yarn version pinned in package.json via Corepack.
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 38068
File: packages/apps-engine/deno-runtime/handlers/lib/assertions.ts:8-12
Timestamp: 2026-01-08T15:07:57.458Z
Learning: In packages/apps-engine/deno-runtime, App objects are never serialized and are instantiated and kept in the runtime context, so duck-typing checks on App methods (including protected methods like extendConfiguration) are reliable for runtime assertions.
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 39701
File: packages/apps-engine/src/server/runtime/deno/AppsEngineDenoRuntime.ts:181-188
Timestamp: 2026-03-18T16:45:52.113Z
Learning: In `packages/apps-engine/src/server/runtime/deno/AppsEngineDenoRuntime.ts`, granting `--allow-read` to the full `this.tempFilePath` (entire temp directory) in the Deno subprocess spawn options is intentional. The `deno.jsonc` config file can affect path resolution in ways that require read access to the broader temp directory, not just the `deno-runtime` subdirectory symlink. Do not flag this as an overly broad permission grant.
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • packages/apps-engine/src/definition/version.ts
  • packages/apps-engine/src/server/compiler/AppPackageParser.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • packages/apps-engine/src/definition/version.ts
  • packages/apps-engine/src/server/compiler/AppPackageParser.ts
📚 Learning: 2026-01-08T15:07:57.458Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 38068
File: packages/apps-engine/deno-runtime/handlers/lib/assertions.ts:8-12
Timestamp: 2026-01-08T15:07:57.458Z
Learning: In packages/apps-engine/deno-runtime, App objects are never serialized and are instantiated and kept in the runtime context, so duck-typing checks on App methods (including protected methods like extendConfiguration) are reliable for runtime assertions.

Applied to files:

  • packages/apps-engine/src/server/compiler/AppPackageParser.ts
🔇 Additional comments (1)
packages/apps-engine/tsconfig.json (1)

13-13: LGTM.

Enabling resolveJsonModule is consistent with the new JSON consumption in src/definition/version.ts. Note the actual version load there still uses dynamic require() (intentionally, to avoid TS resolving the path at compile time and emitting an incorrect relative path from the compiled location), so this option is mainly defensive for any future static JSON imports.

Comment on lines +12 to +13
const runningFromSource = __dirname.endsWith('src/definition');
const requirePath = runningFromSource ? '../../package.json' : '../package.json';
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.

⚠️ Potential issue | 🟡 Minor

Path heuristic is OS-dependent — breaks on Windows.

__dirname on Windows uses backslashes (e.g. C:\…\src\definition), so endsWith('src/definition') will always be false there and the wrong relative path will be selected when running tests via ts-node on Windows. Even if Windows is not a primary target, it's a one-line fix:

🔧 Suggested fix
-const runningFromSource = __dirname.endsWith('src/definition');
-const requirePath = runningFromSource ? '../../package.json' : '../package.json';
+const runningFromSource = __dirname.split(/[\\/]/).slice(-2).join('/') === 'src/definition';
+const requirePath = runningFromSource ? '../../package.json' : '../package.json';

Or use path.basename(path.dirname(__dirname)) === 'src' && path.basename(__dirname) === 'definition'.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const runningFromSource = __dirname.endsWith('src/definition');
const requirePath = runningFromSource ? '../../package.json' : '../package.json';
const runningFromSource = __dirname.split(/[\\/]/).slice(-2).join('/') === 'src/definition';
const requirePath = runningFromSource ? '../../package.json' : '../package.json';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/apps-engine/src/definition/version.ts` around lines 12 - 13, The
OS-dependent dirname check using __dirname.endsWith('src/definition') can fail
on Windows; update the runningFromSource logic to use path utilities instead
(import path) — e.g., determine runningFromSource by checking
path.basename(path.dirname(__dirname)) === 'src' && path.basename(__dirname) ===
'definition' or by normalizing separators with path.join/normalize, then set
requirePath accordingly; modify the runningFromSource and requirePath
calculation (symbols: runningFromSource, __dirname, requirePath) to use path
methods so the correct package.json path is chosen cross-platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feature Pull requests that introduces new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant