Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
285 commits
Select commit Hold shift + click to select a range
309b62b
test(timescale): verify the plugin against TimescaleDB 2.17 and 2.22
qianmoQ Nov 1, 2026
429c015
test(paradedb): verify the plugin against ParadeDB 0.15 and 0.19
qianmoQ Nov 1, 2026
7b47515
revert(web): drop the key-value mode of the query page tree
qianmoQ Nov 1, 2026
ff26f37
feat(driver): describe Redis as databases, keys and columns
qianmoQ Nov 1, 2026
4852f2f
refactor(redis): browse Redis like MySQL instead of a key-value works…
qianmoQ Nov 1, 2026
b250016
feat(neo4j): list the database, labels and properties
qianmoQ Nov 1, 2026
09bbe9d
fix(web): show column detail tabs only for declared capabilities
qianmoQ Nov 1, 2026
99f1465
fix(spi): list columns from drivers without IS_AUTOINCREMENT
qianmoQ Nov 1, 2026
c31787b
fix(monetdb): read the server version from sys.environment
qianmoQ Nov 1, 2026
74b7845
test(monetdb): verify the plugin against MonetDB Aug2024 and Mar2025
qianmoQ Nov 1, 2026
ccc1c37
fix(h2): keep the in-memory database between queries
qianmoQ Nov 1, 2026
a1dc00b
fix(h2): list databases, tables and columns from JDBC metadata
qianmoQ Nov 1, 2026
139fe7a
test(h2): verify the plugin against its bundled H2 2.1.214
qianmoQ Nov 1, 2026
f842962
fix(h2-tcp): list databases, tables and columns from JDBC metadata
qianmoQ Nov 1, 2026
6866ca0
test(h2-tcp): verify the plugin against an H2 2.1.214 TCP server
qianmoQ Nov 1, 2026
53d9599
fix(duckdb): open the database file in the configured directory
qianmoQ Nov 1, 2026
e622412
fix(duckdb): list tables from information_schema
qianmoQ Nov 1, 2026
5c1d443
test(duckdb): verify the plugin against its bundled DuckDB 1.0.0
qianmoQ Nov 1, 2026
1fd65d9
fix(compare): read compared columns through the plugin's column listing
qianmoQ Nov 1, 2026
4c26e20
docs(plugin): rewrite the plugin guides for JDBC and shared metadata
qianmoQ Nov 1, 2026
fb93611
fix(oracle): find the server version on Oracle AI Database 26ai
qianmoQ Nov 1, 2026
682684c
test(oracle): verify the plugin against Oracle Database 23ai and 26ai
qianmoQ Nov 1, 2026
9898187
fix(elasticsearch-8x): check the source without version()
qianmoQ Nov 1, 2026
d4ba1da
test(elasticsearch-8x): verify the plugin against Elasticsearch 8.15 …
qianmoQ Nov 1, 2026
205cfaf
fix(influxdb): check the source with SHOW DIAGNOSTICS
qianmoQ Nov 1, 2026
ade2c4a
fix(influxdb): list databases, measurements, tags and fields
qianmoQ Nov 1, 2026
975c89c
test(influxdb): verify the plugin against InfluxDB 1.8 and 1.11
qianmoQ Nov 1, 2026
7885984
test(trino): verify the plugin against Trino 470 and 476
qianmoQ Nov 1, 2026
fc5cb54
fix(iotdb): check the source with SHOW VERSION
qianmoQ Nov 1, 2026
fb92a21
fix(iotdb): list databases, devices and measurements with SHOW
qianmoQ Nov 1, 2026
f0f1728
test(iotdb): verify the plugin against IoTDB 1.3 and 2.0
qianmoQ Nov 1, 2026
b65fccb
fix(tdengine): read the server version with server_version()
qianmoQ Nov 1, 2026
d1a7efc
fix(tdengine): list columns and tags with DESCRIBE
qianmoQ Nov 1, 2026
669d0cf
fix(tdengine): list super tables and tables from information_schema
qianmoQ Nov 1, 2026
1974c49
test(tdengine): verify the plugin against TDengine 3.1 and 3.3
qianmoQ Nov 1, 2026
cfea491
docs(snowflake): say why the connector has no e2e test
qianmoQ Nov 1, 2026
98bbbbc
docs(hologres): say why the connector has no e2e test
qianmoQ Nov 1, 2026
53ef752
test(dm): verify the plugin against DM 8
qianmoQ Nov 1, 2026
70acbb1
fix(server): open java.nio for the Ignite JDBC driver
qianmoQ Nov 1, 2026
5936036
fix(ignite): report the server version from SYS.NODES
qianmoQ Nov 1, 2026
a38fdb1
fix(ignite): list schemas, tables and columns from JDBC metadata
qianmoQ Nov 1, 2026
2ca3e17
test(ignite): verify the plugin against Ignite 2.17 and 2.18
qianmoQ Nov 1, 2026
4a088c8
test(matrixone): verify the plugin against MatrixOne 3.0 and 4.2
qianmoQ Nov 1, 2026
8ba77f6
fix(dolphindb): report the version as text
qianmoQ Nov 1, 2026
27683e7
fix(dolphindb): list databases, tables and columns with DolphinDB fun…
qianmoQ Nov 1, 2026
02394ef
test(dolphindb): verify the plugin against DolphinDB 2.00 and 3.00
qianmoQ Nov 1, 2026
6aa3449
fix(solr): use the Solr 9 SQL JDBC driver
qianmoQ Nov 1, 2026
3f4db8d
fix(solr): pass the collection as a URL parameter and default to port…
qianmoQ Nov 1, 2026
ba99ed6
fix(solr): list collections and fields from Solr's metadata tables
qianmoQ Nov 1, 2026
d0c5253
test(solr): verify the plugin against Solr 9.4 and 9.11
qianmoQ Nov 1, 2026
ef12bbd
test(hive-2x): verify the plugin against HiveServer2 4.0 and 4.1
qianmoQ Nov 1, 2026
7a71698
test(presto): verify the plugin against PrestoDB 0.296 and 0.299
qianmoQ Nov 1, 2026
2d5387c
fix(service): read export and import columns through the plugin
qianmoQ Nov 1, 2026
d5b4d0f
fix(starrocks): report StarRocks' version, not the MySQL one it emulates
qianmoQ Nov 1, 2026
4fe6039
test(starrocks): verify the plugin against StarRocks 3.5 and 4.0
qianmoQ Nov 1, 2026
2033a43
fix(dremio): connect through the Arrow Flight SQL JDBC driver
qianmoQ Nov 1, 2026
323b439
test(dremio): verify the plugin against Dremio 25.2 and 26.0
qianmoQ Nov 1, 2026
f389fd6
test(sqlserver): verify the plugin against SQL Server 2019 and 2022
qianmoQ Nov 2, 2026
dc8338b
fix(doris): report Doris' version, not the MySQL one it emulates
qianmoQ Nov 2, 2026
fbad83d
fix(doris): default to the frontend's query port 9030
qianmoQ Nov 2, 2026
aa743a3
test(doris): verify the plugin against Doris 2.1 and 4.1
qianmoQ Nov 2, 2026
600639f
fix(pinot): check the source without a sample table
qianmoQ Nov 2, 2026
c964a6c
fix(pinot): list tables and columns without a schema
qianmoQ Nov 2, 2026
9b731d6
test(pinot): verify the plugin against Pinot 1.4 and 1.5
qianmoQ Nov 2, 2026
43028dd
fix(ydb): build the URL the YDB driver reads
qianmoQ Nov 2, 2026
c1ca1c9
fix(ydb): turn on autocommit
qianmoQ Nov 2, 2026
ff9bbba
fix(ydb): run CREATE, ALTER and DROP as scheme queries
qianmoQ Nov 2, 2026
336aeac
fix(ydb): list the database's tables and columns without a schema
qianmoQ Nov 2, 2026
65c7f47
test(ydb): verify the plugin against YDB 25.4 and 26.3
qianmoQ Nov 2, 2026
a6850a9
test(oceanbase): verify the plugin against OceanBase 4.2, 4.3 and 4.4
qianmoQ Nov 2, 2026
751bcef
test(db2): verify the plugin against Db2 11.5 and 12.1
qianmoQ Nov 2, 2026
b2aa4ba
fix(spi): list columns when the server can not look up primary keys
qianmoQ Nov 2, 2026
ca81f45
test(kyuubi): verify the plugin against Kyuubi 1.10 and 1.11
qianmoQ Nov 2, 2026
41c2263
test(server): expect 22 mapped entities
qianmoQ Nov 2, 2026
7e2b0ec
fix(history): list query history newest first
qianmoQ Nov 2, 2026
b424812
refactor(web): drop the list titles above every data table
qianmoQ Nov 2, 2026
8b1224e
test(plugin): skip dm e2e on foreign arch
qianmoQ Nov 2, 2026
0144b29
feat(settings): set file storage in system settings
qianmoQ Nov 2, 2026
e8eec50
feat(web): add a file storage tab to system settings
qianmoQ Nov 2, 2026
f65b2a1
test(plugin): pick e2e images by host arch
qianmoQ Nov 2, 2026
73f9e05
feat(web): show saved query results in a drawer with the shared table
qianmoQ Nov 2, 2026
9fa36ed
refactor(function): use MfTable for the import example, mapping and p…
qianmoQ Nov 2, 2026
43cf28b
build(web): drop dependencies nothing uses
qianmoQ Nov 2, 2026
09a408b
feat(settings): test file storage and runtime settings before saving
qianmoQ Nov 2, 2026
abc04d3
feat(web): move runtime settings into System settings with a test button
qianmoQ Nov 2, 2026
06f893d
fix(security): serve built web assets without a token
qianmoQ Nov 2, 2026
d138492
fix(web): show a spinner until the first page resolves
qianmoQ Nov 2, 2026
6c0543d
fix(web): drop the retired runtime settings menu
qianmoQ Nov 2, 2026
8a0b993
ci: install modules before running the test suite
qianmoQ Nov 2, 2026
7bd983c
refactor(executor): rename the Local executor to MetaForge
qianmoQ Nov 2, 2026
549216e
feat(executor): queue dataset syncs and track their state and metrics
qianmoQ Nov 2, 2026
ef61991
feat(executor): pipeline reads and writes and collect detailed metrics
qianmoQ Nov 2, 2026
b231d79
fix(web): show a spinner while the source wizard loads plugins
qianmoQ Nov 2, 2026
fcc2434
feat(query): rebuild result visualization from the prototype
qianmoQ Nov 4, 2026
92037dd
feat(report): refresh query charts in read-only transactions
qianmoQ Nov 4, 2026
2e1ed5f
feat(query): migrate to ECharts and add chart controls
qianmoQ Nov 4, 2026
afa2846
fix(plugin): key development modules by their directory name
qianmoQ Nov 4, 2026
7f3046c
build(store): generate the plugin catalogue from each module
qianmoQ Nov 4, 2026
ab8817c
feat(plugin): expose the store details shipped in each plugin
qianmoQ Nov 4, 2026
18b80b7
fix(ui): keep horizontal tab bars from scrolling vertically
qianmoQ Nov 4, 2026
d5fc259
feat(store): manage plugins safely and count verified downloads
qianmoQ Nov 4, 2026
1da2f67
feat(ui): let MfDrawer callers replace the body padding
qianmoQ Nov 4, 2026
386321e
feat(store): rebuild the plugin store from the prototype
qianmoQ Nov 4, 2026
9525eb9
feat(report): share reports through public links and iframe embeds
qianmoQ Nov 4, 2026
2785e60
feat(report): add report sharing and the public report page
qianmoQ Nov 4, 2026
1fbd28b
feat(report): expire share links and choose what the public page shows
qianmoQ Nov 4, 2026
af136b3
feat(report): add a share button with expiry and display settings
qianmoQ Nov 4, 2026
082e1fa
fix(report): open share links without sign-in and tidy the share dialog
qianmoQ Nov 4, 2026
fe1363f
feat(report): let shared reports offer their data and a CSV download
qianmoQ Nov 4, 2026
31aef5b
fix(report): keep share addresses intact and offer data downloads
qianmoQ Nov 4, 2026
ccfa891
feat(web): serve the web UI on history-routed page addresses
qianmoQ Nov 5, 2026
61e903c
feat(web): switch to history routing without #/ in addresses
qianmoQ Nov 5, 2026
eadc650
fix(ui): align table headers and stabilize numeric and menu controls
qianmoQ Nov 5, 2026
3a06ced
feat(visualization): support the full echarts series catalog
qianmoQ Nov 5, 2026
24430e3
feat(dashboard): build a complete visual studio for boards and screens
qianmoQ Nov 5, 2026
585fbda
fix(clickhouse): read index details from ClickHouse system tables
qianmoQ Nov 5, 2026
a8d2a9a
fix(source): load the workspace visibly and keep the tree still
qianmoQ Nov 5, 2026
c5ab63c
feat(notify): let channels declare the settings each user fills in
qianmoQ Nov 5, 2026
a58bcdd
feat(notify): deliver scene notices with per-user channel settings
qianmoQ Nov 5, 2026
942a36b
feat(notify): rebuild account notify page around channels and scenes
qianmoQ Nov 5, 2026
d401aef
feat(notify): raise scene notices from sources, reports and accounts
qianmoQ Nov 5, 2026
edc3a34
refactor(notify): show channels as wrapping cards with a settings drawer
qianmoQ Nov 5, 2026
1565a82
fix(notify): refresh header notifications without reloading the page
qianmoQ Nov 5, 2026
b613197
feat(notify): add a per-user notification inbox api
qianmoQ Nov 5, 2026
014a392
feat(notify): rebuild the notification center around a bell panel
qianmoQ Nov 5, 2026
1676490
style(notify): lay out the notification center like other list pages
qianmoQ Nov 5, 2026
e2262b0
fix(forms): align settings fields and keep feedback below controls
qianmoQ Nov 6, 2026
b5dae60
style(web): replace decorative glyphs with svg icons
qianmoQ Nov 6, 2026
79f5b27
feat(workflow): rebuild the studio around executor capabilities
qianmoQ Nov 6, 2026
e02f0b5
refactor(workflow): let executor plugins declare and compile workflows
qianmoQ Nov 6, 2026
16a7492
feat(workflow): drive the studio from executor declarations
qianmoQ Nov 6, 2026
9458cab
fix(workflow): connect ports by dragging between them
qianmoQ Nov 6, 2026
89b9ffe
fix(workflow): end connection arrows at the port rim
qianmoQ Nov 6, 2026
36543a7
fix(ui): keep input autofill paint inside the rounded frame
qianmoQ Nov 6, 2026
acd43fd
refactor(web): share the studio back link between dashboard pages
qianmoQ Nov 6, 2026
3e01de9
feat(workflow): read query columns and previews through source plugins
qianmoQ Nov 6, 2026
d72bdfa
feat(workflow): lay out the list and run details like other pages
qianmoQ Nov 6, 2026
ea25d23
feat(workflow): fill sink targets and edit SQL from source metadata
qianmoQ Nov 6, 2026
79ba14b
fix(spi): write batches with auto-commit on engines without transactions
qianmoQ Nov 6, 2026
73b6c47
fix(workflow): keep the run details menu fixed and scroll the content
qianmoQ Nov 6, 2026
66ebbac
feat(workflow): show the metrics each executor declares for its runs
qianmoQ Nov 6, 2026
77b74a2
fix(executor): count the batch committed when the writer closes
qianmoQ Nov 6, 2026
425ac85
build(server): leave application.properties out of the server jar
qianmoQ Nov 6, 2026
8798c8a
feat(workflow): return run start and finish times formatted by the se…
qianmoQ Nov 6, 2026
6b6c6a0
feat(workflow): split run details into tabs and chart the run metrics
qianmoQ Nov 6, 2026
2a106c9
fix(web): write every date as YYYY-MM-DD HH:mm:ss
qianmoQ Nov 6, 2026
bbd956c
fix(workflow): show run end times and translate execution stages
qianmoQ Nov 6, 2026
c9d8b1a
refactor(source): list column settings in MfTable
qianmoQ Nov 6, 2026
54cf869
feat(executor): report the source total once a run reads it completely
qianmoQ Nov 6, 2026
2e85912
fix(workflow): tolerate runs that report no or partial metrics
qianmoQ Nov 6, 2026
9e6ffea
feat(workflow): count the source before a run by default
qianmoQ Nov 6, 2026
2eb849c
feat(dataset): return sync transition times formatted by the server
qianmoQ Nov 6, 2026
4012e15
refactor(web): share run metrics, stages, log and layout components
qianmoQ Nov 6, 2026
3d494d2
feat(dataset): show sync records like workflow runs
qianmoQ Nov 6, 2026
5e69604
fix(dataset): label the dataset state on the sync records menu
qianmoQ Nov 6, 2026
df882ae
fix(ui): pin badge counts to the corner of the content they mark
qianmoQ Nov 6, 2026
7d910cb
fix(notify): open dataset sync notices on the sync records page
qianmoQ Nov 6, 2026
cbecf84
refactor(web): simplify page and editor panel headings
qianmoQ Nov 6, 2026
6d17780
feat(dataset): rebuild the adhoc query workspace
qianmoQ Nov 6, 2026
94fb6a8
feat(dashboard): add responsive resizable editor sidebars
qianmoQ Nov 6, 2026
eba83c6
fix(dataset): enable ad hoc queries once the dataset table exists
qianmoQ Nov 6, 2026
9ccff08
i18n(web): name visualization pages after what they show
qianmoQ Nov 6, 2026
afa4982
feat(dashboard): let users open a data screen as their home page
qianmoQ Nov 6, 2026
2c88f88
refactor(dataset): group adhoc properties into inspector cards
qianmoQ Nov 6, 2026
b943edf
fix(dashboard): show only the data screen on the home page
qianmoQ Nov 6, 2026
78cfba2
feat(home): redesign the default resource workspace
qianmoQ Nov 6, 2026
33d15ae
feat(dashboard): move data screens to /screen with a toolbar-free view
qianmoQ Nov 6, 2026
d7111e5
feat(dashboard): share data screens with users, roles and everyone
qianmoQ Nov 6, 2026
f3b0b69
feat(dashboard): add public links for data screens
qianmoQ Nov 6, 2026
390f818
fix(dashboard): prevent clipping in the sharing dialog
qianmoQ Nov 6, 2026
841e43d
feat(dashboard): add a searchable gallery with static previews
qianmoQ Nov 6, 2026
449e8e9
feat(home): add query activity charts and recent resources
qianmoQ Nov 6, 2026
cea2f9e
chore(server): document intentional singleton dependencies
qianmoQ Nov 6, 2026
5efaf08
feat(executor): split queries across parallel channels with a rate limit
qianmoQ Nov 7, 2026
881e458
fix(metrics): prevent overlapping chart legends and labels
qianmoQ Nov 7, 2026
927fd80
fix(home): count datasets without loading legacy rows
qianmoQ Nov 7, 2026
28f7a5c
fix(dataset): let fresh installs start and syncs run without pipelines
qianmoQ Nov 7, 2026
6806c04
feat(executor): tolerate write failures and pause, resume, retry syncs
qianmoQ Nov 7, 2026
d1cbe42
feat(charts): add centered loading states
qianmoQ Nov 7, 2026
44041e3
feat(web): show sync progress on the list and group runtime settings
qianmoQ Nov 7, 2026
99f9e48
docs(executor): document the sync executor and its settings
qianmoQ Nov 7, 2026
f1e3451
feat(dashboard): expand screen widgets and report filters
qianmoQ Nov 7, 2026
9777ee9
feat(store): fetch the plugin catalogue through the server
qianmoQ Nov 7, 2026
9272238
chore(store): use forgestats.devlive.org for the statistics service
qianmoQ Nov 7, 2026
f07feb8
ci(release): publish maven central like the grantforge flow
qianmoQ Nov 7, 2026
cfc8c92
feat(dashboard): add operations and inspection widgets
qianmoQ Nov 7, 2026
f73bd47
feat(dashboard): add business analytics widgets
qianmoQ Nov 7, 2026
a09fd9e
feat(settings): make runtime field groups collapsible
qianmoQ Nov 7, 2026
1a90f12
fix(persistence): pass the oracle and sqlserver matrix runs
qianmoQ Nov 7, 2026
b83b1bb
test(workflow): tolerate the run file lagging the success state
qianmoQ Nov 7, 2026
6363fb8
test(presto): drop the e2e that cannot run in a single-node container
qianmoQ Nov 7, 2026
790bfd4
test(e2e): retry while the coordinator reports no live nodes
qianmoQ Nov 7, 2026
ea1cbab
fix(presto): convert the gate deadline to millis
qianmoQ Nov 7, 2026
7ae8749
fix(presto): declare the gate's interrupted sleep
qianmoQ Nov 7, 2026
da8e97e
ci(tests): give the backend suite ninety minutes and gate trino
qianmoQ Nov 7, 2026
70e5fc2
test(sync): poll for the dataset release after a resumed run
qianmoQ Nov 7, 2026
f76d8c8
test(e2e): cap the scheduler containers' memory
qianmoQ Nov 7, 2026
d3eede3
ci(tests): free the runner disk before the e2e modules
qianmoQ Nov 7, 2026
f567ea4
test(starrocks): keep the backend capacity check off the runner disk
qianmoQ Nov 8, 2026
1486221
test(starrocks): mount the tmpfs where 4.0 keeps its backend storage
qianmoQ Nov 8, 2026
dd686aa
test(persistence): pool the matrix connections and pin the oracle image
qianmoQ Nov 8, 2026
d3cf2c6
feat(dashboard): add relationship analysis widgets
qianmoQ Nov 8, 2026
76cb8f7
feat(dashboard): add data diagnostics widgets
qianmoQ Nov 8, 2026
1d0e279
feat(dashboard): add time series widgets
qianmoQ Nov 8, 2026
d925e51
feat(dashboard): add comparative analysis widgets
qianmoQ Nov 8, 2026
987ab36
ci: run only the jobs a change touches
qianmoQ Nov 8, 2026
1798620
ci(web): run the frontend tests on node 22
qianmoQ Nov 8, 2026
7431f7a
ci(tests): reclaim engine images while the suite runs
qianmoQ Nov 8, 2026
21ce454
feat(dashboard): add planning and progress widgets
qianmoQ Nov 8, 2026
88150e2
test(executor): locate the seatunnel module without findProjectRoot a…
qianmoQ Nov 8, 2026
9ab9446
feat(dashboard): add spatial analysis widgets
qianmoQ Nov 8, 2026
e9c35e2
feat(dashboard): add process tracking widgets
qianmoQ Nov 8, 2026
7317d93
feat(dashboard): add interval analysis widgets
qianmoQ Nov 8, 2026
c8fb9b2
feat(dashboard): preview more widget animations on the canvas
qianmoQ Nov 8, 2026
dd1c0d7
test(executor): cut the fault proxy while the source connection is live
qianmoQ Nov 8, 2026
771018c
feat(visual): add reusable process quality components
qianmoQ Nov 8, 2026
5970853
feat(visual): add stacked, step and bubble chart types
qianmoQ Nov 8, 2026
95ea93f
refactor(visual): share reusable screen components
qianmoQ Nov 8, 2026
c892231
feat(visual): add ten chart compositions
qianmoQ Nov 8, 2026
c04e3dd
feat(visual): add eight reusable information blocks
qianmoQ Nov 8, 2026
c573429
feat(visual): expand ambient effects and widget motion
qianmoQ Nov 8, 2026
6693107
fix(visual): distinguish stacked lines and range fills
qianmoQ Nov 8, 2026
9e52748
feat(visual): add twelve analytical charts
qianmoQ Nov 8, 2026
3e83f20
feat(visual): add ten reusable information widgets
qianmoQ Nov 8, 2026
be37ffd
feat(visual): add geometric effects and more motion presets
qianmoQ Nov 8, 2026
896d648
fix(visual): localize query calendar month and day labels
qianmoQ Nov 8, 2026
1dbbd52
ci(release): publish packages and the catalogue to Tencent COS
qianmoQ Nov 8, 2026
440f226
fix(store): point the shipped config at forgestats.devlive.org
qianmoQ Nov 8, 2026
a9c461b
test(executor): cut the source proxy for good and pin the write retries
qianmoQ Nov 8, 2026
3f0d254
feat(visual): tailor screen styles to each component type
qianmoQ Nov 8, 2026
4317ee5
feat(visual): add distribution and time series charts
qianmoQ Nov 8, 2026
0e1f13f
feat(visual): add ten operational information widgets
qianmoQ Nov 8, 2026
a726f38
feat(visual): add flow effects and motion presets
qianmoQ Nov 8, 2026
764390a
feat(visual): preview component examples beside the library
qianmoQ Nov 8, 2026
c5ca923
fix(visual): prevent chart and example clipping in cards
qianmoQ Nov 9, 2026
186b995
feat(visual): add twelve diagnostic chart types
qianmoQ Nov 9, 2026
b08edc0
feat(visual): add twelve reusable collaboration widgets
qianmoQ Nov 9, 2026
9998562
fix(plugin): anchor project root detection correctly
qianmoQ Nov 9, 2026
641f77a
fix(plugin): anchor project root detection correctly
qianmoQ Nov 9, 2026
f8c2f18
Merge branch '2026.0.0' of github.com:qianmoq/datacap into 2026.0.0
qianmoQ Nov 9, 2026
e415ada
ci: upload surefire reports when the backend suite fails
qianmoQ Nov 9, 2026
775ac4f
ci: detach the docker pruner from the step pipes
qianmoQ Nov 9, 2026
a5b39a8
ci: add swap to absorb container memory peaks
qianmoQ Nov 9, 2026
18a85d6
ci: keep the surefire invocation on one shell line
qianmoQ Nov 9, 2026
0650c42
ci: reclaim engine images only when the disk runs low
qianmoQ Nov 9, 2026
be28261
fix(query): list only tables and views in the query page tree
qianmoQ Nov 9, 2026
dc505cb
fix(clickhouse): list user-defined functions only
qianmoQ Nov 9, 2026
1e3cbfb
feat(query): cap query page results at a row limit
qianmoQ Nov 9, 2026
63520b4
fix(test): retry the DolphinDB login until the public key is ready
qianmoQ Nov 9, 2026
9a22388
fix(persistence): upgrade databases that ran the edited changesets
qianmoQ Nov 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
263 changes: 263 additions & 0 deletions .ci/changed-components.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
#!/usr/bin/env bash
# Decide which CI components must run, based on the files changed in this push or pull request.
#
# Usage:
# changed-components.sh [options]
#
# Options:
# --config <file> Component rules (default: .ci/components.conf)
# --base <ref> Diff base commit (default: auto-detected from the CI environment)
# --head <ref> Diff head commit (default: HEAD)
# --files <file> Read the changed file list from <file> ("-" = stdin) instead of git diff
# --all Mark every component as changed (full run)
# --github-output Also append the results to "$GITHUB_OUTPUT"
# --files-of <name> Print only the changed files that trigger component <name>, one per line,
# or a single "*" on a full run (e.g. to pick the Maven modules to build)
# -v, --verbose Explain which file triggered each component
#
# Config format (one component per line, "#" starts a comment, lines may continue with "\"):
# <name>: <pattern> [<pattern> ...]
# _all: <pattern> ... # any match forces a full run
# _ignore: <pattern> ... # matching files never trigger anything
#
# A pattern prefixed with "!" excludes files from that component.
# "*" matches any characters including "/"; "**/" matches zero or more directories.
# Patterns are matched against repo-relative paths, e.g. "backend/**", "**/*.py", "Cargo.lock".
#
# Output (stdout and, with --github-output, $GITHUB_OUTPUT):
# <name>=true|false for every component
# any=true|false whether at least one component changed
# components=[...] JSON array of changed component names (for a dynamic matrix)
#
# Base auto-detection (when --base is not given):
# GitHub pull_request : first parent of the merge commit, else merge-base with origin/$GITHUB_BASE_REF
# GitHub push : "before" from $GITHUB_EVENT_PATH
# GitLab merge request: $CI_MERGE_REQUEST_DIFF_BASE_SHA
# GitLab push : $CI_COMMIT_BEFORE_SHA
# anything else, a new branch, or an unknown base -> full run (safe default)
#
# Compatible with bash 3.2 (macOS). Needs only git; jq is used when available.

