feat: Incremental Build#1267
Draft
RandomByte wants to merge 251 commits into
Draft
Conversation
5224cd2 to
4904c84
Compare
950fc6d to
41eed91
Compare
bb39565 to
2a21507
Compare
6233816 to
f858659
Compare
71db1d0 to
a2c371f
Compare
7364b4b to
cf43f0c
Compare
252b966 to
874a943
Compare
RandomByte
commented
Feb 18, 2026
df275e5 to
0345502
Compare
RandomByte
commented
Mar 5, 2026
9fc2509 to
20ba653
Compare
20ba653 to
9fc2509
Compare
9fc2509 to
940376d
Compare
9197670 to
44d1107
Compare
44d1107 to
d7c402c
Compare
Member
|
Rebased onto origin/main |
Resources <= 128 bytes are stored uncompressed in the CAS, avoiding gzip overhead that exceeds the compression benefit for tiny inputs. The read path uses gzip magic byte detection for backward compatibility.
Build tests: add getRootPath stub and cacheDir to expected args to match the new cache directory parameter in graph.build(). Serve tests: adapt to the non-returning handler pattern (pOnError) by using fire-and-settle instead of awaiting handler completion, and account for the new error callback passed to serverServe.
serveResources: Rewrite tests for simplified middleware that now uses resource.getIntegrity() for ETag and res.send(buffer) instead of streaming, properties encoding, manifest generation, and version replacement. MiddlewareManager: Add required sources parameter to constructor calls and update expected middleware list (serveThemes removed). main: Update expected CSS content (minified by build server), update discovery app_pages entries, remove tests for files no longer produced by the build server (css_variables, library_skeleton). caching: Replace obsolete manifestEnhancer and version placeholder tests with basic ETag caching tests. Also fix port conflict between caching and acceptRemoteConnections tests. Both test files used port 3334 causing ECONNRESET when run concurrently.
The BuildServer's chokidar file watchers kept the event loop alive after the HTTP server was closed, causing test timeouts.
Set UI5_DATA_DIR to an absolute path (test/tmp/.ui5-data) so builder tests use an isolated cache directory instead of the user's ~/.ui5 home, preventing cross-contamination between test runs and local state.
…rrors Move PRAGMA busy_timeout=5000 to be the first statement after opening the database connection. This ensures concurrent processes will wait rather than immediately fail with "database is locked" when they race to set journal_mode=WAL on a freshly created database.
Update stringReplacer and nonAsciiEscaper tests to expect undefined in the result array when a resource is not modified, matching the committed processor behavior of signaling no-ops to enable incremental build optimizations.
Separate build-status and project-build-status event handling: use buildStatusEventStub for determining project build order (via project-build-start status), and projectBuildStatusEventStub for extracting per-project task execution details.
The frozen source reader was inserted into the reader chain without style-specific path mapping, causing buildtime-path resources to leak into dist/flat/runtime queries. Add an applyStyleToReader callback so ProjectResources can wrap the frozen reader with the same transform the source reader receives.
Memory adapter and Proxy reader called the deprecated getStatInfo() to check the nodir option, which triggered a deprecation log via @ui5/logger. This caused spurious verbose log entries that leaked into downstream tests using global logger mocks.
… Module Project._addReadersForWriter used unshift which reversed the stage priority order, causing earlier stages (e.g. replaceCopyright) to shadow later stages (e.g. replaceVersion) in the result reader chain. Change to push so that later stages have higher priority, matching ComponentProject behavior.
…hed tags The build manifest version was bumped to "1.0" but the version check in ProjectBuildContext only accepted "0.1" and "0.2", causing pre-built dependencies to be rebuilt from scratch instead of being skipped. Also ensure getProjectResourceTagCollection() applies cached stage tags before returning the collection, matching the pattern already used by getResourceTagCollection().
0670d94 to
d029efb
Compare
On Windows the SQLite database file handle kept the cache.db locked after the build finished. When a subsequent build tried to clean the output directory, fs.rm failed with EBUSY. Close the CacheManager at the end of buildToTarget, after all deferred disk writes have completed.
Add tests for previously uncovered modules: MonitoredReader, MonitoredReaderWriter, MonitoredResourceTagCollection, and Proxy reader. Also extend existing tests for ResourceTagCollection, resourceFactory, and AbstractReaderWriter to cover missing functions. Functions coverage rises from 81% to 95%.
Add targeted tests to bring @ui5/project coverage above the configured thresholds (95% statements, 90% branches, 95% functions, 95% lines). Also fix AVA timeout for parallel test execution and remove dead code module utils/sanitizeFileName.js. New test files: - build/cache/utils.js, index/TreeNode.js, index/ResourceIndex.js - build/BuildReader.js, helpers/WatchHandler.js, helpers/ProjectBuilderOutputStyle.js - ui5framework/maven/CacheMode.js Extended existing tests: - HashTree.js, SharedHashTree.js, CacheManager.js - specifications/Project.js, types/Component.js, types/Library.js - types/Module.js, types/ThemeLibrary.js, extensions/Task.js
The CacheManager is a singleton per cache directory. When multiple concurrent builds share the same singleton (e.g. in parallel test execution), the first build to finish would close the database and break any other build still using it. Track the number of active consumers via a reference count that is incremented on each create() call and decremented on close(). The underlying SQLite database is only closed when the last consumer releases its reference.
5c533bd to
ee33924
Compare
… BuildServer When source files are modified while a build is in progress (detected by condition rather than a fatal error. This fixes a race condition where the build takes close to or exceeds 500ms, causing the integration test's file writes to land during source revalidation. - Add SourceChangedDuringBuildError for typed error handling - Handle it alongside AbortBuildError in BuildServer (re-queue projects) - Reset source index state on error to prevent infinite retry loops - Pass abort signal to allTasksCompleted() so watcher-triggered aborts take precedence over the source-change error
Replace fragile setTimeout(0) with deterministic promise-based signals to wait for the handler's async work to complete. On Node 22, esmock's off-thread ESM loader hooks can take more than one microtask tick to resolve dynamic imports, causing afterEach's esmock.purge() to nullify the mock cache before the handler's imports resolve. Use handlerReady (resolves on first stdout write) for most tests, and openCalled (resolves when the open stub fires) for --open tests which have an additional dynamic import after stdout output.
…ests BuildServer.destroy() did not close the CacheManager, leaving SQLite file handles open when subsequent tests tried to delete temp directories. On Windows, open handles prevent file deletion (EBUSY). - Close CacheManager in BuildServer.destroy() via new ProjectBuilder.closeCacheManager() method - Close singleton instances in CacheManager create() test - Make after.always rimraf best-effort in cache tests since test/tmp is already cleaned at the start of each run - Handle EBUSY gracefully in isValid file-deletion test (not possible on Windows with open handles)
…n integration tests - Add #destroyed flag to BuildServer to prevent new builds from being triggered after destroy() is called - Clear pending build queue and timeout before awaiting active build to avoid race with setTimeout-based queue processing - Add maxRetries to rmrf in integration tests for Windows file handle release delays after SQLite close
…AL on close On Windows, SQLite WAL mode keeps file handles that prevent deletion even after close(). Adding PRAGMA wal_checkpoint(TRUNCATE) before close flushes WAL content back to the main database and releases all file handles cleanly. This single fix in BuildCacheStorage.close() resolves all Windows EBUSY errors across cache tests and integration tests without needing per-test workarounds. Additional fixes: - Close CacheManager in BuildServer.destroy() to release DB handles - Add #destroyed flag to prevent builds from starting after shutdown - Close singleton instances in CacheManager create() test
Add tests for the serveIndex error-handling path (byGlob rejection) and the sslUtil chmod failure callbacks when fixing outdated file permissions.
Add mocked unit tests covering the previously untested error-handling functions in lib/server.js: the HTTP server error event handler, buildServer error event forwarding, and the close() rejection handler when buildServer.destroy() fails.
68f9cb9 to
4a58a19
Compare
…e during index re-init After a SourceChangedDuringBuildError, the source index is nulled and state reset to RESTORING_PROJECT_INDICES. If projectSourcesChanged or dependencyResourcesChanged was called before initSourceIndex ran again, the state was incorrectly transitioned to REQUIRES_UPDATE, causing initSourceIndex to skip initialization and a subsequent NPE on the null source index.
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.
Implementation of RFC 0017 Incremental Build
This PR supersedes previous PoC: #1238
JIRA: CPOUI5FOUNDATION-1174