set -uo pipefail

config=".ci/components.conf"
base=""
head="HEAD"
files_from=""
force_all=0
gh_output=0
verbose=0
files_of=""

die() { echo "error: $*" >&2; exit 2; }
note() { echo "$*" >&2; }

while [ $# -gt 0 ]; do
case "$1" in
--config) config="${2:-}"; shift 2 ;;
--base) base="${2:-}"; shift 2 ;;
--head) head="${2:-}"; shift 2 ;;
--files) files_from="${2:-}"; shift 2 ;;
--all) force_all=1; shift ;;
--github-output) gh_output=1; shift ;;
--files-of) files_of="${2:-}"; shift 2 ;;
-v|--verbose) verbose=1; shift ;;
-h|--help) sed -n '2,40p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
*) die "unknown option: $1" ;;
esac
done

[ -f "$config" ] || die "config not found: $config"

# ---------------------------------------------------------------- config parsing
names=() # component names, in file order
includes=() # space-separated include patterns per component
excludes=() # space-separated exclude patterns per component
all_patterns=""
ignore_patterns=""

add_rule() { # <name> <patterns...>
local name="$1"; shift
local inc="" exc="" p
for p in "$@"; do
case "$p" in
'!'*) exc="$exc ${p#!}" ;;
*) inc="$inc $p" ;;
esac
done
case "$name" in
_all) all_patterns="$all_patterns$inc"; return ;;
_ignore) ignore_patterns="$ignore_patterns$inc"; return ;;
esac
printf '%s' "$name" | grep -Eq '^[A-Za-z][A-Za-z0-9_-]*$' || die "invalid component name: $name"
local i
for i in "${!names[@]}"; do
if [ "${names[$i]}" = "$name" ]; then
includes[$i]="${includes[$i]}$inc"; excludes[$i]="${excludes[$i]}$exc"; return
fi
done
names+=("$name"); includes+=("$inc"); excludes+=("$exc")
}

pending=""
while IFS= read -r line || [ -n "$line" ]; do
line="${line%%#*}"
case "$line" in
*\\) pending="$pending ${line%\\}"; continue ;;
esac
line="$pending $line"; pending=""
# trim
line="$(printf '%s' "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
[ -z "$line" ] && continue
case "$line" in
*:*) ;;
*) die "bad config line (expected 'name: patterns'): $line" ;;
esac
name="${line%%:*}"; name="$(printf '%s' "$name" | tr -d '[:space:]')"
# shellcheck disable=SC2086 # intentional word splitting of the pattern list
set -f; add_rule "$name" ${line#*:}; set +f
done < "$config"

[ "${#names[@]}" -gt 0 ] || die "no components defined in $config"

# ---------------------------------------------------------------- matching
matches() { # <file> <pattern>; each "**/" means zero or more directories
local f="$1" p="$2" pre post
case "$p" in
*'**/'*)
pre="${p%%'**/'*}"; post="${p#*'**/'}"
matches "$f" "$pre$post" && return 0
matches "$f" "$pre*/$post"; return ;;
esac
# shellcheck disable=SC2053 # unquoted RHS is a glob on purpose
[[ $f == $p ]]
}

matches_any() { # <file> <space-separated patterns>
local f="$1" p
set -f
for p in $2; do
if matches "$f" "$p"; then set +f; return 0; fi
done
set +f
return 1
}

# ---------------------------------------------------------------- base detection
zero='0000000000000000000000000000000000000000'
reason=""

detect_base() {
local ev="${GITHUB_EVENT_NAME:-}"
if [ -n "$ev" ]; then
case "$ev" in
pull_request|pull_request_target)
if git rev-parse -q --verify "$head^2" >/dev/null 2>&1; then
base="$(git rev-parse "$head^1")"; return
fi
if [ -n "${GITHUB_BASE_REF:-}" ]; then
base="$(git merge-base "origin/$GITHUB_BASE_REF" "$head" 2>/dev/null || true)"; return
fi ;;
push)
if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -f "$GITHUB_EVENT_PATH" ]; then
if command -v jq >/dev/null 2>&1; then
base="$(jq -r '.before // empty' "$GITHUB_EVENT_PATH")"
else
base="$(grep -o '"before": *"[0-9a-f]*"' "$GITHUB_EVENT_PATH" | head -n 1 | grep -o '[0-9a-f]\{40\}')"
fi
fi
return ;;
*) reason="event '$ev' always runs everything"; return ;;
esac
fi
if [ -n "${GITLAB_CI:-}" ]; then
base="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-${CI_COMMIT_BEFORE_SHA:-}}"; return
fi
reason="no --base given and no CI environment detected"
}

changed=""
if [ "$force_all" -eq 1 ]; then
reason="--all requested"
elif [ -n "$files_from" ]; then
if [ "$files_from" = "-" ]; then changed="$(cat)"; else changed="$(cat "$files_from")"; fi
else
[ -z "$base" ] && detect_base
if [ -z "$reason" ]; then
if [ -z "$base" ] || [ "$base" = "$zero" ]; then
reason="no usable diff base (new branch or first push)"
elif ! git cat-file -e "$base^{commit}" 2>/dev/null; then
reason="base $base is not in the clone (use fetch-depth: 0 or fetch it)"
else
changed="$(git diff --name-only --no-renames "$base" "$head")" || die "git diff failed"
fi
fi
fi

# ---------------------------------------------------------------- evaluation
results=()
full=0
own_files=""
for i in "${!names[@]}"; do results[$i]=false; done

if [ -n "$reason" ]; then
note "full run: $reason"
full=1
for i in "${!names[@]}"; do results[$i]=true; done
else
count=0
while IFS= read -r f; do
[ -z "$f" ] && continue
count=$((count + 1))
if [ -n "$ignore_patterns" ] && matches_any "$f" "$ignore_patterns"; then
[ "$verbose" -eq 1 ] && note " ignored: $f"
continue
fi
if [ -n "$all_patterns" ] && matches_any "$f" "$all_patterns"; then
note "full run: $f matches an _all pattern"
full=1
for i in "${!names[@]}"; do results[$i]=true; done
break
fi
hit=0
for i in "${!names[@]}"; do
if matches_any "$f" "${includes[$i]}" && ! matches_any "$f" "${excludes[$i]}"; then
[ "$verbose" -eq 1 ] && [ "${results[$i]}" = false ] && note " ${names[$i]} <- $f"
results[$i]=true; hit=1
[ "${names[$i]}" = "$files_of" ] && own_files="$own_files$f
"
fi
done
[ "$verbose" -eq 1 ] && [ "$hit" -eq 0 ] && note " no component: $f"
done <<EOF
$changed
EOF
[ "$verbose" -eq 1 ] && note "changed files examined: $count"
fi

# ---------------------------------------------------------------- output
if [ -n "$files_of" ]; then
if [ "$full" -eq 1 ]; then echo '*'; else printf '%s' "$own_files"; fi
exit 0
fi

any=false
json=""
out=""
for i in "${!names[@]}"; do
out="$out${names[$i]}=${results[$i]}
"
if [ "${results[$i]}" = true ]; then
any=true
json="$json${json:+,}\"${names[$i]}\""
fi
done
out="${out}any=$any
components=[$json]
"

printf '%s' "$out"
if [ "$gh_output" -eq 1 ]; then
[ -n "${GITHUB_OUTPUT:-}" ] || die "--github-output used but GITHUB_OUTPUT is not set"
printf '%s' "$out" >> "$GITHUB_OUTPUT"
fi
25 changes: 25 additions & 0 deletions .ci/components.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Path rules for .ci/changed-components.sh (see its --help for the syntax).
# Each component is one job in .github/workflows/ci.yml. Files that match no rule trigger nothing
# (README, LICENSE, logo/, design/, Dockerfile, ...).

# CI wiring: changing how CI runs re-runs everything.
_all: .github/workflows/ci.yml .ci/**

# Maven reactor. The Java job narrows the build to the touched modules with .ci/maven-projects.sh.
java: pom.xml .mvn/** mvnw mvnw.cmd .java-version configure/** \
client/** core/** convert/** driver/** executor/** fs/** lib/** notify/** parser/** plugin/** \
scheduler/** shaded/** test/** \
!core/metaforge-web/** !core/metaforge-ui/** !core/pnpm-lock.yaml !core/pnpm-workspace.yaml \
!**/*.md

# Metadata persistence suite against every database the setup wizard offers.
persistence: pom.xml .mvn/** mvnw core/metaforge-service/** core/metaforge-server/pom.xml \
core/metaforge-server/src/** \
!**/*.md

# pnpm workspace: component library and web app.
web: core/metaforge-web/** core/metaforge-ui/** core/pnpm-lock.yaml core/pnpm-workspace.yaml \
!**/*.md

# Documentation site.
docs: docs/**
42 changes: 42 additions & 0 deletions .ci/maven-projects.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Map changed files (stdin, one per line, as printed by `changed-components.sh --files-of java`)
# to the Maven reactor modules that own them.
#
# Prints a comma-separated module list for `-pl`, or nothing when the whole reactor must be built:
# a full run ("*"), or a changed file that belongs to no module (root pom, .mvn, configure/, ...).
#
# Usage: changed-components.sh --files-of java | maven-projects.sh [--github-output]

set -uo pipefail

gh_output=0
[ "${1:-}" = "--github-output" ] && gh_output=1

emit() {
echo "projects=$1"
if [ "$gh_output" -eq 1 ]; then echo "projects=$1" >> "$GITHUB_OUTPUT"; fi
exit 0
}

# Reactor modules, longest path first so a nested module wins over its parent directory.
modules="$(sed -n 's:.*<module>\(.*\)</module>.*:\1:p' pom.xml | awk '{ print length, $0 }' | sort -rn | cut -d' ' -f2-)"

selected=""
while IFS= read -r file; do
[ -z "$file" ] && continue
[ "$file" = "*" ] && emit ""
owner=""
while IFS= read -r module; do
case "$file" in "$module"/*) owner="$module"; break ;; esac
done <<EOF
$modules
EOF
if [ -z "$owner" ]; then
echo "whole reactor: $file belongs to no module" >&2
emit ""
fi
case ",$selected," in *",$owner,"*) ;; *) selected="$selected${selected:+,}$owner" ;; esac
done

echo "modules: ${selected:-none}" >&2
emit "$selected"
Loading
Loading