Compare commits

...

406 Commits

Author SHA1 Message Date
Ngoc Khuat
64977bffa6 just tag to clone 2025-10-03 16:10:22 +07:00
Ngoc Khuat
25dddd8f32 using the correct port 2025-10-03 15:31:02 +07:00
Ngoc Khuat
ee806be8b7 we forgot the localstack 2025-10-03 15:10:49 +07:00
Ngoc Khuat
0ea6e387c0 it's 5001 2025-10-03 15:00:31 +07:00
Ngoc Khuat
f6f128b87d use docker with pinned version for our CI 2025-10-03 14:48:47 +07:00
Phoomparin Mano
8cb9ca883d Change embed flow tracking to track step completions for funnel analysis (#63973) 2025-10-03 12:55:01 +07:00
Phoomparin Mano
384d0b5d3b Update alignment and copy for embedding hub (#64279) 2025-10-03 12:06:24 +07:00
Tyler Plude
1561702bdb Return error string in response when model ID is a question instead of 404 (#64342) 2025-10-02 17:25:51 -07:00
Riley Thompson
4d0eef7217 Store transform create/updates in revision table (#64247)
* store transform revisions

* Add tests

* remove unneeded arity

* fix whitespace

* include impl.transform in revisions.init

* move transform test to enterprise folder

* use =? and check unneeded keys were removed

* revert =? use

* dissoc source from transform comparison
2025-10-02 18:40:59 -04:00
Tyler Plude
cc6827ae8c [METABOT] Use limit in final search response (#64336)
* Limit default 50 search results

* tweak
2025-10-02 14:20:26 -07:00
ignacio
08dffba554 minimal change to dashboard caching steps (#64052)
* minimal change

* whoops

* whoops

* Update docs/configuring-metabase/caching.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/configuring-metabase/caching.md

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Alex Yarosh <alexandra@metabase.com>
2025-10-02 21:12:18 +00:00
Jeff Bruemmer
18b59c1b4d docs - notes on Metabot feedback (#64307)
* notes on feedback

* edit

* link
2025-10-02 17:02:18 -04:00
Anderson
d56be957f0 Show 'See it' link next to 'Saved' button after x-ray is saved as dashboard (#64265)
* Show 'See it' link next to 'Saved' button after x-ray is saved as dashboard

* Use Flex and Group mantine components

* use cy.log instead of JS comments

Co-authored-by: Nemanja Glumac <31325167+nemanjaglumac@users.noreply.github.com>

* reverse the order of e2e assertions/actions

Co-authored-by: Nemanja Glumac <31325167+nemanjaglumac@users.noreply.github.com>

* Fix tests

---------

Co-authored-by: Nemanja Glumac <31325167+nemanjaglumac@users.noreply.github.com>
2025-10-02 17:09:05 -03:00
Edward Paget
6631ed5389 chore: Remove unused column-level middleware (#64326)
* chore: Remove unused column-level middleware

* fixup! update docstring
2025-10-02 19:55:30 +00:00
Noah Moss
16c4a16025 Fix edge case in to-tsquery-expr (#64330) 2025-10-02 19:15:21 +00:00
Edward Paget
2219786d93 fix: validate ldap server email before save (#62616)
Prevents the user from getting an ugly assertion error on login if the
ldap is misconfigured so we can't read a real email from the server response.
2025-10-02 18:46:33 +00:00
Phoomparin Mano
93052b8a8e Hide the step number circle in the setup flow when we only have one step (#64292) 2025-10-03 01:14:00 +07:00
Sébastien
e01cbfc87e Closes EMB-854 escape single quotes in embed code snippets (#64242)
* Closes EMB-854 escape single quotes in embed code snippets

* .

* .

* cleanup
2025-10-02 15:54:37 +02:00
Oleksandr Solovyov
899d6edb3c Mage run tests via nrepl (#64236) 2025-10-02 16:48:59 +03:00
Kamil Mielnik
5705ba7f81 Move SmartScalar subcomponents to separate files (#64283) 2025-10-02 19:44:59 +07:00
Cam Saul
0261a15e7b QP result metadata should always populate :lib/desired-column-alias (#64063)
* QP result metadata should always populate `:lib/desired-column-alias`

* Don't truncate desired column aliases for Table returned columns
2025-10-02 09:03:54 +00:00
Mahatthana (Kelvin) Nomsawadi
02cec9f38d fix(sdk): Allow token withoutexp, but raise a warning (#64238)
* Allow token without exp, but raise a warning

* Fix typing

* Fix wrong doc link anchor

* Fix doc link accessible label

* Add a test

* Fix sso endpoint calling repeating when jwt doesn't contain `exp`

* Fix unit tests

* Fix test for real!

* Fix test name typo

Co-authored-by: Nicolò Pretto <info@npretto.com>

* Use correct terminology "session"

Co-authored-by: Nicolò Pretto <info@npretto.com>

* Fix showing no EXP claim warning when the token is being fetched

Co-authored-by: Nicolò Pretto <info@npretto.com>

---------

Co-authored-by: Nicolò Pretto <info@npretto.com>
2025-10-02 10:01:57 +01:00
Cam Saul
8fa9204d57 Fix formatting for native-query (#64291) 2025-10-02 01:43:18 -07:00
Nicolò Pretto
88229c321e fix(modular): links and type/URL columns should be rendered as clickable (#64243)
links
2025-10-02 10:19:43 +02:00
Timofey Kachalov
4d0d576c13 feat(sdk-bundle): Add SqlParametersList component for InteractiveQuestion and StaticQuestion (#64187) 2025-10-02 10:24:54 +04:00
Timofey Kachalov
7e4dfde94f Adjust sample apps setup (#64274) 2025-10-02 08:59:05 +04:00
William
85fc7cb3fd Dependencies tracking (#63248) 2025-10-01 22:37:16 -04:00
dpsutton
16dc5bece0 Log errors in downgrades (#64309)
Fixes https://github.com/metabase/metabase/issues/62179

Before (and bad) (wordwrap introduced for clarity):
```
2025-08-14 16:17:36,662 WARN app-db.liquibase :: The following
changesets were not rolled back. Likely because they are not in the
changelog file: v56.2025-06-05T16:48:48, v56.2025-06-06T20:11:53,
v56.2025-06-06T20:11:54, v56.2025-06-06T20:11:55,
v56.2025-06-06T20:11:56, v56.2025-06-06T20:11:58,
v56.2025-06-13T15:00:00, v56.2025-07-07T08:02:43,
v56.2025-07-17T20:11:55, v56.2025-07-17T20:11:56 2025-08-14 16:17:36,662
INFO liquibase.logging :: Successfully released change log lock ```
```

And now:

```
2025-10-01 16:00:19,326 INFO app-db.liquibase :: Rolling back app database schema to version 55
2025-10-01 16:00:19,326 INFO app-db.liquibase :: Going to roll back changeset v56.2025-07-17T20:11:56
Rolling Back Changeset: migrations/056_update_migrations.yaml::v56.2025-07-17T20:11:56::edpaget
2025-10-01 16:00:19,328 ERROR app-db.liquibase :: Error rolling back migration v56.2025-07-17T20:11:56
liquibase.exception.RollbackFailedException: liquibase.exception.DatabaseException: ERROR: column "jwt_attributes" does not exist
  Position: 41 [Failed SQL: (0) UPDATE core_user SET login_attributes = jwt_attributes WHERE sso_source = 'jwt']
  	at liquibase.changelog.ChangeSet.rollback(ChangeSet.java:1041)
        ...
Caused by: liquibase.exception.DatabaseException: ERROR: column "jwt_attributes" does not exist
  Position: 41 [Failed SQL: (0) UPDATE core_user SET login_attributes = jwt_attributes WHERE sso_source = 'jwt']
	at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:520)
       ... omitted
       ... 65 more
Caused by: org.postgresql.util.PSQLException: ERROR: column "jwt_attributes" does not exist
  Position: 41
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2734)
	... 70 more

2025-10-01 16:00:19,330 WARN app-db.liquibase :: The following
changesets were not rolled back. Likely because there were errors in
rollback (v56.2025-07-17T20:11:56): v56.2025-06-06T20:11:53,
v56.2025-06-06T20:11:54, v56.2025-06-06T20:11:55,
v56.2025-06-06T20:11:56, v56.2025-06-06T20:11:58,
v56.2025-06-13T15:00:00, v56.2025-07-07T08:02:43,
v56.2025-07-17T20:11:55, v56.2025-07-17T20:11:56 2025-10-01 16:00:19,330
INFO liquibase.logging :: Successfully released change log lock
```

How i recreated:
connected to a jar:
```
MB_DB_CONNECTION_URI="postgres://dan:password@localhost:5432/downgrade-checks" MB_JETTY_PORT=2999 java "$(socket-repl 6000)" -jar $JARS/1.56.6.2.jar
```

```sql
downgrade-checks=# alter table core_user drop column jwt_attributes;
ALTER TABLE
```

this will make a downgrade fail:
```yaml
  - changeSet:
      id: v56.2025-07-17T20:11:56
      author: edpaget
      comment: |
        Add sync login_attributes with jwt_attributes, we need to replace jwt_attributes
        with login attributes for users with sso_source jwt so that they will get the new
        behavior where login_attributes can override jwt_attributes
      changes:
        - sql: >-
           UPDATE core_user
           SET jwt_attributes = login_attributes, login_attributes = '{}'
           WHERE sso_source = 'jwt';
      rollback:
        - sql: >-
           UPDATE core_user
           SET login_attributes = jwt_attributes
           WHERE sso_source = 'jwt';
```

This will fail as the `jwt_attributes` column has been removed.

```
Error rolling back migration v56.2025-07-17T20:11:56
liquibase.exception.RollbackFailedException: liquibase.exception.DatabaseException: ERROR: column "jwt_attributes" does not exist
  Position: 41 [Failed SQL: (0) UPDATE core_user SET login_attributes = jwt_attributes WHERE sso_source = 'jwt']
```

And then connect to the jar again, redefine the changes here, and run

```clojure
  (let [data-source (metabase.app-db.core/data-source)]
    (with-open [conn (.getConnection ^javax.sql.DataSource data-source)]
      (with-liquibase [liquibase conn]
        (rollback-major-version! conn liquibase false))))
```
2025-10-01 17:59:50 -05:00
Nathan Voxland
3f15dcd0ad Better error handling when sync-tracking-atoms fails (#64132) 2025-10-01 16:42:11 -05:00
Phoomparin Mano
6e17e96bf0 feat(sdk-bundle): stacked and sidebar layouts for metabot questions (#64142) 2025-10-02 04:03:24 +07:00
Fraser
59dc6a1376 Remove skipped dashboard toast e2e tests (#64266) 2025-10-02 09:36:51 +13:00
John Swanson
4614a37972 Fix u/slugify function's max-length option (#64256)
* Fix `u/slugify` function's max-length option

`u/slugify` url-encoded non-ASCII characters, then took `max-length`
chars off the result.

Both make sense in isolation - but if we're slugifying, e.g., the string
勇士, with max-length 10, this results in:

- first, url encode non-ASCII characters => "%E5%8B%87%E5%A3%AB"
- then, take 10 characters => "%E5%8B%87%"

But a bare `%` character, as in the trailing character above, is not
valid URI syntax.

Discovered in [UXW-666: Users can't download results for questions with
long cyrillic names, error "URL
malformed"](https://linear.app/metabase/issue/UXW-666/users-cant-download-results-for-questions-with-long-cyrillic-names)
but there are probably more cases where this has caused mischief.

* fix test
2025-10-01 11:53:46 -07:00
Alex Yarosh
648039ca1a docs: don't overhype interactive embedding (#64299)
* docs: don't overhype interactive embedding

* Add in-page promo for embedding workshop

Added a promotional section for the embedding workshop.

* Update docs/embedding/interactive-embedding.md

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-10-01 18:46:48 +00:00
Jeff Bruemmer
2804f26f4b fix placeholder (#64240) 2025-10-01 14:30:33 -04:00
Alex Yarosh
158b78fb25 docs: clickhouse cloud (#64296) 2025-10-01 17:49:45 +00:00
Rodrigo López Dato
9b82a4d92d Add explicit import/export direction to serialization errors (#63777) 2025-10-01 20:30:33 +03:00
dpsutton
5fb41fd3b1 lower log level to debug for field ref issues (#64281)
These log lines will now be debug level warnings rather warning level warnings.
```
<lib.normalize>  Error normalizing MBQL 5
<lib.field.resolution>  We tried every trick we could think
<lib.join>  Failed to find matching column in join
```

Intrepid readers will also notice that moved "Resolved field %s to an
expression. ..." to debug as well.
2025-10-01 11:07:06 -05:00
Rodrigo López Dato
db70faad90 Show full timestamp for revision history entries on hover (#63256) 2025-10-01 15:07:42 +00:00
Alex Yarosh
dddf9d679c docs: serializing new entities (#64284)
Added document comments to the list of non-exported entities.
2025-10-01 10:26:54 -04:00
Uladzimir Havenchyk
c6c0bf73dd tests: wait for data in a flaky test (#64267) 2025-10-01 16:13:00 +03:00
John Swanson
c5da59566e Fix downloading tables grouped by datetime->int (#64245)
* Fix downloading tables grouped by datetime->int

The Linear task has a slightly more involved setup. I found that I could
replicate the issue with a slightly simpler setup:

- set up a simple query:
  - select COUNT from ORDERS
  - group by the day of the month
- log in as the sandboxed user
- try to download the card results (as CSV, XLSX, etc)
- see the error

Why does this happen? I found that, for a sandboxed user, the query
results show the "day of the month" column as having

```
         :base_type :type/DateTime,
         :database_type "TIMESTAMP",
         :effective_type :type/Integer,
```

while an admin user sees the same column as having

```
         :base_type :type/Integer,
         :database_type "INTEGER",
         :effective_type :type/Integer,
```

This seems bizarre and worth looking more into, but honestly shouldn't
really matter - if the effective type is an integer, we certainly
shouldn't be formatting it as a datetime.

`field-is-type?` is only used for checking whether a field is temporal
for formatting purposes, so I think this is a relatively low risk
change, and note that `metabase.lib.types.isa/temporal?` (the
replacement suggested by the deprecation notice for
`metabase.types.core/temporal-field?`) returns `false` for both
cases.

[UXW-660: Pivot tables with integer breakout columns fail to download as formatted XLSX for sandboxed tables](https://linear.app/metabase/issue/UXW-660/pivot-tables-with-integer-breakout-columns-fail-to-download-as)

* Write a test
2025-10-01 05:37:26 -07:00
Kamil Mielnik
f914bf8714 Update table editing e2e tests to not add or remove rows in Sample Database (#64273)
* Update the row deleting test to use writable db

* Update the row adding test to use writable db
2025-10-01 06:16:52 -05:00
Ngoc Khuat
448e9c8278 hide the python runner settings if hosted (#64233) 2025-10-01 08:18:44 +00:00
Nicola Mometto
0ac7bce92b Python runner timeouts (#64095)
* add python runner timeout as setting

* set timeout status

* add timeout status test

* appease kondo

* proper script

* Fix if: expr in upload runner logs

* Fix python runner log name

* Remove setting qualifier

* Add python-runner-timeout-seconds to FE settings type

* Ensure premium feature enabled so setting can be changed

---------

Co-authored-by: Dan Stone <wotbrew@gmail.com>
2025-10-01 09:15:08 +01:00
Romeo Van Snick
ccd8a11ee7 Add context to Save verb and fix similar translation issues (#64077)
* Add context to Save verb

* Add key

* Extract button from nested t

* Find other instances of nested c(...).jt`...${<x>...</x>}...` calls and unnest them
2025-10-01 17:58:46 +10:00
Ngoc Khuat
5164a08b2a Do not run transform test in postgres mysql (#64241) 2025-10-01 04:24:04 +00:00
Romeo Van Snick
e50317d86d Avoid extra interval with single interval in Bar chart (#64175)
* Remove extra interval tick when there is only one interval

* Add repro for metabase#63671

* Update Loki Snapshots

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
2025-10-01 13:31:05 +10:00
Nathan Voxland
3800f7452a Support dbname for redshift in config files (#64069) 2025-09-30 22:21:49 -05:00
Romeo Van Snick
f89073a6bd Do not show error when loading (#64082)
* Pass isRunning to Visualization

* Hide error when query is running

* Add unit test for metabase#63410
2025-10-01 13:05:11 +10:00
Mahatthana (Kelvin) Nomsawadi
d848a88e64 Fix can't drill SQL questions in embedding SDK (#64083)
* Fix can't drill SQL questions in embedding SDK

* Add tests

* Fix the audit DB should not be able to see SQL

* Fix every CI check failing from updating from master

* Address code feedback, make it more clean

* Fix transducer order
2025-10-01 03:10:46 +01:00
Fraser
356025f41b Unskip issue 42049 reproduction (#63862) 2025-10-01 12:32:49 +13:00
Fraser
a0c2ebd9e9 Delete test for non-existent feature (#63683) 2025-10-01 09:51:40 +13:00
Alex Yarosh
c9bc786c60 remove actions from embedding overview (#64249)
Updated the requirement note for embedding types to clarify that a Pro and Enterprise plan is necessary.
2025-09-30 16:30:50 -04:00
Ramiro Nuñez Dosio
1f024e148d Revise README for clarity and updated links (#64194)
* Revise README for clarity and updated links

Update readme with 

- Product image (TBC which image)
- Update links to latest version (no redirects)
- Add mention of new features (Metabot AI and React SDK)
- Add community section

* Update README.md

Co-authored-by: alexandermkinn <85193003+alexandermkinn@users.noreply.github.com>

* Update README.md

Co-authored-by: alexandermkinn <85193003+alexandermkinn@users.noreply.github.com>

* Update Metabase product screenshot URL

Updated the product screenshot link in the README.

* Update README.md

Co-authored-by: Jeff Bruemmer <jeffbruemmer@gmail.com>

* Update README.md

Co-authored-by: Jeff Bruemmer <jeffbruemmer@gmail.com>

---------

Co-authored-by: alexandermkinn <85193003+alexandermkinn@users.noreply.github.com>
Co-authored-by: Jeff Bruemmer <jeffbruemmer@gmail.com>
2025-09-30 16:05:51 -04:00
Alex Yarosh
7c8a53c4d5 docs: pin shape (#64251)
* pin shape

* Update docs/questions/visualizations/map.md

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

* wording

Clarified limitations on data points for maps and added details about pin types.

* image

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-09-30 15:15:11 -04:00
John Swanson
bc28d50013 fix: make popular tables clickable (#64208)
Very silly bug, we were just populating the ID with the wrong
thing (`(:database-id table)` instead of `(:db_id table)`), so the FE
couldn't build links correctly.

There was a mismatch between `recent_views` and `popular_items`
endpoints. They have different queries, but are using the same
postprocessing function. So I needed to unify them: both now use
`:db_id`.
2025-09-30 11:31:59 -07:00
Timofey Kachalov
d0af14f90d Fix SegmentedControl colors (#64107) 2025-09-30 20:25:53 +04:00
Eric Normand
6afcf2aed5 Fix ssh tunneling for clickhouse (#63464)
* Fix ssh tunneling for clickhouse

* Remove questionmark

* Use kebab case keys

* Fix kondo;

This is also fixed in https://github.com/metabase/metabase/pull/63645,
so there may be a conflict.

* Don't squash exceptions.

* remove some tests, fix some tests

I removed some tests. Let's be very clear why this is happening. Push
back if you disagree:

```clojure
(deftest clickhouse-connection-fails-test
  (mt/test-driver :clickhouse
    (mt/with-temp [:model/Database db {:details (assoc (:details (mt/db)) :password "wrongpassword") :engine :clickhouse}]
      (testing "`driver/database-supports? :uploads` does not throw even if the connection fails."
        (is (false? (driver/database-supports? :clickhouse :uploads db)))
        (is (false? (driver/database-supports? :clickhouse :uploads nil))))
      (testing "`driver/database-supports? :connection-impersonation` does not throw even if the connection fails."
        (is (false? (driver/database-supports? :clickhouse :connection-impersonation db)))
        (is (false? (driver/database-supports? :clickhouse :connection-impersonation nil))))
      (testing (str "`sql-jdbc.conn/connection-details->spec` does not throw even if the connection fails, "
                    "and doesn't include the `select_sequential_consistency` parameter.")
        (is (nil? (:select_sequential_consistency (sql-jdbc.conn/connection-details->spec :clickhouse db))))
        (is (nil? (:select_sequential_consistency (sql-jdbc.conn/connection-details->spec :clickhouse nil))))))))
```

This test is _GONE_ because it's insane that we are testing that
`conneciton-details->spec` and `database-supports?` is resilient to
opening a connection to a server. That's nuts. We don't do that any
more. Should be the same as if checking `(+ 1 1)` doesn't open a network
connection. We get version information in

```clojure
(def ^:private ^{:arglists '([database])} get-clickhouse-version
  (memoize/ttl
   ^{:clojure.core.memoize/args-fn (fn [[database]] (:details database))}
   (fn [database]
     (sql-jdbc.execute/do-with-connection-with-options
      :clickhouse
      (sql-jdbc.conn/db->pooled-connection-spec database)
      nil
      (fn [^java.sql.Connection conn]
        (with-open [ver-stmt (.createStatement conn)
                    ver-rset (.executeQuery ver-stmt clickhouse-version-query)
                    cloud-stmt (.createStatement conn)
                    cloud-rset (.executeQuery cloud-stmt "SELECT value='1' FROM system.settings WHERE name='cloud_mode'")]
          (cond-> nil
            (.next ver-rset)
            (assoc :version          (.getString ver-rset 1)
                   :semantic-version {:major (.getInt ver-rset 2)
                                      :minor (.getInt ver-rset 3)})

            (.next cloud-rset)
            (assoc :cloud (.getBoolean cloud-rset 1)))))))
   :ttl/threshold default-cache-ttl))

(defmethod driver/dbms-version :clickhouse
  [_driver db]
  (get-clickhouse-version db))
```

We don't need to run this query every time you get a connection spec or
ask if the database supports something. We have the version and if it's
cloud and that's sufficient. The only reason it was opening a connection
was to run the cloud check (`select value=1 from system.settings where
name=cloud_mode`) above.

Also removed:
```clojure
(deftest impersonation-support-check-over-ssh-tunnel-test
  (testing "driver-supports? :connection-impersonation should work through an SSH tunnel (#62377)"
    ;; Use an in-memory SSH server that forwards to the correct port through localhost.
    ;; Since the real database is still reachable locally, it's possible for the driver to ignore the SSH tunnel and
    ;; still connect to the DB. So this test runs twice, once with all correct and once with an incorrect SSH
    ;; password. The latter check should fail (returning false for `driver-supports?`) if the SSH tunnel is being
    ;; respected.
    (mt/test-driver :clickhouse
      (let [username "username", password "password"]
        (with-open [ssh-server (driver.tu/basic-auth-ssh-server username password)]
          (doseq [[correct-password? ssh-password] [[true password] [false "wrong-password"]]]
            (memoize/memo-clear! @#'clickhouse.version/get-clickhouse-version)
            (let [ssh-port (.getPort ssh-server)]
              (with-ssh-tunnel! {:tunnel-enabled true
                                 :tunnel-host "localhost"
                                 :tunnel-auth-option "password"
                                 :tunnel-port ssh-port
                                 :tunnel-user username
                                 :tunnel-pass ssh-password}
                (testing (str "using " ssh-password)
                  (is (= correct-password?
                         (driver/database-supports? :clickhouse :connection-impersonation (mt/id)))))))))))))
```

Again, this is verifying connection resiliency in a call
to `(driver/database-supports? :clickhouse
:connection-impersonation (mt/id))` and ensuring that it uses the ssh
tunnel. This entire concern is gone, and a red flag that it ever
existed.

Changes:
a few tests used the `db` from `with-temp` to do stuff, but now that we
require them to have dbms_version i populated that

in the version check i thought i saw one in test going through with
`dbms-version` and not `dbms_version` so i'm checking both just to be
sure. it's a bit sloppy

* small changes and add back test

* handle dbms-version vs. dbms_version

* fix kondo

---------

Co-authored-by: Riley Thompson <riley@metabase.com>
Co-authored-by: dan sutton <dan@dpsutton.com>
Co-authored-by: Riley Thompson <rileythompson99@gmail.com>
2025-09-30 11:53:45 -04:00
yaojie
99d7d54af3 Set send-server-version? to false to hide Server version from response headers (#57257)
* Set send-server-version? to be false by default

* Update test
2025-09-30 16:40:19 +01:00
Dan Stone
1610538386 MariaDB transform cancellation fix (#64092) 2025-09-30 16:13:41 +01:00
Bergbok
1d94009c3d Update broken link in README (#63000) 2025-09-30 11:12:31 -04:00
Jeff Bruemmer
b8360b6da3 docs - document layout (#64209)
* document layout

* do stuff
2025-09-30 14:58:10 +00:00
Oleksandr Solovyov
cb13bdc086 simpler way to set token: mt/with-random-premium-token! (#64188) 2025-09-30 17:06:53 +03:00
Timofey Kachalov
1704f14bda refactor(sdk): Properly reinitialize metabaseConfig watcher for EmbedJS wizard (#64235) 2025-09-30 17:48:14 +04:00
John Swanson
593ecfb952 Use SQL SECURITY INVOKER for mysql views (#62537)
[UXW-263: Aurora MySQL AppDB can't create Metabase Analytics views
without using `SQL SECURITY
INVOKER`](https://linear.app/metabase/issue/UXW-263/aurora-mysql-appdb-cant-create-metabase-analytics-views-without-using)

Updates all the MySQL view creations to use `SQL SECURITY INVOKER`.
2025-09-30 06:07:10 -07:00
github-automation-metabase
611220c5e0 Update generated docs (master) (#64216)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-30 08:56:57 -04:00
Dan Stone
b77f570c57 Add python runner logs as artifacts on failed tests (#64093)
* Factor out setup/log actions for python runner, use in driver tests

* Remove redundant cd

Co-authored-by: Nicolò Maria Mezzopera <nicolo.mezzopera@metabase.com>

---------

Co-authored-by: Nicolò Maria Mezzopera <nicolo.mezzopera@metabase.com>
2025-09-30 11:59:24 +01:00
Timofey Kachalov
8ba64b7bcd fix(sdk): Fix SDK refresh token race-conditions (#64094) 2025-09-30 13:09:58 +04:00
Nicola Mometto
e1dcfdab2e Do not realize objects in memory early for python transform results (#64034)
* partition documents for mongo insert

* feat: s3/read-to-stream

* don't keep files in memory, stream them

* fix tests

* proper types

* slurp conditionally

* replace_existing

* nil safe

* Tweak InputStream lifetimes

* Fix test now read-to-string returns nil

* Fix kondo / reflection

---------

Co-authored-by: Dan Stone <wotbrew@gmail.com>
2025-09-30 09:42:34 +01:00
Timofey Kachalov
5c9b282361 Update typedoc and its plugins versions (#64219) 2025-09-30 11:43:47 +04:00
Oleksandr Solovyov
cf5c7bd4c3 [search] better search for CamelCased tables and dbs (#64043) 2025-09-30 06:20:14 +00:00
Nemanja Glumac
46adff882f Fix metrics-collection e2e flake (#64204)
We're making the assertion a bit more flexible
without losing the confidence that this test
was supposed to give us when it was created.
2025-09-30 07:50:30 +02:00
Cam Saul
87923e1e1d Fix duplicate coercion on custom columns from joins (#63941)
* Fix duplicate coercion on custom columns from joins

* Fix #63991

* Test fixes 🔧

* Another round of test fixes 🔧

* Test fixes 🔧

* Kondo lint fixes 🔧
2025-09-29 22:16:56 -07:00
Romeo Van Snick
5bd544baf5 Fix native transform editor results UI warts (#64081)
* Pass className to native editor

* Add missing border on top of native editor

* Set minimal editor height so the results panel is always visible

* Move initial height calculation to hook
2025-09-30 14:04:22 +10:00
Anderson
f8d410f858 Change dark ClickHouse icon to be yellow (#64213) 2025-09-29 22:57:18 -03:00
Aleksandr Lesnenko
cfa62e4b8b original card description should be provided to visualizer (#64197) 2025-09-30 00:28:07 +00:00
Romeo Van Snick
fa2820320e Fix zoom and hover on map while editing (#64174)
* Add missing import

* Use late-binding for handlers so they can change without having to recreate markers

* Allow isEditing props to re-render Map component

* Allow disabling zoom control on maps

* Allow clicking the Map action buttons

* Disable zoom and hover when in editing mode

* Add repro for metabase#64138

* Fix e2e tests
2025-09-30 09:03:51 +10:00
Romeo Van Snick
33070f6e06 Fix completion results (#64080)
* Do not shrink grid rows in completion results

* Add e2e test for metabase#63711
2025-09-30 09:03:13 +10:00
Denis Berezin
f43c6462d8 Add support for special intl chars for email formatting (#64060)
* Add support for special intl chars for email formatting

* Fix review comments

* Fix unit tests
2025-09-30 00:16:28 +04:00
Brad Anderson
8f4ccdf2ba Fix #63904: Corrects dashcard selector usage (#64140)
* UXW-1766 Fixes issue where getDashboardHeaderParameters looks at all cached dashcards rather than just the ones from the currently viewed dashboard

* UXW-1766 Adds/updates unit tests
2025-09-29 13:20:34 -04:00
Nemanja Glumac
788bf01ea9 Report Metabot feedback directly to Harbormaster (#64040)
We're introducing a new endpoint in metabase/metabase. It sends the feedback to the backend which then (1) fetches the premium token and (2) constructs the correct store api URL with the same feedback as the payload. Our backend acts as a proxy because the api url contains the token and we can't send it from the FE.
2025-09-29 19:06:51 +02:00
Noah Moss
c4de2725e3 Extract native query content for search indexing rather than the entire dataset_query structure (#64125)
* Extract native query content for search indexing rather than the entire dataset_query structure

* remove inline def

* Fix doc string

* Update search spec field-fields logic to support the :fn syntax to fix test

* Remvoe query_type from expected card spec fields as we're no longer using it to detect native query changes

* Address feedback on :fn semantics, and add a more detailed docstring to define-spec macro
2025-09-29 12:17:17 -04:00
Braden Shepherdson
cd0965a299 [Vertica] Support Vertica UUID columns as :type/UUID (#62512) 2025-09-29 15:38:59 +00:00
Uladzimir Havenchyk
95452f41d3 feat: use new detail view in metadata preview (#63968)
* feat: use new detail view in metadata preview

* drop relationships

* fix e2e helper

* use correct '

* make table responsive

* update helper

* adjust values in tests

* use useSampleData

* rework approach

* update helper

* oops, lost changes

* restore test

* let's add table just in case

* another attempt

* responsive

* restore indexes

* rename index -> rowNumber

* show details group in more cases

* remove force: true

* fix index
2025-09-29 17:31:30 +03:00
John Swanson
b323ecd565 Add a timeout for slow LDAP (#63852)
When the LDAP server is slow, we should fall back to normal
authentication.

For now, use a configurable timeout, defaulting to 15 seconds - this
seems on the high side of reasonable.

[UXW-291: When LDAP is configured, then normal email logins can be blocked if LDAP server is slow/down](https://linear.app/metabase/issue/UXW-291/when-ldap-is-configured-then-normal-email-logins-can-be-blocked-if)
2025-09-29 07:08:10 -07:00
Edward Paget
b2939990fc fix: correct filtering for internal collections (#64065)
* fix: correct filtering for internal collections

* fixup! set is_sample flag on archived collection

filter out analytics namespace
2025-09-29 08:25:36 -05:00
Alexander Polyankin
c63dff0d7b Fixes viz settins for details-only columns (#64113) 2025-09-29 09:12:38 -04:00
John Swanson
521eed05c5 Do not URL-encode default redirect URL (#63965)
I think this was just a mistake - there's no need to URL-encode this and
it actually breaks the redirect.
2025-09-29 06:05:13 -07:00
John Swanson
e88afceba9 Index analytics collections (#64064)
These were excluded from the index, but they should really be in there.
2025-09-29 06:04:02 -07:00
John Swanson
ac2003368e When deleting DB, hide cards from search (#64112)
* When deleting DB, hide cards from search

We have a current issue with search: deleting items does not actually
remove them from search.

This is a particularly nasty version of this, because while usually a
delete follows an update (that marks the card as archived,
which *does* remove it from search), in this case we're just deleting
the items directly as part of an `ON DELETE CASCADE`.

This is a bit hacky, but for now we can just mark them as `archived`
before we delete them to hide them from search.

[UXW-602: Search API returns inexisting cards](https://linear.app/metabase/issue/UXW-602/search-api-returns-inexisting-cards)
2025-09-29 06:03:53 -07:00
Timofey Kachalov
1d2fc06b60 feat(embed-js): Add support of fetchRequestToken for embed-js (#64004) 2025-09-29 16:12:43 +04:00
Kamil Mielnik
581c1e7a38 WRK-871 Details view: JSON formatting missing in details view (#63892)
* Format JSON in new detail view

* Use mantine props

* Use Code

* Use CodeEditor
2025-09-29 10:31:59 +00:00
Romeo Van Snick
17a61a81c8 Add missing import (#64171) 2025-09-29 11:17:26 +02:00
Romeo Van Snick
1d699a5fae Use the entities display name if possible (#64076) 2025-09-29 13:32:11 +10:00
Ngoc Khuat
277d1fdaff Skip sync transforms temp table (#64037) 2025-09-28 15:00:43 +00:00
Oleksandr Yakushev
82b3ba1fcc [perf] Optimize metabase.lib.field.resolution/merge-metadata (#62425) 2025-09-28 13:37:56 +03:00
Dan Stone
dd7845cc83 Improve python error feedback capability (#64053)
* Add i18n / formatting to existing log calls

* Cleanup log conveyance to failure :message

* Improve error feedback capability

- Ensure exception messages do not leak to user logs by default 'Something went wrong'
- Exceptions can carry a `transform-message` key to provide a custom failure message (with i18n)
- Defined messaging for:
   - Error during table copy
   - Error during execution
   - Error during writeback

I would like to follow up with additional context in the form of message log entries for further progress / context of any failure.

Logs can be correlated to metabase logs for stack traces or further debugging. Python output remains presented as-is (traceback etc).
2025-09-27 15:31:57 +00:00
Edward Paget
7e7ed1ac9f fix(scim): support patch requests without a path (#64130)
adheres to the standard and accomodates how we can get these requests
from Okta.
2025-09-26 16:18:45 -05:00
Jeff Bruemmer
19387d8d29 add transforms option (#64128) 2025-09-26 16:45:46 -04:00
Alex Yarosh
7ac8feb49b docs: embedding hub changes (#64012)
* embedding hub changes

* more edits

* Apply suggestions from code review

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-09-26 20:04:08 +00:00
Alex Yarosh
4447e2c6bc expand embedding comparison table (#64071) 2025-09-26 15:47:01 -04:00
Oleksandr Yakushev
8434b23764 [match] Prevent match-lite from extracting common result that depends on uncommon bindings (#64073)
* [match] Prevent match-lite from extracting common result that depends on uncommon bindings

* [match] Fail if match-lite's :guard is provided with incorrect predicate syntax

Also fix its treatment of named functions passed as predicates.
2025-09-26 22:39:26 +03:00
Jeff Bruemmer
be72407fc8 docs - RLS notes (#64111) 2025-09-26 19:34:07 +00:00
John Swanson
e530911305 Correctly render empty series in static viz (#63987)
* Correctly render empty series in static viz

[UXW-1754: Row chart with an empty series fails to send on static viz](https://linear.app/metabase/issue/UXW-1754/row-chart-with-an-empty-series-fails-to-send-on-static-viz)

`getColumnValueFormatter` and `getColumnValueStaticFormatter` had
different behaviors for empty strings, so this worked on the frontend
but failed for static visualizations.

* cleanup

---------

Co-authored-by: Aleksandr Lesnenko <alxnddr@gmail.com>
2025-09-26 11:49:59 -07:00
Noah Moss
ca9ba3390d make u/profile log lines look nicer (#64114) 2025-09-26 18:01:53 +00:00
Oleksandr Solovyov
a947f3cb94 [advanced-config] uppercased letter in users email should not fail (#64109)
fixes #62894
2025-09-26 17:20:39 +00:00
Dan Stone
33de954fcf Temporarily disable python transforms tests for BQ/Snowflake (#64118) 2025-09-26 17:15:34 +00:00
Kamil Mielnik
db79c64d3d DSN-73 Verified badge icon should be correct size and nearer text in model and saved question titles (#63871)
* Fix verified badge styling

* Misalign icons :see-no-evil:

* Remove min width on dashboard caption input

* Fix overflow
2025-09-26 16:14:41 +00:00
Jakub Chodorowicz
3e646a69f3 Move dev instances upsell down on embedding settings pages (#64099) 2025-09-26 17:57:27 +02:00
Sébastien
d6c15aab01 Closes EMB-853 renamed legends get ignored by translation (#64023)
* Closes EMB-853 renmaed legends get ignored by translation

* feedback

* if -> ts-pattern
2025-09-26 16:04:57 +02:00
Jeff Bruemmer
34c224b5f2 docs - verified content (#64067) 2025-09-26 13:28:33 +00:00
Sébastien
568443a99c Closes EMB-407 transparent background download pdf (#63836)
* Closes EMB-407 transparent background download pdf

* e2e

* cleanup
2025-09-26 15:18:24 +02:00
github-automation-metabase
5fe1efe15b Update generated docs (master) (#64078)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-26 06:46:56 -04:00
Alexander Polyankin
894176cf26 Add missing transform filters (#63998)
* Params

* Params

* Params

* Params

* Params

* Params

* Rename param

* Transform params

* Transform params

* Transform params

* Transform params

* Transform params

* Transform params

* Transform params

* Transform params

* fixes

* add a test

* add a test

* add a test

* add a test

* add a test

* Fix field filters for type/TextLike

* Fix polling
2025-09-26 06:39:11 -04:00
lbrdnk
c28f66c961 Add guards to metabot and semantic search job implementations (#64031)
* Fix arity

* Add guards for job implementations

* Adjust test
2025-09-26 10:36:00 +02:00
Kamil Mielnik
85e6e7f779 DSN-74 People page should use tabs instead of radios for active/deactivated control (#63817)
* Inline AdminPaneLayout

* Do not show invite button on deactivated tab

* Simplify

* Use modern button

* Add tabs in People page

* Move mb

* Fix typo

* Make people search input full width

* Move tabs to the top
2025-09-26 15:19:24 +07:00
Kamil Mielnik
d44a2cab66 DSN-67 We could improve the "Scanning for Filter Values" setting (#63887)
* Update scanning schedule form to use new UI components

* Update tests
2025-09-26 15:18:35 +07:00
Brad Anderson
e349faa741 Fix: #60843 Prevents dashboard from being saved when clicking "Discard changes" (#63899)
* UXW-333 Prevents `updateDashboardAndCards` from being called when discarding changes (still called when clicking "Save changes")

* UXW-333 Adds e2e test
2025-09-25 17:40:54 -04:00
Aleksandr Lesnenko
817af7b71d pass lat and lon fields to the tile endpoints as query params (#63533)
* for fetching tiles encode field refs as safe base64

* clojure implementation

* update public api

* pass lat and lon fields in query params

* specs

* fix specs

* update preview endpoints and tests

* clean up previous url safe base64 implementation

* fix specs
2025-09-25 21:11:26 +00:00
Jeff Bruemmer
e8cd58b376 Revise contributor instructions in PR template (#64059)
Updated warning section for first-time contributors.
2025-09-25 20:07:31 +00:00
Brad Anderson
62d7beec2b Fix: #63463 Loosens condition that forces saving to dashboard (#63855)
* UXW-709 When drilling into a dashboard card that had a filter applied, the resulting query can now be saved outside of the original dashboard. "New Question"/"New SQL query" via dashboard edit screen behavior is unaffected (still forces you to save to that dashboard).

* UXW-709 Updates unit tests
2025-09-25 15:55:45 -04:00
Brad Anderson
c2ec56beed UXW-172 Fix is-neg condition (#63905) 2025-09-25 15:54:48 -04:00
Nathan Voxland
5274867997 Log system signals for better debugging (#63780) 2025-09-25 13:56:48 -05:00
Anderson
b5a9d7457f Have a separate email content for user joining through setup invitation (#63778)
* Allow redirect url from password reset page

* Add await when inviting user so that errors will be displayed

* Allow for different email content when inviting user from setup / Set returnUrl param

* Code refinements

* Add backend tests

* Add frontend tests

* Run formatter

* handle email content when invitor's first name is empty/unset
2025-09-25 15:36:08 -03:00
Radoš Milićev
12f4387864 Fix links in CONTRIBUTING.md (#63653) 2025-09-25 14:31:54 -04:00
Jakub Chodorowicz
6b5e3bd646 Prg 154 allow running dev env on a custom port (#63875)
* Allow running dev on custom MB_FRONTEND_DEV_PORT

Signed-off-by: Jakub Chodorowicz <jakub@chodorowicz.com>

* Unify port env var naming between JS and Clojure

* Add dev server port info

* Update devenv docs

Co-authored-by: Sébastien <sebastien@metabase.com>

* update docs

---------

Signed-off-by: Jakub Chodorowicz <jakub@chodorowicz.com>
Co-authored-by: Sébastien <sebastien@metabase.com>
2025-09-25 20:18:33 +02:00
José H.
b7c4063dd9 [docs] Add SPARQL driver in community drivers list (#61994) 2025-09-25 13:57:36 -04:00
Anton
49fcc4a40f Fixed misspell in timezones.md (#64041) 2025-09-25 13:52:24 -04:00
Denis Berezin
7fb62b782b Document Layout - add charts side-to-side (#63101)
* Add working table with 2 columns

* Table layout and dnd polishing

* ResizeNode

* Refactor to use grid container

* Add Card node title ellipsification

* cleanup, add min height

* Fix FlexContainer to work with ResizeNode

* Fix empty ResizeNode after card dnd

* Document layout no dnd kit (#63363)

* using tiptap drag and drop

* Fix some issues with dnd

* Add support for resize node, fix styles

* Remove comments

---------

Co-authored-by: Nick Fitzpatrick <nickfitz.582@gmail.com>

* Fixes after merge comments

* Fix issues with dnd logic

* Fix issue where rearranging columns within a flexContainer didn't respect which side of a cardEmbed we dropped; it always inserted dragged column to the left.

* Fix issue where moving a cardEmbed out of a flexContainer and placing it right after doesn't wrap the card in a resizer

* Fix issues with dropzones and card id

* Fix issue with column resize handlers

* Fix issues with cards previews on dnd

* Feat: UXW-717 Reconcile comments with document layout (#63593)

* UXW-717 Add comment option to cardEmbed menu
* UXW-717 Wires up comment option in cardEmbed menu
* UXW-717 Stubs out CommentsMenu reorganization so logic can be reused inside cardEmbeds (button and menu item)
* UXW-717 Design tweaks per design feedback (and fixes ts error)
* UXW-717 Updates hover state of cardEmbed ellipsis menu trigger per design feedback

* Fix issues with funnel chart and resizer

* Fix issues with column rearrange

* Fix adding third column position

* UXW-739 Adds ResizeNode wrapper to charts added by metabot

* UXW-749 [1/2] Fix: Cutting/copying a chart from a group then pasting it (cmd+v) results in a chart without a resizeNode

* UXW-749 [2/2] Fix: Copying and pasting from one chart to another doesn't preserve the structure correctly

* Refactor dnd logic - consolidate all use cases in HandleEditorDrop

* remove redundant message and add_message icons

* actually remove redundant message icons

* replace references to old icons with new icons

* Fix issue with dropping a card into existing flexContainer

* Fix issue with moving a card from one flexContainer into another

* UXW-748 - Fix broken document when typing with a card selected

* Handle dropping cards onto paragraphs (#63754)

* Handle dropping cards onto paragraphs

* PR Feedback

* cleanup flex containers

---------

Co-authored-by: Denis Berezin <denis.berezin@metabase.com>

* small feedbacks

* breaking up document drop handler

* UXW-689 - add basic e2e tests

* type fix

* loki diff

* Add more e2e tests

* Fix typecheck

* happy types

* passing document.cy.spec

* Fix e2e tests

* e2e test for card resizing

* flex container column resize tests

* Add node deletion e2e tests

* Fix review issues

* Try to fix typecheck

* Refactor useCommentsButtonProps to a react component

* final PR feedback

* fix removing a card via menu

---------

Co-authored-by: Nick Fitzpatrick <nickfitz.582@gmail.com>
Co-authored-by: Brad Anderson <brad@metabase.com>
Co-authored-by: Maz Ameli <maz@metabase.com>
Co-authored-by: Nick Fitzpatrick <nick@metabase.com>
Co-authored-by: Kamil Mielnik <kamil@kamilmielnik.com>
2025-09-25 21:08:49 +04:00
Phoomparin Mano
f393237eb9 Adjust link and action button layout for modular embedding cards (#63876) 2025-09-25 23:00:29 +07:00
Alexander Polyankin
48376d3f63 Fix field filters for type/TextLike (#64045) 2025-09-25 15:47:16 +00:00
github-automation-metabase
a67c48a036 Update generated docs (master) (#64017)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-25 10:29:52 -04:00
Alex Yarosh
8c3d77473a docs: renaming sheets columns (#64011) 2025-09-25 10:29:07 -04:00
Kamil Mielnik
9f029dbb2f WRK-900 [Bug] Detail View: related records are messed up in tables with no PK (#63977)
* Add repro for WRK-900

* Hide relationships when there's no PK
2025-09-25 21:07:38 +07:00
Kamil Mielnik
1adaaae66e WRK-899 Detail view: keep fields used as titles & sub-titles in the regular list of fields (#63889)
* Include header columns in the body of detail view

* Update tests
2025-09-25 21:07:07 +07:00
Oleksandr Solovyov
21956d6ab7 [serdes] NativeQuerySnippet collection_id should not prevent export (#63870)
Previously `extract-query "NativeQuerySnippet"` would use standard method for exporting entities, which checks for
collection_id in entity and prevents its export if it's outside requested collections.

While that makes sense for Cards (and we do escape analysis for those), snippets live in their own separate collection
namespace and this logic is not relevant to them. So now we export either those in requested collections _or_
dependencies of cards that are being exported.
2025-09-25 17:03:23 +03:00
Sébastien
fd94a0b0cb feat(sdk-embed): adds onVisualizationChange to InteractiveDashboard and InteractiveQuestion (#63969)
* Closes EMB-152 add onVisualizationChange callback to SDK embedding components

* .

* .

* .

* fixed schema

* height

* .
2025-09-25 15:59:28 +02:00
Nicola Mometto
7b6fbd6374 Python Transforms (#63700)
* cherry pick driver code (#63628)

* cherry pick driver code

* update changelog

* add type->database-type unit tests

* kondo

* create/insert table

* insert-from-jsonl test

* missing rename-tables for snowflake

* extend rename-tables-test to more drivers

* line breaks

* add driver python transform feature

* handle review comments

* kondo

* feat: replace string->val with a more generic insert-col->val

* remove non transactional impls

* chore: docsstrings

* TODO

* extra test

* fix extra test

* test all base-types

* fix sqls

* setup ci properly (#63693)

* S3 transport layer for python-runner (#63697)

* Add s3 dependencies (#63706)

* port prometheus/instrumentation (#63631)

* port prometheus metrics

* port instrumentation

* instrument existing transform paths

* wider buckets

* remove nil handling

* warn on nil bytes/rows

* add stage-type mapping

* typo

* split CI into separate jobs (#63746)

* Add python_runner.clj (#63747)

* Add python runner

* Kondo

* Traceback fix

* Remove dead code

* start the runner by default

* Cancellation not used yet

* Remove unused keys from fields-metadata

* cherry pick driver fixes

* start for postgres and mysql as well

* clickhouse fixes

* relax for snowflake

* typo

* exclude transform-python-test from appdb

* exclude transforms-python-test as well

* try exclude-tag here too

---------

Co-authored-by: Ngoc Khuat <qn.khuat@gmail.com>
Co-authored-by: Nicola Mometto <nicola.mometto@metabase.com>

* execute.clj (#63755)

* execute.clj

* with drivers test and execute test

* with wait tables

* missing utils

* /s/open/start

* fix failing tests due to getting the wrong source and target

* kondo

* move cancel-python-code-http-call to python-runner

* Dan's feedback

* we have 2 implementstation of cancel

* and 2 db-routing-enabled?

---------

Co-authored-by: Nicola Mometto <nicola.mometto@metabase.com>

* Transforms python APIs (#63762)

* transforms python api

* new tests pass locally

* clean up the db id utils

* move to util

* fix: missing refer

* chore: missing tests/kondo

* kondo

* more kondo

* fix: make function resilient

* eh, validate on old

* on new

* Add python transform support for jobs (#63764)

* Add python transforms job support

* Fix whitespace in when

* Avoid churn due to new local

* Add feature test

* Add ignore for logs (there might be away to avoid this)

* Use new target-database-id util

* Remove duplicated fn

---------

Co-authored-by: Nicola Mometto <nicola.mometto@metabase.com>
Co-authored-by: Dan Stone <wotbrew@gmail.com>

* Move transform ordering tests to the python module (#63827)

* Add transform ordering tests to the python module

- Consistent with api tests for python transforms being in the python
module
- In practice transforms module 'knows' about python, so this is
organizational only
- Copied test helpers for now, not sure if functions strong enough to be
shared

* Check :transforms/python

* Proj python/table name len (#63842)

* feat: ensure temp-table-name respects max length

* add unit test

* add limit for missing drivers

* depend on it

* fix: use db instead of db-id

* Proj ptyhon/table swap (#63878)

* add rename feature, rename-table! multimethod

* add table swap with atomic or rename or fallback

* changelog

* drop requirement

* ensure we're testing replace flow

* wait for completion, table already exists

* wip

* add rename-table-test

* fix for snowflake

* fix: support bigints (#63898)

* fix: support bigints

* merge meta

* Frontend for Python Transforms (#63699)

* cherry pick driver code (#63628)

* cherry pick driver code

* update changelog

* add type->database-type unit tests

* kondo

* create/insert table

* insert-from-jsonl test

* missing rename-tables for snowflake

* extend rename-tables-test to more drivers

* line breaks

* add driver python transform feature

* handle review comments

* kondo

* feat: replace string->val with a more generic insert-col->val

* remove non transactional impls

* chore: docsstrings

* TODO

* extra test

* fix extra test

* test all base-types

* fix sqls

* setup ci properly (#63693)

* feat: add Python transform frontend pages

* Integerate with FE

* Fix wrong source field name used for showing script in transform view

* Revert "Fix wrong source field name used for showing script in transform view"

This reverts commit c7dfb541f3.

* Fix edit button not doing anything for python scripts

Closes QUE-2300

* call api proxy instead of internal call, also have settings page for transform

* python transforms now properly being scheduled

* FE select table when creating python transform

* multiple tables

* ensure tables are unique in tables selector

* source alignments

* run test

* dead code

* Better default schema, better docstring

* fixex test run

* add cancel button

* better endpoint name

* add cancel button to test python endpoint

* working button

* Auto-update Python transform function signature when table aliases change

- Automatically updates def transform(...) signature when aliases are modified
- Updates docstring Args section with aligned descriptions and table names
- Adds reset button to restore default slugified aliases
- Validates alias input to only allow valid Python identifiers
- Handles multi-line signatures for many parameters (>80 chars)
- Shows visual distinction between custom and auto-generated aliases
- Fixes code editor layout to prevent overlap with Run button

* feat: settings page with s3 configs

* feat: split settings

* remove placeholders

* eh, rename to appease the munging

* Logs are viewable inline during execution of python transforms

* Some minor fixes around docstring rewriting

* solve more fe lints

* fix type errors

* more type check fixes - including some smelly optional override stuff

* fix delete transform + table

* fix: don't remove indentation before """

* chore: allow empty schemas

* Critical fix: docstring indentation

* Separate file / s3 lifetimes / writes / reads from http calls (#63294)

- python-runner no longer simulates a single http api that does
everything (incl s3 interaction)
- Separates file lifetimes (shared storage) from execution
- Easier to see how to avoid reading into strings (e.g. for piping into
tmp files, follow up)

Earlier on we had a service that managed much of the I/O, metabase now
coordinates it so it makes little sense pretending there is still
an overall http api.
# Conflicts:
#	enterprise/backend/src/metabase_enterprise/transforms/api.clj
#	enterprise/backend/src/metabase_enterprise/transforms/execute.clj
#	enterprise/backend/src/metabase_enterprise/transforms/python_runner.clj
#	enterprise/backend/test/metabase_enterprise/transforms/python_runner_test.clj

* Add first-class PythonTransformSource type

# Conflicts:
#	enterprise/frontend/src/metabase-enterprise/transforms/components/QueryEditor/EditorBody/EditorBody.tsx

* Lay python editor out in two columns

* Make python editor resizable

* Move parseCSV to utils

* Split off results into separate component

* Add empty and loading state components

* Split up ExecutionResult component

* Move python execution to separate hook

* Remove color in editor gutter

* Increase indentUnit for python

* Allow extension to be passed to CodeEditor

* Add pandas completions

* Use DataGrid for displaying results

* Python library APIs (#63378)

Co-authored-by: Romeo Van Snick <romeo@romeovansnick.be>
# Conflicts:
#	enterprise/backend/src/metabase_enterprise/api/routes.clj
#	enterprise/backend/src/metabase_enterprise/transforms/python_runner.clj
#	enterprise/backend/test/metabase_enterprise/transforms/python_runner_test.clj
#	enterprise/frontend/src/metabase-enterprise/api/tags.ts
#	resources/migrations/057_update_migrations.yaml

* transforms python module (#63503)

# Conflicts:
#	enterprise/backend/src/metabase_enterprise/transforms/api.clj
#	enterprise/backend/src/metabase_enterprise/transforms/execute.clj
#	enterprise/backend/src/metabase_enterprise/transforms/jobs.clj
#	enterprise/backend/src/metabase_enterprise/transforms/util.clj
#	enterprise/backend/src/metabase_enterprise/transforms_python/python_runner.clj
#	enterprise/backend/test/metabase_enterprise/transforms_python/api_test.clj
#	enterprise/backend/test/metabase_enterprise/transforms_python/e2e_test.clj
#	enterprise/backend/test/metabase_enterprise/transforms_python/python_runner_test.clj

* Use normal title case

* Handle json-line output

* Remove unused props

* Rename PythonEditor to PythonQueryEditor

* Move script rewriter to utils

* Flatten Python transform page

* Rename shared to common

* Remove dead code

* Reduce specialization in Transform editor

* Remove unused props

* Move PythonQueryEditor to top-level components

* Nest Python editor components in PythonTransformEditor

* Restructure Python transform editor

* Split up component more

* Add helpers for python editor

* Disable default schema

* Add test ids

* Fix import path

* Reuse transform save modal

* Fix parameter

* Add e2e tests for python common lib

* Move python transform api to general transforms folder

* Move type to metabase-api/types

* Disable debugger for python transforms for now, allow to open it with query param

* Disable debugger hotkey for python transforms

* Add syntax highlighting to Python script on Transform page

* Remove cancelation code for now

# Conflicts:
#	enterprise/frontend/src/metabase-enterprise/transforms/components/RunButton/RunButton.tsx
#	enterprise/frontend/src/metabase-enterprise/transforms/pages/TransformPage/RunSection/RunSection.tsx

* Add more generic RunInfo

* Remove unused LogOutput

* Set up python runner in CI (#63566)

* Check out with submodules in CI

* Include python-runner in docker compose for tests

* Set up python runner in CI

* Fix import

* Update python-runner
# Conflicts:
#	python-runner

* Fix font sizes

* Fix table layout

* Revert "Remove unused LogOutput"

This reverts commit 90c0704344.

* Add LogOutput back to runsection

* Remove duplicate schema field

* Use css instead of styled components

* Fix LogOutput styling

* Add transforms/python feature

* Do not allow picking unsupported databases

* Use slugify from metabase/lib/formatting

* Add type for transform alias map

* Fix some type imports

* Refactor PythonDataPicker

# Conflicts:
#	enterprise/frontend/src/metabase-enterprise/transforms/components/PythonTransformEditor/PythonDataPicker/PythonDataPicker.tsx

* Further refactors

* Use data selector for database picker

* Use data picker to pick tables

* Remove unused var

* Improve tests for python transform

* Fix duplicate imports

* Use DatabaseId in python transform

* Remove source/draft ambiguity in types

* Move library types to metabase-types/api

* Remove api transforms

* Remove vibe-comment

* Remove unused component

* Validate source more

* Move TableInput to separate file

* Remove TableOption type

* Simplify props

* Move AliasInput to separate file

* Remove unused props

* Add border to empty results

* Fix import

* Remove extension

* Move draft back to new python transform page

* Fix new python transform page nesting

* Simpify new transform page structure

* Add analytics to history revision and data reference (#63587)

* Transform run cancellation (#62387)

* Add cancellation to transform api

* Use effect to set polling state

* Add cancellation button to run button

* Set up cancellation on transform page

* Use confirmation modal to cancel transform

* Add run cancel button to run list

* Make api endpoint take transform id instead of run id.

* Fix cancelation api

* Add canceled state to TransformRunStatus

* Add canceled state to transform page

* Add polling to RunListPage

* Remove comment in code

* Set status to canceling when you click cancel

* Add canceling status

* Poll when the transform is canceling

* Add copy for runs that are being canceled

* Manually track fetching status for running and canceling

* Handle canceling status in utils

* Avoid wrapping cancel button in run list

* Add test for canceling run on transform page

* Add e2e for canceling test from runs page

* Fix prop type

* Change copy to Canceling

* Add custom color to canceled state

* Remove mock code

* Increase cancelation tiemout

* Fix copy in text

* Fix snowplow event

* Remove void specifier and close modal in handler directyle

* Add optimistic update for run cancelation

* Avoid manually tracking cancelation status

* Avoid useEffect when changing isPolling

* Add in missing helper

* Remove another useEffect

* Add placeholder run when starting

---------

Co-authored-by: Eric Normand <ericwnormand@gmail.com>
Co-authored-by: Alexander Polyankin <alexander.polyankin@metabase.com>

* Fix command z not working in connection string input (#63689)

- Stop preventing default event handling onPaste.
- Improve Cypress paste emulation to be compatible with React way of handling paste events.

* Transforms prepare for python (#63698)

* pull out transform run utils to prepare for python transforms

* fix: check running-run on transform-id, not run-id

* chore: put on a new line

* Fix #63629: Filter on cards causes an unnecessary horizontal scroll bar for public/static embedding (#63650)

* Closes EMB-50 tabs dimmed out on iOS (#63690)

* S3 transport layer for python-runner (#63697)

* Add s3 dependencies (#63706)

* port prometheus/instrumentation (#63631)

* port prometheus metrics

* port instrumentation

* instrument existing transform paths

* wider buckets

* remove nil handling

* warn on nil bytes/rows

* add stage-type mapping

* typo

* Implement data picker according to designs

* Further adjust to design file

* Fix some e2e tests

* Clone python runner when running CI

* Avoid starting the container in e2e tests twice

* Hide python runner admin route when user does not have the feature for it

* Remove unused variables

* Move Python runner amdin page to transforms plugin

* Do not show Python library link when the user does not have python transforms support

* Hide Python transforms features when the user does not have transforms-python token

* Use useHasTokenFeature hook where possible

* Add transforms-python feature

* Fix e2e tests

* Do not include python-runner in test docker-compose yet

* Tag tests for python transforms with @transforms-python

* Add helper to update Python library

* Add check for python output

* Fix Revert on python library when it does not exist

* Fix e2e test helper

* Add python runner settings in CI

* WIP

* Translate pandas definitions

* Add AnsiLogs component

* Use AnsiLogs in Logs components

* Use AnsiLogs in LogOutput component

* Remove token feature gate in enterprise folder

* Return alias instead of throwing

* Check type in isPythonTransform assertion

* Use isResourceNotFoundError

* Make transforms-python it's own plugin

* /s/localhost/localstack

* Add test for editing Python transform

* Verify that running the transform with the library works

* Add missing transforms-python feature to mocks

* Simplify source layout

* Change setting type of python runner token

* Fix tests

* Use ConcreteTableIds in python transforms only

* Deduplicate codemirror helpers

* Ignore errors in non-parseable JSON lines

* Use useLocation hook to enable debugger

* Use useErrorMessage helper

* Move SourceSection to transforms-python plugin

* Fix codemirror helpers

* Remove undefined color

* Fix types

* Fix codemirror helpers more

* Move transform ordering tests to the python module (#63827)

* Add transform ordering tests to the python module

- Consistent with api tests for python transforms being in the python
module
- In practice transforms module 'knows' about python, so this is
organizational only
- Copied test helpers for now, not sure if functions strong enough to be
shared

* Check :transforms/python

* Proj python/table name len (#63842)

* feat: ensure temp-table-name respects max length

* add unit test

* add limit for missing drivers

* depend on it

* fix: use db instead of db-id

* Proj ptyhon/table swap (#63878)

* add rename feature, rename-table! multimethod

* add table swap with atomic or rename or fallback

* changelog

* drop requirement

* ensure we're testing replace flow

* wait for completion, table already exists

* wip

* add rename-table-test

* fix for snowflake

* Extract sourceDatabaseId helper

* Fix e2e helpers

* Fix error in table picker

* Add missing test-id

* Fix transform tests

* Validate python source

* Fix issues after merge

* Fix tag test

* Fix other tag test

---------

Co-authored-by: Nicola Mometto <nicola.mometto@metabase.com>
Co-authored-by: Ngoc Khuat <qn.khuat@gmail.com>
Co-authored-by: Nicolo-Maria <nicolo.mezzopera@metabase.com>
Co-authored-by: Dan Stone <wotbrew@gmail.com>
Co-authored-by: Chris Truter <chris@metabase.com>
Co-authored-by: Nemanja Glumac <31325167+nemanjaglumac@users.noreply.github.com>
Co-authored-by: Eric Normand <ericwnormand@gmail.com>
Co-authored-by: Alexander Polyankin <alexander.polyankin@metabase.com>
Co-authored-by: Jakub Chodorowicz <jakub.chodorowicz@metabase.com>
Co-authored-by: Brad Anderson <brad@metabase.com>
Co-authored-by: Sébastien <sebastien@metabase.com>
Co-authored-by: Chris Truter <crisptrutski@users.noreply.github.com>

* Proj python fix tests (#63970)

* add premium feature

* fix tests that didn't run previously

* exclude from vertica

* remove internal id from mongo table-rows

* fix: require transforms/python db feature for python transforms

* missing in stats

* fix for mongo

* whitespaces to appease the linter

* more more whitespace for the linter gods

* disambiguate for the e2e tests

* Some small type fixes for Python transforms  (#64021)

* Remove duplicate helper

* Add updateEnterpriseSetting helper for type-correctness

* Add missing python runner settings

* Use correct setting name

---------

Co-authored-by: Ngoc Khuat <qn.khuat@gmail.com>
Co-authored-by: Chris Truter <crisptrutski@users.noreply.github.com>
Co-authored-by: Dan Stone <wotbrew@gmail.com>
Co-authored-by: Romeo Van Snick <romeo@romeovansnick.be>
Co-authored-by: Nicolo-Maria <nicolo.mezzopera@metabase.com>
Co-authored-by: Chris Truter <chris@metabase.com>
Co-authored-by: Nemanja Glumac <31325167+nemanjaglumac@users.noreply.github.com>
Co-authored-by: Eric Normand <ericwnormand@gmail.com>
Co-authored-by: Alexander Polyankin <alexander.polyankin@metabase.com>
Co-authored-by: Jakub Chodorowicz <jakub.chodorowicz@metabase.com>
Co-authored-by: Brad Anderson <brad@metabase.com>
Co-authored-by: Sébastien <sebastien@metabase.com>
2025-09-25 13:03:38 +00:00
Romeo Van Snick
eeecd9a10a Fix native preview button in transforms (#63865)
* Allow passing language as a plugin to CodeEditor

* Pull out NativeQueryPreview

* Render NativeQueryPreview in the native transform editor

* Relax prop types

* Add e2e test for query preview in transforms

* Fix e2e tests

* Pass query instead of question

* Use CopyButton instead of bespoke component

* Fix unit test
2025-09-25 20:42:46 +10:00
Roman Abdulmanov
685424df74 fixed colors (#64029) 2025-09-25 10:06:54 +00:00
Phoomparin Mano
c4af9c415b Double scrollbars are showing up on metabase-browser when always show scrollbar is set (#63971) 2025-09-25 16:07:56 +07:00
Mahatthana (Kelvin) Nomsawadi
ca66414190 Reset colors when passing undefined to theme (#63957)
* Reset colors when passing undefined to theme

* Add tests
2025-09-25 10:07:43 +01:00
Tyler Plude
855e846d0a Add result ID to search click event tracking (#64009)
* Add result ID to search click event tracking

* include entity_id in SearchEventSchema type
2025-09-24 22:13:03 -07:00
Alexander Polyankin
270086315f Add last run status info to jobs (#63994) 2025-09-24 20:51:02 -04:00
Alexander Polyankin
16ea0dc141 Rename DatePicker intervals to "past" and "future" (#63993) 2025-09-24 20:49:52 -04:00
Timothy S. Dean
94b9737f0b Handle trailing spaces appropriately in snippet template tags (#63582)
Attempting to use a snippet template-tag with a trailing space in the snippet name (e.g., `{{snippet: foobar }}`) caused an exception to be thrown when running the native query (missing required parameter).

The regex used for identifying snippet tags will now strip trailing spaces appropriately.
2025-09-24 23:05:27 +00:00
Nathan Voxland
4448933543 Add MB_WEBPACK_PORT env variable config (#63355) 2025-09-24 17:15:19 -05:00
Alex Yarosh
a9e0afd420 interactive embedding notes (#64007) 2025-09-24 17:18:31 -04:00
Cam Saul
d018b4a1bc Use Lib for query->source-card; fix busted tests and busted X-Ray code (#63921)
* Misc Lib improvements

* Restore deleted function... for now

* Test fix 🔧

* Mark more stuff in Legacy MBQL utils as deprecated

* Use Lib for query->source-card

* Update modules config

* Update tests 🔧

* Fix the X-Rays

* Druid test fix 🔧

* Appease Kondo
2025-09-24 13:47:57 -07:00
lbrdnk
92011484de Disable fks sync on CH (#63976)
* Disable fks sync

* Describe implementation with warning

* Kondo
2025-09-24 22:34:03 +02:00
Alex Yarosh
c10fd5cd5b docs: db routing with static embedding (#63999)
* docs: db routing with static embedding

Clarified limitations of database routing in Metabase.

* Update docs/permissions/database-routing.md

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-09-24 20:22:35 +00:00
Oleksandr Yakushev
564556d706 [perf] Suggest drop-in replacements for clojure.core functions from metabase.util.performance (#62971)
* [perf] Suggest drop-in replacements for clojure.core functions from metabase.util.performance

* Fix walk for nil

* [perf] Make metabase.util.performance/reduce compatible with non-iterables (like strings)
2025-09-24 20:08:22 +00:00
Riley Thompson
5e55ecd75c Add regression test for clickhouse jdbc driver (#63906)
* add regression test for clickhouse

* revert to 0.8.4

* fix

* fix tests
2025-09-24 13:50:03 -06:00
Ngoc Khuat
0a33f82baf Fix static viz ignore viz-settings order (#63980) 2025-09-24 19:28:38 +00:00
github-automation-metabase
7ecdc2f757 Update generated docs (master) (#63947)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-24 13:34:01 -04:00
Phoomparin Mano
0bf1ac867f Replace interactive embedding card in embed modal with embed flow (#63942) 2025-09-25 00:14:36 +07:00
Cam Saul
cbdc23a7bf Fix sorting on aggregate columns (#63940)
* Fix sorting on aggregate columns

* cljfmt
2025-09-24 10:55:23 -06:00
Edward Paget
c59e9de090 fix: check email in update before validing for sso (#63915)
Changes to any user attribute for sso users were failing preventing them
from being to set their user locale. This was due to us not checking if
`email` is present in the body of the update request before failing a
`check-403` call if the user has an sso source.
2025-09-24 11:10:58 -05:00
Uladzimir Havenchyk
9668ebe98c chore: upgrade typescript to 5.9 (#61494) 2025-09-24 18:45:28 +03:00
Sébastien
3c2d46151b Closes EMB-851 static embed pin map (#63897)
* Closes EMB-851 static embed pin map

* .

* .

* Update frontend/src/metabase/visualizations/lib/map.ts

Co-authored-by: Phoomparin Mano <poom@metabase.com>

* Update frontend/src/metabase/visualizations/lib/map.ts

Co-authored-by: Phoomparin Mano <poom@metabase.com>

---------

Co-authored-by: Phoomparin Mano <poom@metabase.com>
2025-09-24 17:42:40 +02:00
Alexander Polyankin
1cacd1f510 Constraint available relative directions in the DatePicker for transforms (#63893) 2025-09-24 11:36:39 -04:00
Ryan Laurie
a8074ca04b Thinner + Darker Borders (#63675)
* fix button borders

* update-border-color

* dont mix the colors

* update loki

* update again

* Update Loki Snapshots

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
2025-09-24 15:31:25 +00:00
Oleksandr Solovyov
28014961c3 add index on report_card.type (#63493) 2025-09-24 15:19:51 +00:00
Tyler Plude
ec5b20af0c [METABOT] Fix bug in Metabot search deduplication (#63943)
* [METABOT] Fix bug in Metabot search deduplication

* rm debug defs
2025-09-24 08:01:06 -07:00
dpsutton
ab68e21cf7 revert nett-common and netty-buffer bumps (#63967)
rather than 4.2.4.Final, they will now be "io.netty/netty-buffer
4.1.118.Final" which puts it the same as that in 3.5.0.

The issue is that both the bigquery-cloud-sdk driver and athena driver
get put onto the classpath and it depends on which order the drivers are
added for resolving which version of this netty buffer dep you get.

```clojure
user=> (metabase.classloader.core/the-classloader)
user=> (enumeration-seq (.. (Thread/currentThread) getContextClassLoader (getResources "io/netty/buffer/ByteBufAllocator.class")))
(#object[java.net.URL 0x3bb34fe "jar:file:/private/tmp/fixed-athena/plugins/bigquery-cloud-sdk.metabase-driver.jar!/io/netty/buffer/ByteBufAllocator.class"]
 #object[java.net.URL 0x4ac1867d "jar:file:/private/tmp/fixed-athena/plugins/athena.metabase-driver.jar!/io/netty/buffer/ByteBufAllocator.class"])
```

One annoying bit to keep track of this is that bigquery uses a regular
jar that specifies its dependencies, so you can you regular tooling:

```
clj -X:deps tree :aliases '[:drivers]' > /tmp/deps.with.netty.downgrade
```

And then see those deps:

```
  . metabase/bigquery-cloud-sdk /Users/dan/projects/work/metabase/modules/drivers/bigquery-cloud-sdk
    . com.google.cloud/google-cloud-bigquery 2.54.2
      . com.google.cloud/google-cloud-core 2.60.0
      . ... [lots omitted]
    . org.apache.arrow/arrow-memory-netty 17.0.0
      X org.apache.arrow/arrow-memory-core 17.0.0 :older-version
      . org.apache.arrow/arrow-memory-netty-buffer-patch 17.0.0
        X org.apache.arrow/arrow-memory-core 17.0.0 :older-version
        . io.netty/netty-buffer 4.1.110.Final
```

This version was created without any pinning of netty. Checking the
athena version is a bit more tricky. We use a fat jar. But you can
download the source from amazon as a jar with deps:

```
athena-jdbc-3.5.0-lean-jar-and-separate-dependencies-jars
```

https://docs.aws.amazon.com/athena/latest/ug/jdbc-v3-driver-previous-versions.html

This zip includes `runtime-dependencies` which includes
`netty-buffer-4.1.jar`

The pom inside of this jar specifies

```xml
  <parent>
    <groupId>io.netty</groupId>
    <artifactId>netty-parent</artifactId>
    <version>4.1.118.Final</version>
  </parent>
```

And `META-INF/maven/io.netty/netty-buffer/pom.properties` specifies

```
artifactId=netty-buffer
groupId=io.netty
version=4.1.118.Final
```

So i am confident now that with the pinning in bigquery and this version
here that regardless of class resolution from
"jar:file:/private/tmp/fixed-athena/plugins/bigquery-cloud-sdk.metabase-driver.jar!/io/netty/buffer/ByteBufAllocator.class"
or
"jar:file:/private/tmp/fixed-athena/plugins/athena.metabase-driver.jar!/io/netty/buffer/ByteBufAllocator.class"
you will get the same class and athena shall work again.
2025-09-24 09:48:38 -05:00
dpsutton
821c0f624b ensure type/* for base-type if otherwise not known (#63930)
* ensure type/* for base-type if otherwise not known

Using the follow query that returns pg arrays:

```sql
SELECT *
FROM (
  VALUES
    (1, ARRAY['https://example.com', 'https://example.org']),
    (2, ARRAY['https://test.com']),
    (3, ARRAY['https://foo.com', 'https://bar.com', 'https://baz.com'])
) AS adhoc_table (id, urls);
```

In 55 this returned a nil base-type

```clojure
user=> (metabase.query-processor.metadata/legacy-result-metadata
         {:database 2
          :type :native,
          :native {:template-tags {},
                   :query "SELECT *\nFROM (\n  VALUES\n    (1, ARRAY['https://example.com', 'https://example.org']),\n    (2, ARRAY['https://test.com']),\n    (3, ARRAY['https://foo.com', 'https://bar.com', 'https://baz.com'])\n) AS adhoc_table (id, urls);"}}
         1)
[{:display_name "id",
  :source :native,
  :field_ref [:field "id" {:base-type :type/Integer}],
  :ident "native[]__id",
  :name "id",
  :database_type "int4",
  :base_type :type/Integer,
  :semantic_type :type/PK}
 {:display_name "urls",
  :source :native,
  :field_ref [:field "urls" {:base-type nil}],
  :ident "native[]__urls",
  :name "urls",
  :database_type "_text",
  :base_type nil}]
```

In master, this just fails. If you remove the type checking in places,
it will eventually return similar.

This base-type is computed in sql-jdbc/metadata

```clojure
(mu/defn query-result-metadata :- [:sequential driver-api/schema.metadata.column]
  "Default implementation of [[metabase.driver/query-result-metadata]] for JDBC-based drivers. Gets metadata without
  actually running a query."
  ([driver :- :keyword
    query  :- :map]
   (driver-api/with-qp-setup [query query]
     (let [database               (driver-api/database (driver-api/metadata-provider))
           {:keys [query params]} (driver-api/compile query)]
       (query-result-metadata driver database query params))))

  ([driver      :- :keyword
    database    :- driver-api/schema.metadata.database
    ^String sql :- :string
    params      :- [:maybe [:sequential :any]]]
   (sql-jdbc.execute/do-with-connection-with-options
    driver
    database
    nil
    (fn [^java.sql.Connection conn]
      (with-open [stmt (sql-jdbc.execute/prepared-statement driver conn sql params)]
        (let [rsmeta (.getMetaData stmt)]
          (mapv (fn [i]
                  (let [database-type (.getColumnTypeName rsmeta i)]
                    {:lib/type      :metadata/column
                     :name          (.getColumnLabel rsmeta i)
                     :database-type database-type
                     :base-type     (or (sql-jdbc.sync.interface/database-type->base-type driver (keyword database-type))
                                        :type/*)}))
                (range 1 (inc (.getColumnCount rsmeta))))))))))
```

Before this change, there was no `or` and
`sql-jdbc.sync.interface/database-type->base-type` would just return
nil.

```clojure
user=> (metabase.driver.sql-jdbc.sync/database-type->base-type :postgres (keyword "_text"))
nil
```

Unfortunately this is a multimethod so we can't easily update it in one
spot to fall back to type/*. Each implementation must take care to do
this. A few do (clickhouse does) but a few dont (snowflake does not). So
we update this call site to ensure we have something from the
multimethod or add our own type/*

Why did this start happening now?
> I think it's because I added :metadata/model-metadata to :metabase.lib.schema.info/info at some point

Query info stashes the model metadata which is
```clojure
[:metadata/model-metadata {:optional true} [:maybe [:sequential ::lib.schema.metadata/lib-or-legacy-column]]]
```

We had been throwing errors asynchronously when trying to save metadata,
but now we have on-thread type mismatch for model metadata, which is
what is in the ticket.

* add test to ensure we can handle existing base_type nil's

this got annoying because legacy metadata from the app-db comes from a
different location. I was adding a card schema migration but this is
better here.

The previous commit makes sure we don't put out more bad data, but this
commit here ensures that we can update the card.
2025-09-24 09:37:11 -05:00
Vamsi Peri
7423aaf572 Remove sessions from sync metadata registry (#63949)
Remove sessions table from sync metadata registry
2025-09-24 14:34:51 +00:00
Phoomparin Mano
03f68f0a2c Add embed flow to the command palette (#63944) 2025-09-24 21:22:55 +07:00
Romeo Van Snick
e8f125c19b Add error info to transform job page (#63623)
* Move cron info up into cron section

* Move schedule explanation logic to utils

* Allow ReactNode as explain message

* Render explain message in cron component

* Add status to transform job page

* Add e2e tests for job error message

* Add assertion to lookup

* Add extract shared logic for run status

* Add missing test-ids

* Select correct section
2025-09-25 00:20:23 +10:00
Romeo Van Snick
21c5271879 Fix failing transform tags test (#63964)
* Do not expect tag to be in popover when it's already selected

* Invalidate specific tags when deleting a tag

* Fix other tag test
2025-09-25 00:19:57 +10:00
Jeff Bruemmer
45d701fd6b docs - updates on documents, comments, and Metabot (#63922) 2025-09-24 14:06:31 +00:00
Uladzimir Havenchyk
7c1152e9d0 chore: fix type usage of parameters in sdk (#63918)
* chore: fix type usage for parameters in sdk

* make types plane
2025-09-24 16:21:54 +03:00
Kamil Mielnik
ab20852102 DSN-70 Custom maps section in Admin should have a nicer empty state for its table (#63874)
* Add empty state to custom maps component

* Add unit test
2025-09-24 11:04:24 +00:00
Phoomparin Mano
137bc61a42 Show toggle for enabling saves for question embeds in embed flow (#63908) 2025-09-24 16:35:02 +07:00
Kamil Mielnik
f567aeece1 Do not render tabs in ParameterSidebar if there's only 1 tab (#63815) 2025-09-24 16:21:16 +07:00
Mahatthana (Kelvin) Nomsawadi
e60e38682b Don't send new user login for SDK or Embedded Analytics JS (#63883)
* Don't send new user login for SDK or Embedded Analytics JS

* Update tests

* Stop using hard-coded string to detect modular embedding headers

* Conform to spacing rule
2025-09-24 08:59:23 +01:00
Timofey Kachalov
84efc79be4 refactor(sdk-bundle): Adjust SDK compatibility warning messages and banners (#63919) 2025-09-24 11:58:32 +04:00
Kamil Mielnik
8de8d13eb6 Update copy (#63823) 2025-09-24 14:55:11 +07:00
Kamil Mielnik
a52d58a3e2 Make info panel headings consistent (color, line-height, margin-bottom) (#63882) 2025-09-24 14:54:27 +07:00
Kamil Mielnik
f34cb3d5c3 Use Tab component in TagEditorSidebar (#63829) 2025-09-24 14:52:49 +07:00
Kamil Mielnik
d8571ccabe Update background color of Field items in TableSection (#63831) 2025-09-24 14:52:15 +07:00
Kamil Mielnik
19f279610b Remove forceActiveStyle prop from ActionButton (#63869) 2025-09-24 14:51:51 +07:00
Riley Thompson
5647233576 Fix starbust query cancellation with isClosed proxy implementations (#63857)
* add isClosed impls to proxys

* use mt/id in test

* test all drivers

* check if statements are supported, refactor statement-supported? multimethod to drive feature

* add namespace to statements feature
2025-09-24 05:10:13 +00:00
Riley Thompson
14481bcf2f Clean up transforms test schemas (#63406)
* clean up transforms test schemas

* use destroy-dataset! for bigquery
2025-09-24 05:08:55 +00:00
Mahatthana (Kelvin) Nomsawadi
bbccbb4842 fix(embed-js): Only report analytics when not in the preview (#63812)
* Only report analytics when not in the preview

This would avoid confusing preview usage with the actual usage

* Ensure analytics would be report even if iframe isn't ready

* Add E2E test

* Make the test pass

* Stop relying on redux store to fetch `site-url`

* Clarify test with comment

* Add tests

* Fix linter

I was naming a file wrong, so it doesn't match unit test spec. This rule
apparently doesn't take tests into account, which is great.
2025-09-24 06:06:45 +01:00
Cam Saul
4b99060f46 Do not recurse forever when resolving bad :field refs for expressions (#63926) 2025-09-23 17:57:27 -07:00
Cam Saul
3903af487f Misc Lib improvements to support wider Lib usage in the backend (#63911)
* Misc Lib improvements

* Restore deleted function... for now

* Test fix 🔧
2025-09-24 00:14:30 +00:00
Phoomparin Mano
0fb061b839 Minor visual improvements for embedding hub (#63813) 2025-09-24 06:14:51 +07:00
Tyler Plude
ab9e7bbcb8 [BOT-292] Metabot with Search 2.0 (#62067)
* Add search endpoint for Metabot and adjusted metadata

* More tests and better split out of logic into separate files

* dedupe search terms and description if they happen to be the same

* fix bad merge conflict

* Answer blending sql querying via search tables (#62415)

* Only put tables used in SQL into context
* Change format of injected database content by reusing existing models
* Create separate function for new schema enchancement
Co-authored-by: Sloan Sparger <sloansparger@gmail.com>

* Add table reference for implicitly joinable fields in context injection (#62753)

* Update Metabot profile IDs (#62864)

* [Answer blending] Updates to the metabot admin configs (#62551)

* remove ability to configure the selected collection for default metabot

* add verified toggle

* add migrations for metabot collection configuration changes

* add metabot PUT endpoint, rip out metabot entities endpoints and usages, convert FE over to new FE, fix tests

* remove metabot_entity table, model, usage and refactor code to use updated metabot and metabot_prompts schemas

* enforce verification and regenerate prompts on verification + collection id change

* fix bad references

* fix bad regexp for fetch-mock collections by id endpoints breaking unit tests

* fix kondo

* fix + increase tests for enterprise/backend/test/metabase_enterprise/metabot_v3/tools/api_test.clj

* fix migration boolean default value syntax

* maybe fix be tests

* fix some tests

* enforce verified filter on the search endpoint

* factor in verified check into find-metric

* hide verification setting behind token feature check, fix migration lint, do not migrate collection id for default metabot, fix kondo errors

* fix core tests

* fix kondo

* fix most of the failing serialization tests

* fix migration lints

* fix one test file

* maybe fix migration failures

* move test resource file

* prevent default metabot from getting a collection id configured

* yolo

* add cascade delete to entity drop table migration

* increase unit tests for verification config UI

* remove extra add column

* fix migration... i think for real this time

* for real for real fix migrations

* no really

* tests fixes and add preventing verification toggle if the instance does not have the content_verification feature

* fix failing feature tests in ci

* fix one more

* fix cljfmt issue

---------

Co-authored-by: Tyler Plude <tsplude@gmail.com>

* [Metabot] Quick slash command + dynamic profile ui (#62909)

* quick slash command + dyanmic profile ui

* add back code i did not mean to remove

* fix failing test

* Revert "fix failing test"

This reverts commit b1c7e9efb9.

* [BOT-284] BE for notebook query tool table support (#62710)

* init

* moved query-table endpoint to query-datasource; add support for both model and table ids

* unit test fixes

* use existing card-query and table-query utils

* adding unit tests

* [Answer blending] Respect collection id in search (#63150)

* remove find metric tool

* adjustments to search endpoint

* add tests

* fix failing test in ci

* add way to override the metabot id

* add way to override metabot request id

* fix whitespace lint

* missing paren...

* fix failing test

* New BE `/search` endpoint for ai-service `SearchTool` (#63154)

* new metabot search tool BE endpoint

* remove debug prints

* parallel searches; incomplete effort to return more fields for results

* Simplify result transforming & response schemas

* unit tests

* kondo fixes; pr feedback

* fallback search model list

* remove references to MetabotEntity model which got re-added incorrectly in rebase

* Make internal metabot use verified content by default (#63529)

Update linter for usage of task in metabot-v3

Move suggested-prompts to separate namespace

Add collection condition only when current-user-id

Add startup task

migration

Update tests

Verified cards only

Test

Docstrings

Limit number of entities

Review feedback

* [METABOT] Default use_verified_content to false; tweak prompts (#63843)

* default use_verified_content false; limit amount of prompts

* reworked unit test to not depend on ai-service or appdb contents

* PR feedback

* remove mock of get metrics and models in favor of mt/with-empty-h2-app-db

* Small refactors & simplifications to metabot PUT endpoint and suggested
prompts job

* small simplification, use m/distinct-by for deduping tables

* rm deprecated search_data_sources

* Cleanup and prioritize verified content (#63877)

* Remove now redundant content verification guard

* Prioritize verified content

* Redundant merge

* Test

* ensure field IDs in user_is_viewing context are snake_cased

* Use proper source column alias as name for the model / table fields (#63826)

* Use proper source column alias as name for the model / table fields

* Add name as fallback

* test fix

* switch to using :lib/desired-column-alias, revert test fix

---------

Co-authored-by: Tyler Plude <tsplude@gmail.com>
Co-authored-by: Noah Moss <noahbmoss@gmail.com>

* Fix some tests: consistent use of snake_case, and a :lib/source-column-alias fallback for model field :name

* fix more field_id snake_case issues

* fix another snake case issue - revert result_columns back to result-columns

---------

Co-authored-by: Thomas Schmidt <thomas.heinz.schmidt@gmail.com>
Co-authored-by: Sloan Sparger <sloansparger@gmail.com>
Co-authored-by: Thomas Schmidt <thomas@metabase.com>
Co-authored-by: Sloan Sparger <sloansparger@users.noreply.github.com>
Co-authored-by: Noah Moss <noahbmoss@gmail.com>
Co-authored-by: lbrdnk <lbrdnk@users.noreply.github.com>
2025-09-23 14:42:29 -07:00
Alex Yarosh
a137631b7f docs: time grouping stages (#63934)
* docs: time grouping stages

* Update docs/dashboards/filters.md
2025-09-23 21:19:43 +00:00
Edward Paget
e4a04ebc05 fix: jetty stats handler tests flake (#63912)
* fix: jetty stats handler tests flake

These tests could hang indefinitely on the `(.join server)` statement
because the core.async/go block handling async requests was incorrectly
doing a blocking take `<!!`. This also updates our :dev alias to enable
core.async to print warnings when using blocking operations in `go` blocks.

* fixup! oncomplete dispatch in go block

* fixup! using alts!! in go block
2025-09-23 16:17:41 -05:00
Stas Gavrylov
432287f763 update comments email template (#63626)
* WRK-893: Update API to store comment html content

* WRK-891: Add HTML content sending in comments. Add proper SmartLink serialization to HTML.

* WRK-891: Update comment email template to display comment content

* WRK-891: Fixes for comment email template. Add space insertion after smartLink

* trigger comment notification by id

* put old api behavior back and cleanup comment notification context

* whitespace

* fix tests

* Fix changeset author

* WRK-891: Fix smart links serialization. Add parent comment display in email

* Add style payload for comments email template

* fix types

* 🙄

* test email changes

* test email again

* make email formatting looking perfect

* cleanup

* require html content to be provided when posting a comment

* fix e2e test

* fix another e2e test

* pass 0 as tiptap placeholder when no label available

---------

Co-authored-by: Oleksandr Solovyov <o@solovyov.net>
Co-authored-by: Uladzimir Havenchyk <uladzimir@metabase.com>
Co-authored-by: Uladzimir Havenchyk <125459446+uladzimirdev@users.noreply.github.com>
2025-09-23 21:16:18 +00:00
Oreon Lothamer
d8be52f651 use vertica-ce from ecr (#63609)
* use vertica-ce from ecr

* use CI_IAM_ROLE for vertica ECR

* Adjust test

---------

Co-authored-by: lbrdnk <lbrdnk@users.noreply.github.com>
2025-09-23 11:09:32 -10:00
Nathan Voxland
6516199e3f Improve FieldValues inactive check (#63847) 2025-09-23 21:04:09 +00:00
Thomas Schmidt
1bba35237e Auto set template tags (#63691) 2025-09-23 19:19:34 +00:00
Alex Yarosh
4337a1baf3 docs: scim <> saml interaction (#63925) 2025-09-23 15:07:38 -04:00
Brad Anderson
23cb8b11c0 Fix: #50011 Hides "Here are some explorations of" when there are no explorations (#63839) 2025-09-23 14:07:33 -04:00
Cam Saul
c863f41c2a Improved mu/defn and mu/fn macros: only evaluate schemas once (#63737)
* Mega Malli fn improvements

* Remove commented out code
2025-09-23 10:44:03 -07:00
Jakub Chodorowicz
34e7a0e9f1 Adjust DB form page width and form fields spacing (#63818)
* Adjust DB form page width and form fields spacing

* Extract layout field settings to one file

* Use lg spacing between form fields

* Conditionally add labelProps property

* Fix typo

* Refactor deprecated default export

* Simplify responsive max width

* Simplify DB page responsive styles

* Add card background to add db form
2025-09-23 18:25:56 +02:00
dpsutton
454a05e3c6 Downgrade athena (#63894)
having issues with classpath. I _think_ that athena is finding the
bigquery provided version of a netty class and that is failing. but it's
a bit difficult to follow.

downgrading now until we can take time to understand and sort it.
2025-09-23 10:53:34 -05:00
Ryan Laurie
1ed050b03d Make Loki work more consistently (#63859)
* fix loki?

* update loki scripts

* use ci

* remove double build

* update scripts

* update documentation
2025-09-23 15:16:54 +00:00
Robert Kosara
9041dbb329 docs: Remove the +New option for creating new models (#63861)
* Remove the +New option for creating new models

* Bring back the from-scratch approach

Based on Alex's requested change, but also realized that you can use the command palette

* Move note about models getting pinned back into the new model section

* Format UI terms using bold instead of italics
2025-09-23 08:08:29 -07:00
lbrdnk
63cc5c3137 Semantic search token usage tracking (#63591)
* Pass type of embedding request

* Initial migration

* Add remaining opts args

* Add SemanticSearchTokenTracking module

* Connect token tracking to ai-service impl

* Add test for token tracking writes.

* Remove prompt_tokens including migration

* Add usage trimmer job

* Trimmer test

* Activate trimmer job

* test

* Record tokens for openai

* Update test

* Use total-tokens

* Comment

* linter

* Add index

* Exclude from copy
2025-09-23 16:50:55 +02:00
Phoomparin Mano
7551f766dd Hide non-customer-facing embedding hub settings (#63838) 2025-09-23 21:45:31 +07:00
John Swanson
f4b675b3f2 Serialize transforms (#63658)
Serialization for transforms
2025-09-23 07:34:17 -07:00
github-automation-metabase
123e0cef51 Update generated docs (master) (#63864)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-23 09:17:55 -04:00
Fraser
eed3bb1e19 Make timing steps continue-on-error (#63881) 2025-09-23 14:11:01 +02:00
Cam Saul
dad9b5c709 Don't spend minutes trying to generate descriptions for massive schemas (#63739)
* Don't spend minutes trying to generate descriptions for massive schemas

* Cljs test fix 🔧
2025-09-23 14:38:07 +03:00
Nicolò Pretto
166e20c944 fix typo in WhatsNewNotification: 'dimiss' -> 'dismiss' 2025-09-23 09:51:15 +00:00
Jakub Chodorowicz
e4d0318213 Migrate last direct usage of settings store url, to useStoreUrl (#63771) 2025-09-23 08:56:04 +02:00
Alexander Polyankin
3913c6e850 Fix pills input padding (#63840) 2025-09-23 02:03:55 +00:00
Fraser
f6384ac6f3 Automatically update e2e timings (#61950) 2025-09-23 10:19:09 +12:00
Maz Ameli
bd6d5e527b Replace usage of info_filled icon with info icon (#63734)
* replace usage of info_filled icon with info icon

* Update Loki Snapshots

* drop unused info_filled icon

* Update Loki Snapshots

* update stories

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
Co-authored-by: Aleksandr Lesnenko <alxnddr@gmail.com>
2025-09-22 21:10:42 +00:00
Maz Ameli
4dac7d9dcf remove dropshadow from glossary container (#63730)
Co-authored-by: Stas Gavrylov <stas@metabase.com>
2025-09-22 21:04:20 +00:00
Nemanja Glumac
5bda80e53f Add simple event tracking for drill-thrus and other "click actions" (#63792) 2025-09-22 22:56:04 +02:00
Sébastien
07a34dc556 Removed loki flaky test (#63824) 2025-09-22 13:15:17 -07:00
Alex Yarosh
3a4e2a311c docs: send only attachements (#63846)
* docs: send only attachements

* Apply suggestions from code review

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-09-22 20:04:43 +00:00
Jeff Bruemmer
f0427f0a34 docs - add glossary and image (#63844) 2025-09-22 16:00:04 -04:00
Jeff Bruemmer
ebcdcf1ce9 Remove .json format from subscription options (#63849) 2025-09-22 15:59:09 -04:00
Nick Fitzpatrick
20afc08468 Hiros document desires (#63035)
* starting document copying

* Document copy from collection page

* remove card node
2025-09-22 16:53:00 -03:00
Alexander Polyankin
c60b139cf4 Fix removing all tags from a transform job (#63837) 2025-09-22 14:24:19 -04:00
Alexander Polyankin
cb7e5a0437 Transforms schedule component (#63767) 2025-09-22 18:04:33 +00:00
Anderson
1e4e4bcae5 Update user invitation email design (#63682)
* Update user invitation email design

* Add alt attr to img element

* Update system event clj test
2025-09-22 14:32:20 -03:00
Phoomparin Mano
f65c0fb194 Add completion checks for creating models in embedding hub (#63661)
* update test and implementation

* update models query to make more sense

* flake fix: try adding timeouts to Done

* remove cy.wait from tests

* wait for model creation

* modify create model tests
2025-09-22 16:33:12 +00:00
Nathan Voxland
fa187a027d Fix crash during reindexing of analytics on upgrade (#63770)
* Don't force reindex on serialization load to be async

* Allow reindex to be controlled when calling load

* Keep load reindex sync for now

* Make reindex async again
2025-09-22 10:30:57 -05:00
Alexander Polyankin
d25a14aec8 Show an error that variables in transforms are not supported (#63759) 2025-09-22 15:30:17 +00:00
Brad Anderson
4a59711053 Fix: #63258 + UXW-570 Fix truncated dashboard notifications (#63726)
* UXW-570 Fix truncated toast messages

* UXW-570 Updates e2e test

* #63258 Fix e2e tests (breaking because toast is wider, blocks previously unobscured elements)
2025-09-22 11:18:46 -04:00
Nemanja Glumac
c33489af35 Add tracking to bookmarks (#63752) 2025-09-22 15:12:24 +00:00
Alexander Polyankin
d6c7ef8e63 Fix MLv2 error with audit v1 (#63772) 2025-09-22 10:27:41 -04:00
Nemanja Glumac
6e7aeb6d71 Add tracking to the metadata changes from admin (#63672) 2025-09-22 16:20:52 +02:00
github-automation-metabase
6db1e7e2ad Update generated docs (master) (#63810)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-22 09:37:11 -04:00
Alexander Polyankin
f901d08b1c Hide cursor in the readonly native editor (#63774) 2025-09-22 13:26:06 +00:00
Alexander Polyankin
5bc7d211ba Remove unsupported buttons from native editor in transforms (#63768) 2025-09-22 09:20:43 -04:00
Alexander Polyankin
d04ffc2925 Change the default editor height for transforms (#63773) 2025-09-22 09:20:27 -04:00
Kamil Mielnik
c471c32f3f Allow to un-resolve deleted comments (#63429) 2025-09-22 10:06:21 +03:00
Romeo Van Snick
d867a09072 Convert MBQL transforms to SQL (#63565)
* Add a controlled version of NotebookNativePreview

* Use ReactNode instead of JSX.Element

* Add a button to toggle native sql

* Add sql preview to transform query editor

* Pull out resizehandle component

* Add e2e test for converting an MBQL transform to a native transform

* Move native query toggle out of header

* Move Native editor sidebar to separate component

* Fix overflow in native sidebar

* Fix copy on button

* Move connected NotebookNativePreview to query_builder

* Remove canConvertToNative prop

* Rename prop

* Move styles to css
2025-09-22 15:42:54 +10:00
github-actions[bot]
090fbc2d5a [chore] Update E2E test timings with recent data (#63327) 2025-09-22 14:27:07 +12:00
Fraser
33fe7b3afe Delete skipped expression popover e2e tests (#63732) 2025-09-22 12:08:46 +12:00
Phoomparin Mano
ea7eeeb15e Update related settings copy and alignment on embedding hub (#63660) 2025-09-20 09:46:30 +07:00
Phoomparin Mano
b693b137f6 Replace the language selection step on the setup flow with the language selector (#63584) 2025-09-20 08:55:34 +07:00
Phoomparin Mano
1a6044bbb3 Use blue shadow on embedding hub card to highlight next step (#63655) 2025-09-20 08:55:24 +07:00
Phoomparin Mano
e5706a4def Adjust the embedding homepage copy and add upsell for OSS (#63646) 2025-09-20 08:55:09 +07:00
Nicolò Maria Mezzopera
0014bbc775 fix(ci): properly account for ci-skip condition in jobs that specify IF condition (#63785) 2025-09-19 22:10:56 +00:00
Alex Yarosh
b96b8fbead docs: fix include in editable tables (#63783) 2025-09-19 17:55:54 -04:00
Phoomparin Mano
7e09b87447 Update embedding hub card copy for embed in your code step (#63656) 2025-09-20 04:46:49 +07:00
Brad Anderson
102025c69c UXW-753 Fix issues with Detail visualization columns getting out of sync (#63769) 2025-09-19 17:12:14 -04:00
Alex Yarosh
80b31c4b1e docs: progress bar (#63779)
* progress bar

* header

* Optimized 3 images, saved 190.8 KB (53.7% smaller)

* link

* Apply suggestions from code review

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

* feedback

* links again?..

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-09-19 16:59:49 -04:00
Alex Yarosh
d4adbb7ef0 docs: snippets (#63761)
* snippets

* Optimized 5 images, saved 209.2 KB (50.7% smaller)

* link

* sql -> native

* Apply suggestions from code review

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

* Update docs/questions/native-editor/snippets.md

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

* rawwwwww

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-09-19 16:50:12 -04:00
Jeff Bruemmer
04192e385d docs - model list view (#63727) 2025-09-19 20:48:25 +00:00
Uladzimir Havenchyk
18b9ae17c7 rework comments sidebar (#63636)
don't use Sidesheet and use sidebar on the same level as Metabot sidebar, so both sidebars can be opened side by side
2025-09-19 19:48:46 +00:00
Alexander Polyankin
b69218fe00 Transforms copy changes (#63760) 2025-09-19 15:03:48 -04:00
Alexander Polyankin
61a8141a44 Remove selected tags (#63714) 2025-09-19 18:40:19 +00:00
Cam Saul
2ed9e3e1d4 Delete dead FE code (#63740)
* Delete dead FE code

* Update enterprise/frontend/src/metabase-enterprise/audit_app/lib/cards/queries.js

---------

Co-authored-by: Uladzimir Havenchyk <125459446+uladzimirdev@users.noreply.github.com>
2025-09-19 10:18:13 -07:00
Abed Habli
a1a9e71867 docs: renaming Debian references (#63763)
* Renaming debian

* redirect to the doc
2025-09-19 17:52:17 +02:00
Edward Paget
0ed177ddb1 fix: remove commented out card pivot test (#63701) 2025-09-19 15:41:59 +00:00
Mahatthana (Kelvin) Nomsawadi
814dd5c800 Fix static embedding dashboard calling GET: /api/dashboard unnecessarily (#63753) 2025-09-19 21:32:19 +07:00
Oleksandr Solovyov
8285e38f9c cleanup v3/v2/ (#63634) 2025-09-19 17:25:58 +03:00
github-automation-metabase
8ad7ee944d Update generated docs (master) (#63736)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-19 09:07:22 -04:00
Phoomparin Mano
975002a6f7 Revert the cloud setup flow's layout to match self-hosted setup flow (#63577) 2025-09-19 18:34:03 +07:00
Phoomparin Mano
3fddbec54e feat(embed-js): better error message when useExistingUserSession fails (#63125) 2025-09-19 18:13:18 +07:00
Sébastien
c3461ab646 Closes EMB-816 misleading text for number of rows (#63561)
* Closes EMB-816 misleading text for number of rows

* updated e2e tests

* marked a test as flaky until we figure out what is up with it

* addressed legit comment

* Update Loki Snapshots

* loki

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
2025-09-19 12:31:22 +02:00
Phoomparin Mano
b5878d9bf5 Show the embedding hub checklist in embedding homepage (#63596) 2025-09-19 16:47:51 +07:00
Oleksandr Solovyov
6206b6f204 document comments: enable user mentions (#63426) 2025-09-19 09:42:06 +03:00
Mahatthana (Kelvin) Nomsawadi
4ef96bd73a feat(embed-js): Add analytics to Embedded Analytics JS (#63580)
* Add Embedded Analytics JS usage snowplow schema

* Add analytics

* Clarify code with comments

* Fix analytics logic + fix typing

* Add unit tests

* Make E2E embedded analytics JS util supports multiple elements

* Fix code not working in Cypress for some reason

* Add E2E test suite

* Fix import order

* Remove extra line

* Fix E2E from util API change

* Update snowplow/iglu-client-embedded/schemas/com.metabase/embedded_analytics_js/jsonschema/1-0-0

Co-authored-by: Phoomparin Mano <poom@metabase.com>

* Update e2e/test/scenarios/embedding/sdk-iframe-embedding/sdk-iframe-embedding.cy.spec.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Update e2e/support/helpers/e2e-embedding-iframe-sdk-helpers.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Fix E2E by updating a function API

* Pass snowplow schema lint

---------

Co-authored-by: Phoomparin Mano <poom@metabase.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-09-19 06:46:35 +01:00
Romeo Van Snick
b336da1517 Allow going back to snippet root collection (#63549)
* Allow going back to root collection from top-level snippet collection

* Add e2e test for snippet collections
2025-09-19 12:23:34 +10:00
Alexander Polyankin
c98dca560d Unskip transform tests (#63733) 2025-09-18 21:50:52 -04:00
github-actions[bot]
e370820778 Fix: Weird menu state shown when there are no questions in recents (#62985)
* Fix: Weird menu state shown when there are no questions in recents

Fixes #62728

🤖 Generated with [Claude Code](https://claude.ai/code)

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

* fix the robot's mess

---------

Co-authored-by: Claude Code[bot] <noreply@anthropic.com>
Co-authored-by: Ryan Laurie <iethree@gmail.com>
2025-09-18 23:06:45 +00:00
github-actions[bot]
69405a7dea Update translations 2025-09-16 (#63546)
* Update translation sources 2025-09-16

* Update translations

---------

Co-authored-by: github-actions <github-actions@github.com>
2025-09-18 23:06:31 +00:00
Fraser
c0ca9e0493 Only run auto-backport when a backport label is added (#63606)
* Only run auto-backport when a backport label is added

* Assign backported PR to original PR creator
2025-09-18 16:57:42 -06:00
Fraser
ced8d84def Delete out of datte skipped caching test (#63680) 2025-09-19 10:39:24 +12:00
Fraser
8c8279e570 Delete unimplemented FKs in nested queries e2e test (#63684) 2025-09-19 10:39:00 +12:00
Fraser
6afe00b9f1 Fix custom column isNull e2e test (#63685) 2025-09-19 10:38:45 +12:00
Fraser
6e8cca3da7 Unskip join source table e2e tests (#63678) 2025-09-19 10:38:12 +12:00
Maz Ameli
a1582d07de Fix palette preview in Branding section (#63677)
* add tabs

* move reset button and remove needless tableheader

* fix palette preview chart

* change tab text

* cleanup

---------

Co-authored-by: Ryan Laurie <iethree@gmail.com>
2025-09-18 21:19:11 +00:00
Ryan Laurie
40387cc586 Update ActionButton to typescript (#63454)
* update ActionButton to typescript

* address review comments

* replace ref
2025-09-18 21:14:07 +00:00
Alexander Polyankin
911da7f851 Make transform list pages wider (#63710) 2025-09-18 20:49:56 +00:00
Jeff Bruemmer
4deefb87b3 docs - basic table editing (#63601) 2025-09-18 16:36:23 -04:00
Timofey Kachalov
c56432c2f7 Properly run tiles-query as admin user for static endpoints if JWT token is valid (#63692) 2025-09-19 00:11:33 +04:00
Timofey Kachalov
f9e9a20d94 fix(sdk): Properly load Tiles from MB instance (#63676) 2025-09-19 00:07:31 +04:00
Alex Yarosh
5d68e7363f docs: remove references to date coercion (#63716) 2025-09-18 15:58:58 -04:00
Stas Gavrylov
0efa8eac5b Data Reference – Glossary (#63576)
* feat: add glossary UI

* fix: line-height

* Styling

* Show edit button only on hover

* Make the term required

* Delete modal

* Actions menu

* Fix popovers opened for multiple terms

* Autofocus

* glossary api

* serialization

* support moving from h2 to cloud

* WRK-890: Replaces mocked glossary API with proper integration

* WRK-889: Refactor Glossary editing and overall styling

* WRK-889: Fix layout margin

* WRK-889: Update Glossary styling

* WRK-890: Address design comments. Refactor GlossaryTable into a separate component

* WRK-890: Add unit tests for GlossaryTable component

* WRK-890: Add e2e tests for Glossary

* WRK-890: Cleanup css, fix linter

* add boat empty state

* add explanatory text

* text and font weight tweaks

* tweak placeholder text

* improve delete confirm modal

* WRK-889: Update Glossary styling, implement hotkeys handling

* WRK-890: Add optimistic updates for Glossary editing

* WRK-890: Fix unit tests

* WRK-889: Adjust line height for glossary items

* WRK-889: More styling adjustments for GlossaryRowEditor

* WRK-890: Fix e2e tests

* fix merge results

* WRK-890: Address PR comments

* serialization fixes

---------

Co-authored-by: Konstantin Darutkin <spalt08@mail.ru>
Co-authored-by: Kamil Mielnik <kamil@kamilmielnik.com>
Co-authored-by: Oleksandr Solovyov <o@solovyov.net>
Co-authored-by: Uladzimir Havenchyk <125459446+uladzimirdev@users.noreply.github.com>
Co-authored-by: Maz Ameli <maz@metabase.com>
2025-09-18 22:38:56 +03:00
Oleksandr Yakushev
6e3dfdb62b Upgrade c3p0 to 0.11.2 (#63213) 2025-09-18 21:47:35 +03:00
lbrdnk
e915bf2d40 Add guards to semantic search jobs (#63694) 2025-09-18 18:57:14 +02:00
Cam Saul
118613ab89 Binning middleware needs to update :lib/original-binning as well (#63673)
* Binning middleware needs to update `:lib/original-binning` as well

* Test fixes 🔧

* cljfmt
2025-09-18 09:37:29 -07:00
Alexander Polyankin
4f764b82ef Do not autopivot transform query results (#63669) 2025-09-18 16:21:09 +00:00
Alexander Polyankin
ce5a554d4d Add transform count to the job list (#63647) 2025-09-18 16:16:51 +00:00
github-automation-metabase
eb5100abc6 Update generated docs (master) (#63679)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-18 11:44:29 -04:00
Sébastien
64630276e3 Closes EMB-50 tabs dimmed out on iOS (#63690) 2025-09-18 15:57:35 +02:00
Brad Anderson
6f660a3090 Fix #63629: Filter on cards causes an unnecessary horizontal scroll bar for public/static embedding (#63650) 2025-09-18 09:51:31 -04:00
Nicola Mometto
eab4bf076d Transforms prepare for python (#63698)
* pull out transform run utils to prepare for python transforms

* fix: check running-run on transform-id, not run-id

* chore: put on a new line
2025-09-18 13:46:24 +00:00
Jakub Chodorowicz
2be60d80c3 Fix command z not working in connection string input (#63689)
- Stop preventing default event handling onPaste.
- Improve Cypress paste emulation to be compatible with React way of handling paste events.
2025-09-18 15:20:03 +02:00
Romeo Van Snick
3038880e46 Transform run cancellation (#62387)
* Add cancellation to transform api

* Use effect to set polling state

* Add cancellation button to run button

* Set up cancellation on transform page

* Use confirmation modal to cancel transform

* Add run cancel button to run list

* Make api endpoint take transform id instead of run id.

* Fix cancelation api

* Add canceled state to TransformRunStatus

* Add canceled state to transform page

* Add polling to RunListPage

* Remove comment in code

* Set status to canceling when you click cancel

* Add canceling status

* Poll when the transform is canceling

* Add copy for runs that are being canceled

* Manually track fetching status for running and canceling

* Handle canceling status in utils

* Avoid wrapping cancel button in run list

* Add test for canceling run on transform page

* Add e2e for canceling test from runs page

* Fix prop type

* Change copy to Canceling

* Add custom color to canceled state

* Remove mock code

* Increase cancelation tiemout

* Fix copy in text

* Fix snowplow event

* Remove void specifier and close modal in handler directyle

* Add optimistic update for run cancelation

* Avoid manually tracking cancelation status

* Avoid useEffect when changing isPolling

* Add in missing helper

* Remove another useEffect

* Add placeholder run when starting

---------

Co-authored-by: Eric Normand <ericwnormand@gmail.com>
Co-authored-by: Alexander Polyankin <alexander.polyankin@metabase.com>
2025-09-18 10:34:50 +00:00
Nemanja Glumac
b2b04e9206 Add analytics to history revision and data reference (#63587) 2025-09-18 09:44:49 +00:00
Alexander Polyankin
ef8111537e Update copy in UpdateTargetModal.tsx (#63667) 2025-09-18 08:11:11 +00:00
Nemanja Glumac
7bce3ff38a Add analytics to Metabot events (#63415)
* Add Metabot events

* Fix tooltip label

* Add new event for metabot chat controlled from the native editor
2025-09-18 08:44:19 +02:00
Cam Saul
066d3a233d Pure Lib QP: remove code to wrap legacy middleware (#63645)
* cumulative-aggregations-middleware => Lib

* Ensure MBQL 5

* Fix NOCOMMIT

* Fix indentation

* Pure-Lib QP :party:

* Remove some more unused legacy MBQL utils
2025-09-18 00:13:20 +00:00
Fraser
095ad3c39c Tag latest flaky tests (#63617) 2025-09-18 11:54:13 +12:00
Fraser
d50561227f Fix skipped chart drill-through e2e tests (#63548) 2025-09-18 11:18:02 +12:00
Ryan Laurie
63f9d193a9 Use Iframe for changelog (#62943)
* use iframe for changelog

* add query params and tabs

* always show update info

it's useful even if you're on the latest version

* remove metabase as configurable host

* always allow changelog/releases in iframes

* fix tests

* fix tests

* update tests

* use root metabase domains

* fix test

---------

Co-authored-by: John Swanson <john.d.swanson@gmail.com>
2025-09-17 14:40:52 -06:00
Alexander Polyankin
0a18c13feb Skip failing tests (#63663) 2025-09-17 18:57:52 +00:00
Nemanja Glumac
a58c63a74f Add analytics to x-rays (#63498) 2025-09-17 19:55:51 +02:00
Alexander Polyankin
96f1ef42a2 Disable transform editing buttons when running (#63642) 2025-09-17 16:05:51 +00:00
Jakub Chodorowicz
fd073fb8b1 PRG-130 Send parse connection string parsing events only on blur (#63558)
* Send parse connection string parsing events only on blur

* Use synchronous last parsing result for monitoring

* Improve test assertions for connection string events

* Make sure we don' track the same parsing event again

* Refactor ts-match to simple if conditions

* Make lastStatus have the same success value depending on non undefined values

* Improve the snowplow Cypress test setup for connection string
2025-09-17 16:03:04 +00:00
Alexander Polyankin
a7971b43b1 Fix table layout issues in transform pages (#63540) 2025-09-17 11:49:22 -04:00
Cam Saul
0d1b4e253a cumulative-aggregations-middleware => Lib (#63592)
* cumulative-aggregations-middleware => Lib

* Ensure MBQL 5

* Fix NOCOMMIT
2025-09-17 15:47:13 +00:00
Sébastien
9986021635 Closes EMB-303 search bar in embedding no longer awfully long (#63632) 2025-09-17 17:09:28 +02:00
Anderson
ae422678b2 [Admin settings] Show help documentation to connect DB in a side panel (#63420)
* [Admin settings] Show help documentation to connect DB in a side panel

* Add unit tests

* Add more tests / tweaks

* Add e2e tests

* Make sure help content is not rendered if not available

* Self-review tweaks

* Use useDocsUrl in DatabaseHelpSidePanel.tsx

* Use aside element for the side panel

* Use await findBy when possible

* Use JSDoc / Remove unnecessary comment

* Add some style to blockquote

* Add test file for useHelpLink

* Fix failing test

* Add analytics event
2025-09-17 11:59:05 -03:00
Cam Saul
8ecc5c6718 add-rows-truncated middleware => Lib (#63616) 2025-09-17 14:52:21 +00:00
Cam Saul
dec95aabe7 resolve-joins middleware => Lib, remove add-source-metadata (#63608) 2025-09-17 14:50:07 +00:00
Ngoc Khuat
98e29f6c39 [Transform python] python lib apis and settings (#63568) 2025-09-17 14:23:11 +00:00
lbrdnk
b110c02981 Fix empty db url for metric collector job (#63633) 2025-09-17 14:15:20 +00:00
github-automation-metabase
a5056280e8 Update generated docs (master) (#63611)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-17 10:10:53 -04:00
Alexander Polyankin
33f5b24a0a Fix flaky "Change target" behavior for transforms (#63526) 2025-09-17 09:15:43 -04:00
Uladzimir Havenchyk
323e6f3823 chore: drop unused files (#63500) 2025-09-17 13:29:30 +03:00
Timofey Kachalov
b5b9bad486 Add the better handling of the missing enterprise token for Sample Apps e2e (#63573) 2025-09-17 11:51:20 +04:00
Thomas Schmidt
7f4cb813c2 Adjust legacy sql generation button to toggle Metabot chat (#63554)
* Adjust legacy sql generation button to toggle Metabot chat

* Change placeholder text
2025-09-17 07:01:08 +00:00
Oleksandr Solovyov
068f460124 [metabot] tool_calls should be a vector (#63579)
Co-authored-by: Noah Moss <32746338+noahmoss@users.noreply.github.com>
2025-09-17 09:09:28 +03:00
Oleksandr Solovyov
50e10ee9c2 enable metabot stats and prevent recursive token checks (#63574) 2025-09-17 09:09:06 +03:00
Cam Saul
4d54129a72 viz-settings middleware => Lib (#63597) 2025-09-16 22:32:46 -07:00
Cam Saul
3d2789c2f1 Fix #63571 (#63595) 2025-09-16 20:31:19 -07:00
Ryan Laurie
2e4c39904e Handle when tags are not defined (#63588)
Co-authored-by: Fraser <fraser@metabase.com>
2025-09-17 00:29:57 +00:00
Alexander Polyankin
0911bbe3b3 Simplify state management and fix the flicker with the transform run button (#63586)r
* Fix optimistic updates with transforms

* Fix optimistic updates with transforms
2025-09-16 18:49:37 -04:00
Luis Paolini
e08969edd9 Document password handling for special characters (#63590)
* Document password handling for special characters

* Add section on special character passwords in MariaDB

Added information about handling passwords with special characters in MariaDB connection strings.

* Apply suggestions from code review

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Update docs/databases/connections/mysql.md

---------

Co-authored-by: Alex Yarosh <alexandra@metabase.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-09-16 19:22:14 -03:00
Aleksandr Lesnenko
b5942d4f36 respect decimals setting when compact formatting is enabled (#63457) 2025-09-16 17:54:07 -04:00
Alex Yarosh
914d56b2c0 docs: transforms draft (#63594)
* skeleton

* transforms

* privileges

* Apply suggestions from code review

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

* edits

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-09-16 21:53:21 +00:00
Anton Kulyk
035be556eb Improve the look and feel of charts in dashboards (#62610)
* Fix vertical legend position for cartesian charts

* Set dashcard title font size to 14px

* Decrease legend dot size

* Decrease value labels density for cartesian charts

* Use normal font weight for axis names, labels, etc

* Make y axis split lines solid vs dashed

* Show scalar card title in dashcard header

* Always show pie chart total

* Hide axis names on small dashcards

* Update screenshots

* Fix tests

* Fix number cards font size

* Fix hiding cartesian chart axis

* Fix font styles in other legend components

* Fix e2e tests

* Hide cartesian chart axes independently

* Use different legend style only in dashboards

* Apply min spacing to labels per series

* Fix legend dot size in edit mode

* Update label sizes for funnels and sankey charts

* Use bold font for data labels

* Update screenshots

* prettier

* Update Loki Snapshots

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
2025-09-16 21:09:38 +00:00
Cam Saul
1919a6cd62 Trivial middleware, qp.compile, qp.execute => Lib (#63419)
* Trivial preprocessing middleware => Lib

* Handle already-native MBQL 5 queries

* substitute-persisted-query => Lib

* A bunch of post-processing middleware is actually MBQL-5 ready

* Fixx 🔧

* Test fixes 🔧

* More fixes 🔧

* Fix more stuff

* Wow even more test fixes =(

* (Hopefully) final round of test fixes

* Kondo

* More test fixes 🔧

* Fixes 🔧
2025-09-16 22:08:09 +03:00
Jeff Bruemmer
1a16244f86 docs - note on images (#63583) 2025-09-16 13:54:25 -04:00
Alexander Polyankin
ea5b0d4a9e Make description input in transforms bigger (#63541) 2025-09-16 15:13:57 +00:00
Ryan Laurie
b84b11532e skip broken about e2e test (#63572) 2025-09-16 08:07:07 -06:00
Oleksandr Solovyov
5e3968f517 report date for metabot usage info to HM (#63560)
* report date for metabot usage info to HM

* disable metabot stats to resurrect stats
2025-09-16 16:45:11 +03:00
Jeff Bruemmer
1b2ebb4fd7 docs - clarify webhook permissions (#63567)
* update webhook docs

* summary

* more perms
2025-09-16 09:30:17 -04:00
github-automation-metabase
d888aa8ee1 Update generated docs (master) (#63542)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-16 09:01:00 -04:00
Ngoc Khuat
7aa3f7fed1 Send pulse skip legacy alerts (#63497) 2025-09-16 11:44:43 +00:00
Phoomparin Mano
be673c4771 Unskip and fix flaky locale test for embedded analytics js (#63518) 2025-09-16 18:05:54 +07:00
Fraser
41db01c5e2 Unskip About page e2e test (#63538) 2025-09-16 22:19:55 +12:00
Oleksandr Solovyov
b0299c474d fix metabot token count query (#63556) 2025-09-16 13:04:04 +03:00
Ngoc Khuat
3275cb9a44 Driver table CRUD to skip QP (#63427) 2025-09-16 09:10:17 +00:00
lbrdnk
e7b70ba03f :metabase-search/semantic-fallback-results-usage (#63442) 2025-09-16 11:00:09 +02:00
Jakub Chodorowicz
25adbcfee8 Adjust label spacing in the db form (#63499)
# Conflicts:
#	frontend/src/metabase/databases/components/DatabaseEngineField/DatabaseEngineSelect.tsx
2025-09-16 10:24:52 +02:00
Timofey Kachalov
94b90013cb refactor(sdk): Replase Zod with Yup for SDK bundle schema validation (#63489) 2025-09-16 10:34:39 +04:00
Oleksandr Solovyov
065d6ce5aa Store Metabot conversation history with token usage and report it to HM (#63073) 2025-09-16 09:02:01 +03:00
Romeo Van Snick
2ce5dc4e46 Native editor sidebar for transforms (#63287)
* Swap cancel and save button

* Render sidebar in native query editor for transforms

* use toggleSnippetSidebar from props

* Fix snippets sidebar

* Export SelectionRange

* Add aria label for data reference button

* Open database on mount

* Add aria-label to snippets button

* Add e2e tests for sidebar in SQL transforms

* Rename prop for clarity

* Return instead of throwing

* Use Lib.rawNativeQuery

* Pass selected text to native editor

* Fix types

* Move longer handlers to hooks in utils

* Handle empty text and reshuffle code
2025-09-16 15:36:49 +10:00
Aleksandr Lesnenko
5b450f29aa support value and goal column selection in progress visualization (#62963)
* progress bar: support value and goal column selection

* design feedback

* fix spacing

* BE review

* FE review

* spec
2025-09-16 04:16:13 +00:00
Nathan Voxland
dbc6913076 Reindex has to be async on language change callback (#63531) 2025-09-16 03:27:35 +00:00
Cam Saul
c1a3971ae8 add-implicit-clauses middleware => Lib (#63360)
* add-implicit-clauses middleware => Lib

* Test fixes 🔧

* Some lib.convert fixes from #61398

* Test fixes 🔧

* More test fixes

* Test fixes 🔧

* Handful of test fixes 🔧

* Discourage use of legacy MBQL utils in QP

* Integrate the platinum metadata provider

* Only one failing test left

* Test fix 🔧

* Kondo

* Test fixes 🔧

* Test fix 🔧

* Test fixes 🔧

* Handle legacy pivot viz settings where `base-type` might not be present

* Handle legacy pivot viz settings where `base-type` might not be present

* Handle legacy pivot viz settings where `base-type` might not be present

* Handle legacy pivot viz settings where `base-type` might not be present

* Handle legacy pivot viz settings where `base-type` might not be present

* Handle legacy pivot viz settings where `base-type` might not be present

* Handle legacy pivot viz settings where `base-type` might not be present

* Handle legacy pivot viz settings where `base-type` might not be present

* Handle legacy pivot viz settings where `base-type` might not be present

* Test fix 🔧

* Test fix 🔧

* Kondo

* Test fix

* Test fix 🔧

* Skip failing transforms tests

* Mark failing tests flaky
2025-09-15 19:35:54 -07:00
appleby
319fc114ab Update :bookmarked and :user_recency scorer to work with mysql and mariadb (#63205)
* Update :bookmark scorer to work with mysql and mariadb

* Update :user_recency scorer to work with mysql and mariadb
2025-09-15 18:43:22 -07:00
Alexander Polyankin
c456cb5a6f Disable failing transform tests (#63535) 2025-09-15 22:52:32 +00:00
Fraser
a743c86b25 Enable skipped implicit-join and breakout e2e tests (#63486) 2025-09-16 10:50:36 +12:00
Fraser
0348e0b3c3 Remove skipped pie chart label truncation e2e test (#63471) 2025-09-16 10:47:59 +12:00
Fraser
a32eeb88a2 Fix skipped time series binning e2e test (#63428) 2025-09-16 09:37:24 +12:00
Fraser
7ad5cdac94 Fix skipped notebook info popoever e2e tests (#63487) 2025-09-16 09:37:07 +12:00
Phoomparin Mano
0aa42f596f Integration branch for Embedding Hub (#62986)
* Setup sidebar and onboarding page for embedding hub (#62517)

* Add the add data and new dashboard modals to embedding hub (#62528)

* mark sandboxed step as done (#62758)

* Auto-mark 'secure your embeds' step as done when either JWT or SAML is configured (#62736)

Co-authored-by: Nicolò Pretto <info@npretto.com>

* Add UTM tags to documentation links in the embedding hub (#62747)

* Add a wizard to select a table to x-ray in embedding hub (#62715)

* Mark the create embed steps in embedding hub as done from embed flow (#62759)

* Add a dropdown to switch embedding solutions in embedding hub (#62870)

* fix(embed-hub): adds key prop to component passed to jt (#63060)

* feat(embed-hub): checklist endpoint (#62875)

* feat(embed-hub): EMB-770 and EMB-742, add checklist endpoint with
'create-dashboard'

* feat(embed-hub): EMB-740 auto mark "Add data" as done

* Revert "mark sandboxed step as done (#62758)"

This reverts commit be775aceed.

* feat(embed-hub): EMB-768 move sandbox check to the BE

* EMB-772: move all "done" checks on the be, move endpoints to ee

* cleanup

fmt

configure enterprise module to make linting pass

test: activate license to make e2e tests pass again

remove fe unit test now that all the logic is on the be

add doc to the endpoint to maybe the tests will pass?

whitespace?

fixes

idk anymore how to make all the linters be happy

last try

refactor has-configured-sso to a function

revert  visibility to see if tests pass

sort config.edn

* tests: remove cy.wait from embed hub tests (#63066)

* Bit of cleanup

- remove warn-on-reflection; there is no interop
- clean up a bit of duplication in sql clause generation
- remove unncessary try/catch around t2 access
- remove a few boolean calls on boolean functions

---------

Co-authored-by: dan sutton <dan@dpsutton.com>

* fix(embed-js): disable the next button when embedded js is disabled (#63134)

* Replace the accordion in embedding hub with steppers (#63271)

* Move embedding settings into its own top-level menu (#63339)

* Add related setting cards to modular embedding and setup guide (#63340)

* Remove the Embed menu from the New menu (#63385)

* Completing later steps on embedding hub should not tick off the former steps (#63393)

* Modular embedding toggle label should depend on toggle states (#63391)

* Add the interactive embedding upsell to the settings page (#63399)

* Lock embed in production step in embedding hub checklist until sso configured (#63449)

* Use ee plugins to check if embedding is enabled in nav (#63446)

* Check for CSV uploads in embedding-hub checklist endpoint (#63501)

* update embedded-analytics-js.md to have consistent quickstart pages

---------

Co-authored-by: Nicolò Pretto <info@npretto.com>
Co-authored-by: dan sutton <dan@dpsutton.com>
Co-authored-by: Alexander Polyankin <alexander.polyankin@metabase.com>
2025-09-15 22:27:57 +01:00
Brad Anderson
dd68df30c9 Fix: UXW-683 Saving document resets undo history (#63462)
Fixes issue where undo history is deleted on save. Also fixes issue where CommentsSidesheet stays open (big unclosable grey box) when navigating to a different document when it was open.
2025-09-15 16:19:52 -04:00
Jeff Bruemmer
af495f2ff3 elaborate on privacy (#63524) 2025-09-15 14:46:39 -04:00
Alexander Polyankin
c343eaa0a3 Fix flaky transform tests (#63523) 2025-09-15 14:36:33 -04:00
Ngoc Khuat
29c013a78a Add rename-tables! driver method (#63302) 2025-09-15 16:36:13 +00:00
Alexander Polyankin
a85675ef2a Fix some transform flaky tests (#63517) 2025-09-15 12:00:00 -04:00
Alexander Polyankin
8c1582e601 Fix metrics stats in anonymous tracking (#63507) 2025-09-15 15:28:29 +00:00
Jakub Chodorowicz
a7eacc1c96 PRG-138 fix mongo and sql server YAML setup (#63496)
* Move sqlserver description to extra info tooltip

* Fix mongo additional-options not appearing in advanced-options section

# Conflicts:
#	e2e/test/scenarios/admin/databases.cy.spec.js
2025-09-15 17:21:10 +02:00
Jakub Chodorowicz
6ab20070a4 PRG-137 add engine icons (#63491)
* Add new DB engine icons, add icon to regular add DB flow

* Refactor old export style

* update h2 icon

* Fix layout of browse databases cards

* Adjust padding of browse databases cards

* Remove empty comment

* Render default db icon in case of empty engine key
2025-09-15 17:18:18 +02:00
Alexander Polyankin
7bc2093651 Ignore new flaky transform tests until they are fixed (#63516) 2025-09-15 08:34:04 -06:00
Alexander Polyankin
fa9d4ad2a4 Make RTK queries populate metadata created by the getMetadata selector without using the entity framework (#63262) 2025-09-15 10:19:48 -04:00
metamben
ea74e4e1dc Fall back to DESCRIBE if Athena JDBC reports duplicate column names (#63452)
* Fall back to DESCRIBE if Athena JDBC reports duplicate column names

* Make test fail another way

* Fix test

* Verify that the hijacked function gets called
2025-09-15 10:51:27 -03:00
Fraser
1920cc924c Delete old skipped test (#63372) 2025-09-15 21:49:49 +12:00
Sébastien
df7ba12468 Closes EMB-791 custom pivot column title not being translated (#63436) 2025-09-15 10:23:13 +02:00
Romeo Van Snick
35f9175eb0 Hide empty breakout step in readonly notebook (#63367) 2025-09-15 14:28:50 +10:00
Fraser
eeab38518a Remove skipped Metabase Cloud e2e tests (#63417) 2025-09-15 10:57:54 +12:00
Fraser
bc7d55b0dd Remove field filter popover cutoff e2e test (#63418) 2025-09-15 10:57:25 +12:00
Alexander Polyankin
c5b5970b77 Handle legacy viz settings where base-type might not be present (#63468) 2025-09-13 02:14:00 +00:00
Nathan Voxland
c8982e0d1d Fixed lint error (#63460) 2025-09-12 21:42:48 +00:00
Aleksandr Lesnenko
3477b876a2 fix trend chart month cut off (#63453) 2025-09-12 21:08:21 +00:00
Alexander Polyankin
63a60230f1 Migrate the Revision entity to RTK query (#63440) 2025-09-12 17:08:12 -04:00
Jeff Bruemmer
b9838f7cf7 docs - embedding chat (#63259) 2025-09-12 16:32:36 -04:00
Nathan Voxland
c024186f79 Search Indexing Improvements (#63099) 2025-09-12 15:01:39 -05:00
Cam Saul
acbff0c969 ℳℯ𝓉𝒶𝒹𝒶𝓉𝒶 𝒫𝓇ℴ𝓋𝒾𝒹ℯ𝓇 𝒫𝓁𝒶𝓉𝒾𝓃𝓊𝓂 ℰ𝒹𝒾𝓉𝒾ℴ𝓃 (#63368)
* Metadata Provider Platinum Edition

* Revert some formatting changes

* Revert changes to QP tests

* Revert NOCOMMIT changes

* Fix missing ns alias

* Pull in missing changes from other branches

* Misc fixes and changes

* Fixes

* Fix bugs in JVM metadatas

* Fix composed provider not propagating inactive

* JS fixes 🔧

* Test fix 🔧

* Test fixes 🔧

* Test fixes 🔧

* Another JS test fix 🔧

* More FE fixes 🔧

* Don't be too strict

* Set database

* Fix merge conflict

* Fix kondo

---------

Co-authored-by: Alexander Polyankin <alexander.polyankin@metabase.com>
2025-09-12 18:46:03 +00:00
Jeff Bruemmer
75d56ef281 docs - rename file (#63451)
* rename file

* links
2025-09-12 18:20:26 +00:00
Jeff Bruemmer
d2b1aadf84 docs - docs (#63413) 2025-09-12 13:49:04 -04:00
Ryan Laurie
f07baad1f8 add environment var to disable embedding builds (#63441) 2025-09-12 10:40:59 -06:00
Cam Saul
eecf97f077 Sandboxing middleware => Lib (#63321)
* Sandboxing middleware => Lib

* Test fix 🔧

* Remove some unused stuff

* rename `row-level-restricitions` middleware => `sandboxing`

* Remove TODO

* :model/GroupTableAccessPolicy => :model/Sandbox

* Test fixes 🔧

* Test fix and mark more stuff deprecated

* Test and Kondo fixes 🔧

* "Fix" sandboxes with extra columns because I don't want to update e2e tests

* cljfmt
2025-09-12 09:34:57 -07:00
Alex Yarosh
4768c58a01 docs - add modular embedding to securing embeds (#63444)
* docs - add modular embedding

Also adjust headers a bit because ToC is difficult to scan

* Update docs/embedding/securing-embeds.md

* Update docs/embedding/securing-embeds.md
2025-09-12 16:16:44 +00:00
github-automation-metabase
84530c5a58 Update generated docs (master) (#63421)
Co-authored-by: github-actions <github-actions@github.com>
2025-09-12 12:16:07 -04:00
Ryan Laurie
0d1522742e Make question moving errors bubble correctly (#63409)
* make sure errors bubble correctly

* e2e tests

* fix test
2025-09-12 09:48:37 -06:00
Brad Anderson
2fcecd5de8 Fix: UXW-606 Bookmark drag and drop handle shown when there's nothing to rearrange (#63358)
* UXW-606 Hides bookmark drag handle when there's only one bookmark

* UXW-606 Adds unit tests
2025-09-12 10:25:58 -04:00
Riley Thompson
9164ad955e Disable transforms when db routing is enabled (#63402)
* disable transforms with routing

* disable selecting dbs with routing enabled
2025-09-12 09:32:35 -04:00
Sébastien
293120750e Closes EMB-792 dashcard title and description translation (#63432) 2025-09-12 14:26:59 +02:00
Anton Kulyk
b8b61d0647 Update "Customize Homepage" modal UI (#62280)
* Update "Customize Homepage" modal UI

* Update tests

* Reset selected dashboard on "Cancel" btn click

* Fix button name in test
2025-09-12 13:23:08 +01:00
Anton Kulyk
e4744ae67f Always use "public" schema for x-rays if it exists (#62285)
* Always use "public" schema for x-rays if it exists

* Handle null schema

* Fix type error
2025-09-12 13:13:00 +01:00
Nemanja Glumac
aa59dca84e Make "database" the first option in the "Add data" modal (#63412) 2025-09-12 10:52:22 +02:00
Cam Saul
5f5b2f6d07 Minor lib.convert fixes (#63401)
* Some lib.convert fixes from #61398

* Fix conversion of :dimension pseudo-clauses

* cljfmt
2025-09-11 20:12:13 -07:00
Cam Saul
40420f8d44 Test to confirm #63261 is fixed in master (#63414) 2025-09-12 03:11:34 +00:00
Cam Saul
34bddeb931 Normalize horribly broken fingerprints (#63407)
* Normalize horribly broken fingerprints

* Handle nil fingerprints
2025-09-12 03:02:09 +00:00
github-automation-metabase
16daec0315 Bump com.github.seancorfield/next.jdbc from 1.3.1048 to 1.3.1070 (#63220)
Inspect dependency changes here: https://github.com/seancorfield/next-jdbc/blob/v1.3.1070/CHANGELOG.md
2025-09-12 02:38:10 +00:00
github-automation-metabase
5caa919d59 Bump nrepl/nrepl from 1.3.1 to 1.4.0 (#63222)
Inspect dependency changes here: https://github.com/nrepl/nrepl/blob/v1.4.0/CHANGELOG.md
2025-09-12 02:22:22 +00:00
github-automation-metabase
69bda6feef Bump babashka/fs from 0.5.26 to 0.5.27 (#63216)
Inspect dependency changes here: https://github.com/babashka/fs/blob/v0.5.27/CHANGELOG.md
2025-09-12 02:18:39 +00:00
github-automation-metabase
cb1c25d58b Bump io.github.metabase/hawk from 1.0.11 to 1.0.12 (#63221)
Inspect dependency changes here:
2025-09-12 02:12:07 +00:00
Anderson
d998df052e [PRG-114] Show help & more specific error message when a database connection fails (#62956)
* Implement new DatabaseFormError component & break DatabaseForm component down

* Implement scrolling actions / Avoid 'div in p' console error

* Fix typing check issues / Add 'Read the docs' link url

* Define 'invite teammate' and 'contact support' urls

* add more tests / further refactoring

* css tweaks

* Simplify tests a bit

* Remove comment / Fix translation cases

* Refactor tests

* Adjust 'Check Host and Port settings' button / Fix css lint

* Fix test

* Add target=_blank to doc links / Use existing color for the error container border

* Use cloud-gateway-ips setting when showing IPs to whitelist / Move some helpers to a local utils.tsx

* Use 'be.visible' over 'exist' in cypress test

* Use useDisclosure

* Make Alert title have dark text color by default / Add storybook case to show warning color variant
2025-09-11 22:07:06 -03:00
Fraser
ce15cfeea9 Mark pagination test as flaky (#63328) 2025-09-12 10:54:50 +12:00
Ryan Laurie
a10afa8256 Deprecate old Alert (#63408) 2025-09-11 21:22:34 +00:00
Alex Yarosh
daca8d6c4e docs: translations are case-insensitive (#63383)
* docs: translations are case-insensitive

* Update docs/embedding/translations.md

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>

* Add localization details for embedded Metabase

Added section on localizing embedded Metabase.

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-09-11 17:09:35 +00:00
Timothy S. Dean
80d6389e6e Handle mixed catalog table errors in Trino sync (#63356)
Trino's Hive plugin shows the tables in question in its metadata, but if you try to get a handle on these tables, it will always throw an exception with error code `UNSUPPORTED_TABLE_TYPE`. The Iceberg plugin has a similar exception for such circumstances.

For us, there doesn't seem to be much difference between not being able to query a table because it's an unsupported type and not being able to query because we don't have permissions, so`have-select-privilege?` is modified to return false in these cases. We can examine the vendor-specific error code on the SQLException to detect them.
2025-09-11 09:53:04 -06:00
Kamil Mielnik
7f723a20de Document Comments (#62800)
* Update Start new thread UI

* Refactor

* Lint migrations

* Lint migrations

* Lint

* Fix comments count

* Thread submit input improvements

* Align 'Start new thread' button

* mention metabase entities

* Stupid link copying

* Deep linking to comments

* fix: sidebar style improvements

* Fix line breaking bug on submit

* Maz Comments styling tweaks (#62964)

* add tabs hiding/showing logic

* only show persistent button for open comments

* move comment buttons to the right

* attempt to fix tests

* always display the add-a-comment input in the sidebar

* Remove unused attr

* Placeholders without flags

* Refactor comments' tabs markup

* Refactor CommentsMenu

---------

Co-authored-by: Kamil Mielnik <kamil@kamilmielnik.com>
Co-authored-by: Stas Gavrylov <stasgavrylov@gmail.com>

* Fix incorrect counter for unresolved comments

* Fix warning

* Fix key warning in Discussions

* Make document read-only when comments sidebar is open

* Refactor URL generation

* Automatically open correct tab for the comment targeted by URL hash

* Clean up

* Use createPortal instead of Portal from metabase/ui to fix CommentsMenu appearing above CommentsSidesheet when visiting a specific comment via URL

* Remove more/less feature

* Set max-height when editing comments, fix scrolling area

* Extra padding

* Make it possible to mention yourself

* Add ability to resolve deleted threads

* Remove ability to comment on resolved threads

* Remove ability to add new comments on Resolved tab

* allow using @ character without showing mention list

* Fix type errors

* Fix types

* Resolve/unresolve deleted comments

* Remove DocumentContext

* Fix inserting mentions on Enter press

* Minor styling fixes for mentions

* Remove unused endpoint

* Clean up

* Remove unused component

* Remove stories

* Fix storybook

* Remove TODO

* Remove unused file

* Remove outdated comment

* Avoid cast

* Remove redundant code

* Deal with any

* Don't trim empty nodes

* Simplify Discussions component

* Align avatar, submit button and code editor

* Do not show last divider if not necessary

* Get rid of currentIndex

* Fix typo

* Remove hack

* Check only unresolved comments when deciding whether to autofocus comment editor when sidebar opens

* Enable inline_code styling in comments

* Rename css file

* Fix cast

* Use top instead of transform

* Use a flag

* Remove commented-out code

* Move getCommentsUrl to utils

* Use Menu

* Add Avatar to metabase/ui

* Bring back accidentally removed code

* Resolve CSS duplication

* Use void

* Add comment

* Add all comments sidebar

* Use createSelector

* Fix no results styling

* Autofocus editor when editing comments

* Disable menu when editing is disabled

* Add a toast when copying the link

* Prevent deleting and editing someone else's comments

* Fix types

* Update copy

* Cleanup all comments sidebar

* Extract isMetabotBlock

* Use CustomStarterKit

* Copy

* feat: add Emoji picker (#62991)

* feat: add Emoji picker

* fix: styles

* fix: class for loading label

* Add ability to inline emojis in CommentEditor

* fix: keyboard events for emoji picker

* fix: focus visible for emoji picker viewport

* Implement proper keyboard support for inline emojis

* Temporarily hide emoji reaction button

* Improve UX around selecting first emoji

---------

Co-authored-by: Stas Gavrylov <stasgavrylov@gmail.com>

* Pass editable

* Use mentions plugin

* Fix z-index

* Add reactions BE

* Improve list paddings

* Add users support to SmartLink and MentionExtension

* Remove old mentions

* use semantic colors for Avatar

similar logic to what do for users in admin

* show add comment input when we switch from resolved tab

* Limit number of user results

* feat: add comment reactions (#63072)

* feat: add comment reactions

* fix: typescript

* fix: click to react

* fix: styling

* tweak spacing between replies (#63100)

* fix: reply styles

* Update submit shortcut to Cmd-Enter. Fix emoji picking behavior

* fix: do not close discussion sidesheet on some escape events

* fix: cancel editing on escape press

* Make DocumentPage 400px narrower when comments modal is opened

* Extract shared tiptap-related code

* Move EmojiPicker to common/components

* Fix DiscussionComment error when creator is null

* Fix missing formatting menu in CommentEditor

* Add tests boilerplate

* Allow many reactions on a comment

* Hydrate creator info on deleted comments

* Add first test and helpers

* Add tests for more types of nodes

* Add comment

* Improve test name

* Test highlighting

* Add test for splitting paragraphs

* fix: blur comment editor on submit

* Add schema upgrade test

* Add test for creating comments and threads

* Add tests for deleting comments

* Editing a comment

* Test for Esc

* fix: limit editable functionality and add comment styles (#63161)

* Fix test

* Update test

* Fix flaky test

* Fix tooltip

* fix: do not react on deleted comments

* fix: show resolved threads

* fix duplicate replies display

* Add mentions tests

* Make suggestions taller to accommodate users search results without a vertical scrollbar

* don't count deleted comments for the comment badge

* don't show threads if all comments deleted

* Add emoji tests

* fix: can react true by default

* Fix floating menu positioning in CommentEditor

* fix document / menu selected item styling

* Sort comment reactions by created_at ASC

* Make Esc close emoji popup

* first pass at comments api

* Fix reactions ascending order

* WIP

* fix linting

* model resolution

* update test setup to include _id, so equality check works correctly

* replace is_deleted with deleted_at to detect deleted comments

* fix types

* remove ?new=true from url after adding a new comment

* Fix tests

* Improve arrow navigation when emoji popup is opened. Allow selecting with Tab

* Add test

* Refactor

* Update test

* Fix emoji popup Esc handler removal

* Add formatting tests

* Rename test

* Add e2e API helpers to create and delete comments

* Update test name

* Refactor

* Fix types

* update is not deleted eh

* Add test for the comment button

* Add test

* Add a test

* Add test

* test: basic resolve/unresolve tests (#63243)

* test: add resolve other person thread test

* Add test for disabling document editing when comments are open

* Add test for unsaved document changes

* Add test for show all comments button and fix the issue

* Add tests for deleting/editing other people's comments

* Add e2e tests for comment links

* add e2e tests for all comments

* way better/less verbose permission checks

* test: cannot reply to resolved threads

* ESLint

* Update assertion

* Fix unresolved comments count

* e2e tests for comments reactions

* first iteration of notifications

* fix migration lint errors

* fix module tests

* Add label attribute for SmartLinks to simplify server-side notifications rendering

* add e2e test for removing ?new=true after creating a comment

* Fix

* fix clj syntax

* Remove commented-out code

* Use H.readClipboard()

* Refactor

* Update reaction icon

* Move util

* Lint

* Fix

* Lift conditional rendering, move Reaction component to a separate file

* Refactor

* Do not render invalid links

* Refactor

* Update new comment notification template

* add e2e test for top blocks

* fix: comment date to respect browser locale

* Update reactions icon

* Add 1st test for email subscriptions

* Update email template to match figma, remove the comment content

* Add document icon to email template

* Update test

* Remove protocol from the link

* Extract verifyEmail helper

* fix migrations because mysql is majorly unhappy about those rollbacks

* correct urls for comments, notifications on mentions

* Update assertion

* Insert both comment URL and document URL into the email template

* Fix url

* fix copy tests

* Add a setup for next test

* Implement assertions

* 2nd email variant

* Add another test

* Add an assertion

* add more tests for email template

* Ignore whitespace

* Error handling for mutations - toasts

* add more tests

* feedback: drop blue border from paragraph

* feedback: placeholder

* fix e2e test to pass

* Update setup

* Comments design polish (#63352)

* use new Send icon instead of up_arrow

* remove extra space below a Discussion

* restyle Discussions

* fix CommentEditor spacing

* restyle current user reaction

* only show No Comments message on the All Comments sheet

* add on-hover highlighting for All Comments section

* fix for fe-type-check

* fix test

* Cleanup

---------

Co-authored-by: Kamil Mielnik <kamil@kamilmielnik.com>

* put user permissions check back and new api for mentions

* pagination

* Use new GET /api/ee/comment/mentions in frontend

* Use new GET /api/ee/comment/mentions in smart link node

* paid feature in tests

* seed notifications

* oh

* clj-kondo 🤦

* port numbers

* Try to fix flaky test

* attempt to fix flaky e2e

* disable returning users for mentions

* disable mention related tests

---------

Co-authored-by: Stas Gavrylov <stasgavrylov@gmail.com>
Co-authored-by: Anton Kulyk <kuliks.anton@gmail.com>
Co-authored-by: Konstantin Darutkin <spalt08@mail.ru>
Co-authored-by: Maz Ameli <maz@metabase.com>
Co-authored-by: Uladzimir Havenchyk <uladzimir@metabase.com>
Co-authored-by: Oleksandr Solovyov <o@solovyov.net>
2025-09-11 22:09:54 +07:00
Aleksandr Lesnenko
179d170826 fix question title layout (#63348)
* fix question title layout

* fix dashboards as well
2025-09-11 10:32:34 -04:00
Aleksandr Lesnenko
b263bd0bc0 fix missing tooltip max width (#63353)
* fix missing tooltip max width

* repro
2025-09-11 10:32:25 -04:00
Aleksandr Lesnenko
4e851e0e19 fix date picker month navigation timezone issue (#63366) 2025-09-11 10:32:15 -04:00
Braden Shepherdson
8ac41c91d2 [ClickHouse] Fix SQL for equality filters on UUID columns (#62922)
Fixes #62492.

A literal UUID was reaching the driver as
`[:value "uuid-string" {:base_type :type/UUID}]`
but this was not recognized as a UUID-valued field because `:value`
clauses have `:base_type` and not `:base-type` like `:field` clauses.

Therefore the `:sql` core driver was rewriting this clause to cast the
UUID field to a string and compare that against the literal string.
With that logic now correctly recognizing such a `:value` clause, the
UUID fields are compared directly. This is much better for indexing,
but also works with *nullable* UUID columns, where the
`CAST(my_uuid AS text)` would cause SQL compilation errors.
2025-09-11 13:59:39 +00:00
2421 changed files with 637622 additions and 513679 deletions

View File

@@ -173,6 +173,7 @@
metabase.driver.sql-jdbc.execute/execute-prepared-statement!
metabase.notification.models/create-notification!
metabase.pulse.send/send-pulse!
metabase-enterprise.transforms-python.python-runner-test/execute!
;; Safe in tests, where we typically use a private, temporary index per thread.
metabase.search.core/reindex!
metabase.util/run-count!
@@ -228,7 +229,7 @@
(clojure.core.logic/fresh)
(clojure.core.logic/matcha)
(clojure.core.logic/run)
(clojure.test/is [query= =? malli= qv=])
(clojure.test/is [=? malli= qv=])
(clojure.tools.macro/macrolet)
instaparse.core/transform
(metabase.server.streaming-response/streaming-response)
@@ -418,6 +419,7 @@
metabase-enterprise.transforms.api-test/with-transform-tags clojure.core/let
metabase-enterprise.transforms.api-test/with-worker-runs clojure.core/let
metabase-enterprise.transforms.test-util/with-transform-cleanup! clojure.core/let
metabase-enterprise.transforms.execute/with-transform-lifecycle clojure.core/let
metabase.actions.test-util/with-actions clojure.core/let
metabase.api.common/let-404 clojure.core/let
metabase.app-db.custom-migrations.util/with-temp-scheduler! clojure.core/fn
@@ -519,6 +521,7 @@
metabase-enterprise.cache.config-test/with-temp-persist-models hooks.common/with-seven-bindings
metabase-enterprise.semantic-search.db.connection/with-migrate-tx hooks.common/let-one-with-optional-value
metabase-enterprise.serialization.test-util/with-temp-dpc hooks.toucan2.tools.with-temp/with-temp
metabase-enterprise.transforms-python.drivers-test/with-test-table hooks.common/with-two-bindings
metabase.api.common.internal-test/with-jetty-server hooks.common/with-one-binding
metabase.api.macros/defendpoint hooks.metabase.api.macros/defendpoint
metabase.app-db.schema-migrations-test.impl/test-migrations hooks.metabase.app-db.schema-migrations-test.impl/test-migrations
@@ -621,10 +624,11 @@
metabase.test/with-non-admin-groups-no-root-collection-perms hooks.common/do*
metabase.test/with-persistence-enabled! hooks.metabase.model-persistence.test-util/with-persistence-enabled!
metabase.test/with-prometheus-system! hooks.common/with-two-bindings
metabase.test/with-random-premium-token! hooks.common/with-one-binding
metabase.test/with-temp hooks.toucan2.tools.with-temp/with-temp
metabase.test/with-temp-file hooks.metabase.test.util/with-temp-file
metabase.test/with-temporary-setting-values hooks.metabase.test.util/with-temporary-setting-values
metabase.users.api-test/with-temp-user-email! hooks.common/with-one-binding
metabase.users.api-test/with-temp-user-email! hooks.common/with-one-binding
metabase.util.i18n/deferred-trs hooks.metabase.util.i18n/deferred-trs
metabase.util.i18n/deferred-tru hooks.metabase.util.i18n/deferred-tru
metabase.util.i18n/trs hooks.metabase.util.i18n/trs
@@ -713,13 +717,18 @@
{:pattern "^metabase\\.lib\\..*"
:name metabase-lib-excluding-legacy-mbql}
;;
;; QP source namespaces: `metabase.query-processor.*`, `metabase-enterprise.sandbox.query-processor.*`, and
;; `metabase.driver.*`, excluding `-test` namespaces.
;; QP and driver source namespaces: `metabase.query-processor.*`, `metabase-enterprise.sandbox.query-processor.*`,
;; and `metabase.driver.*`, excluding `-test` namespaces.
;;
{:pattern "metabase(?:(?:(?:-enterprise\\.sandbox)?\\.query-processor\\.)|(?:\\.driver\\.)).*(?<!-test)$"
:name qp-and-driver-source-namespaces}
;;
;; driver namespaces
;; QP source namespaces
;;
{:pattern "metabase(?:(?:-enterprise\\.sandbox)?\\.query-processor\\.).*(?<!-test)$"
:name qp-source-namespaces}
;;
;; driver namespaces, including tests
;;
{:pattern "metabase\\.driver.*$"
:name driver-namespaces}
@@ -779,7 +788,7 @@
clojure.string/lower-case {:level :off}
clojure.string/upper-case {:level :off}}}}
;; enable all the extra linters we haven't enabled in the core app yet in MLv2. It's all new code so we can adhere
;; enable all the extra linters we haven't enabled in the core app yet in Lib. It's all new code so we can adhere
;; to the new stricter rules from day 1
metabase-lib
{:linters
@@ -799,19 +808,25 @@
metabase.test/with-temp {:message "Don't use application database inside Lib code"}}
:discouraged-namespace
{metabase.driver {:message "MLv2 code should be independent of driver code/methods"}
metabase.test {:message "MLv2 tests should only use MLv2 test helpers"}
metabase.test.data {:message "MLv2 tests should only use MLv2 test helpers"}
metabase.util.malli.schema {:message "Prefer metabase.lib.schema schemas in MLv2 code"}
toucan.db {:message "Don't use application database inside MLv2 code"}
toucan.models {:message "Don't use application database inside MLv2 code"}
toucan.util.test {:message "Don't use application database inside MLv2 code"}
toucan2.core {:message "Don't use application database inside MLv2 code"}}}}
{metabase.driver {:message "Lib code should be independent of driver code/methods"}
metabase.test {:message "Lib tests should only use Lib test helpers"}
metabase.test.data {:message "Lib tests should only use Lib test helpers"}
metabase.util.malli.schema {:message "Prefer metabase.lib.schema schemas in Lib code"}
toucan.db {:message "Don't use application database inside Lib code"}
toucan.models {:message "Don't use application database inside Lib code"}
toucan.util.test {:message "Don't use application database inside Lib code"}
toucan2.core {:message "Don't use application database inside Lib code"}}}}
metabase-lib-excluding-legacy-mbql
{:linters
{:discouraged-var
{metabase.legacy-mbql.util/unique-name-generator {:message "Use metabase.lib.util/unique-name-generator or non-truncating-unique-name-generator"}}}}
{metabase.legacy-mbql.util/unique-name-generator {:message "Use metabase.lib.util/unique-name-generator or non-truncating-unique-name-generator"}}}
:discouraged-namespace
{metabase.legacy-mbql.js {:message "Avoid legacy MBQL utils in Lib; move things into Lib if needded."}
metabase.legacy-mbql.jvm-util {:message "Avoid legacy MBQL utils in Lib; move things into Lib if needded."}
metabase.legacy-mbql.predicates {:message "Avoid legacy MBQL utils in Lib; move things into Lib if needded."}
metabase.legacy-mbql.util {:message "Avoid legacy MBQL utils in Lib; move things into Lib if needded."}}}
driver-namespaces
{:linters
@@ -821,26 +836,47 @@
performance-sensitive
{:linters
{:discouraged-var
{clojure.core/update-keys {:message "Use metabase.util.performance/update-keys"}}}}
{clojure.core/every? {:message "Use metabase.util.performance/every?"}
clojure.core/mapv {:message "Use metabase.util.performance/mapv"}
clojure.core/run! {:message "Use metabase.util.performance/run!"}
clojure.core/select-keys {:message "Use metabase.util.performance/select-keys"}
clojure.core/some {:message "Use metabase.util.performance/some"}
clojure.core/update-keys {:message "Use metabase.util.performance/update-keys"}
clojure.walk/keywordize-keys {:message "Use metabase.util.performance/keywordize-keys"}
clojure.walk/postwalk {:message "Use metabase.util.performance/postwalk"}
clojure.walk/prewalk {:message "Use metabase.util.performance/prewalk"}
clojure.walk/walk {:message "Use metabase.util.performance/walk"}}}}
qp-and-driver-source-namespaces
{:linters
{:discouraged-namespace
{metabase.query-processor.store {:level :off}
metabase.util.malli.schema {:message "Prefer metabase.lib.schema or metabase.legacy-mbql.schema schemas in QP/driver code"}
toucan.db {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
toucan.models {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
toucan.util.test {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
toucan2.core {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}}
toucan.db {:message "Don't use application database directly in QP code; use the MetadataProvider"}
toucan.models {:message "Don't use application database directly in QP code; use the MetadataProvider"}
toucan.util.test {:message "Don't use application database directly in QP code; use the MetadataProvider"}
toucan2.core {:message "Don't use application database directly in QP code; use the MetadataProvider"}}
:discouraged-var
{medley.core/map-keys {:message "Use metabase.util.performance/update-keys"}
medley.core/map-vals {:message "Use clojure.core/update-vals"}
metabase.app-db.core/query {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
metabase.app-db.core/reducible-query {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
metabase.app-db.core/query {:message "Don't use application database directly in QP code; use the MetadataProvider"}
metabase.app-db.core/reducible-query {:message "Don't use application database directly in QP code; use the MetadataProvider"}
metabase.lib.convert/->legacy-MBQL {:level :off}
metabase.lib.core/->legacy-MBQL {:level :off}}}}
qp-source-namespaces
{:linters
{:discouraged-namespace
{metabase.legacy-mbql.js {:message "Avoid legacy MBQL namespaces in the QP, use Lib instead"}
metabase.legacy-mbql.jvm-util {:message "Avoid legacy MBQL namespaces in the QP, use Lib instead"}
metabase.legacy-mbql.normalize {:message "Avoid legacy MBQL namespaces in the QP, use Lib instead"}
metabase.legacy-mbql.predicates {:message "Avoid legacy MBQL namespaces in the QP, use Lib instead"}
metabase.legacy-mbql.schema {:message "Avoid legacy MBQL namespaces in the QP, use Lib instead"}
metabase.legacy-mbql.schema.helpers {:message "Avoid legacy MBQL namespaces in the QP, use Lib instead"}
metabase.legacy-mbql.schema.macros {:message "Avoid legacy MBQL namespaces in the QP, use Lib instead"}
metabase.legacy-mbql.util {:message "Avoid legacy MBQL namespaces in the QP, use Lib instead"}}}}
general-qp-and-driver-test-namespaces
{:linters
{:discouraged-var

View File

@@ -428,6 +428,11 @@
:api #{metabase.database-routing.core}
:uses #{premium-features}}
dependencies
{:team "Querying"
:api #{metabase.premium-features.core}
:uses #{premium-features}}
driver
{:team "Drivers"
:api #{metabase.driver
@@ -502,6 +507,7 @@
metabase.embedding.init
metabase.embedding.jwt
metabase.embedding.settings
metabase.embedding.util
metabase.embedding.validation}
:uses #{analytics
api
@@ -516,6 +522,7 @@
public-sharing
queries
query-processor
request
server
settings
tiles
@@ -547,6 +554,18 @@
settings
util}}
glossary
{:team "Workflows"
:api #{metabase.glossary.api}
:uses #{api
models
util}}
graph
{:team "Querying"
:api #{metabase.graph.core}
:uses #{util}}
indexed-entities
{:team "UX West"
:api #{metabase.indexed-entities.api
@@ -716,6 +735,7 @@
metabase.native-query-snippets.core}
:uses #{api
collections
events
lib
models
permissions
@@ -885,6 +905,19 @@
enterprise/advanced-permissions
enterprise/sandbox}}
python-runner
{:team "Workflows"
:api #{metabase.python-runner.api
metabase.python-runner.core
metabase.python-runner.init}
:uses #{api
driver
models
query-processor
request
util
enterprise/transforms}}
queries
{:team "Querying"
:api #{metabase.queries.api
@@ -930,6 +963,7 @@
:uses #{api
legacy-mbql
lib
lib-be
models
permissions
query-processor
@@ -1012,6 +1046,7 @@
metabase.request.schema}
:uses #{api
config
embedding
permissions ; FIXME
session
settings
@@ -1217,6 +1252,7 @@
events
lib
models
premium-features
query-processor
settings
task
@@ -1325,9 +1361,11 @@
users
{:team "UX West"
:api #{metabase.users.api
metabase.users.core
metabase.users.init
metabase.users.models.user
metabase.users.models.user-parameter-value}
metabase.users.models.user-parameter-value
metabase.users.schema}
:uses #{analytics
api
appearance
@@ -1462,6 +1500,7 @@
driver
legacy-mbql
lib
lib-be
models
queries
query-permissions
@@ -1612,6 +1651,18 @@
util
enterprise/harbormaster}}
enterprise/comments
{:team "Workflows"
:api #{metabase-enterprise.comments.api
metabase-enterprise.comments.init}
:uses #{api
channel
events
models
request
users
util}}
enterprise/content-translation
{:team "UX West"
:api #{metabase-enterprise.content-translation.dictionary
@@ -1678,6 +1729,29 @@
warehouse-schema
warehouses}}
enterprise/dependencies
{:team "Querying"
:api #{metabase-enterprise.dependencies.api
metabase-enterprise.dependencies.core
metabase-enterprise.dependencies.init}
:uses #{analyze
api
app-db
collections
config
driver
events
graph
lib
lib-be
models
native-query-snippets
premium-features
queries
query-processor
task
util}}
enterprise/documents
{:team "UX West"
:api #{metabase-enterprise.documents.api
@@ -1710,6 +1784,17 @@
settings
util}}
enterprise/embedding-hub
{:team "Embedding"
:api #{metabase-enterprise.embedding-hub.api}
:uses #{api
appearance
audit-app
embedding
premium-features
util
enterprise/sso}}
enterprise/gsheets
{:team "Cloud"
:api #{metabase-enterprise.gsheets.api
@@ -1782,10 +1867,13 @@
pulse
query-processor
request
search
server
settings
store-api
sync
system
task
users
util
warehouse-schema
@@ -1946,8 +2034,11 @@
{:team "Querying"
:api #{metabase-enterprise.transforms.api
metabase-enterprise.transforms.core
metabase-enterprise.transforms.init}
:uses #{api
metabase-enterprise.transforms.init
metabase-enterprise.transforms.instrumentation
metabase-enterprise.transforms.util}
:uses #{analytics
api
app-db
config
driver
@@ -1963,7 +2054,25 @@
sync
task
task-history
util}}
upload
util
enterprise/transforms-python}}
enterprise/transforms-python
{:team "Querying"
:api #{metabase-enterprise.transforms-python.api
metabase-enterprise.transforms-python.execute
metabase-enterprise.transforms-python.init
metabase-enterprise.transforms-python.settings}
:uses #{api
app-db
config
driver
models
query-processor
settings
util
enterprise/transforms}}
enterprise/upload-management
{:team "UX West"

View File

@@ -13,7 +13,10 @@
toucan2.core/insert-returning-pk!
toucan2.core/insert-returning-pks!
clojure.core.async/<!!
clojure.core.async/<!
clojure.core.async/>!!
clojure.core.async/>!
clojure.core.async/alts!
clojure.core.async/alts!!
clojure.core.async/close!
clojure.core.async/poll!

View File

@@ -232,7 +232,6 @@
metabase.test.data/$ids [[:inner 0]]
metabase.test.data/dataset [[:inner 0]]
metabase.test.data/mbql-query [[:inner 0]]
metabase.test.data/native-query [[:block 0]]
metabase.test.data/query [[:block 1]]
metabase.test.data/run-mbql-query [[:inner 0]]
metabase.test.data/with-empty-h2-app-db! [[:block 0]]
@@ -253,7 +252,6 @@
metabase.test/format-rows-by [[:default]]
metabase.test/let-url [[:block 1]]
metabase.test/mbql-query [[:inner 0]]
metabase.test/native-query [[:block 0]]
metabase.test/query [[:block 1]]
metabase.test/run-mbql-query [[:inner 0]]
metabase.test/test-driver [[:inner 0]]

View File

@@ -3,7 +3,7 @@
> **Warning**
>
> If that is your first contribution to Metabase, please sign the [Contributor License Agreement](https://docs.google.com/a/metabase.com/forms/d/1oV38o7b9ONFSwuzwmERRMi9SYrhYeOrkbmNaq9pOJ_E/viewform) (unless it's a tiny documentation change). Also, if you're attempting to fix a translation issue, please submit your changes to our [Crowdin project](https://crowdin.com/project/metabase-i18n) instead of opening a PR.
> If that is your first contribution to Metabase, please sign the [Contributor License Agreement](https://docs.google.com/a/metabase.com/forms/d/1oV38o7b9ONFSwuzwmERRMi9SYrhYeOrkbmNaq9pOJ_E/viewform). Also, if you're attempting to fix a translation issue, please submit your changes to our [Crowdin project](https://crowdin.com/project/metabase-i18n) instead of opening a PR.
Closes https://github.com/metabase/metabase/issues/[issue_number]

View File

@@ -0,0 +1,36 @@
name: Cleanup Python Runner
description: Cleanup python-runner services and upload logs as artifacts
inputs:
upload-logs:
description: 'Whether to upload logs (typically on failure)'
required: false
default: 'false'
logs-artifact-suffix:
description: 'The unique name of the .zip artifact containing the logs'
required: false
default: ''
runs:
using: composite
steps:
- name: Cleanup python-runner services
if: always()
run: |
echo "Stopping python-runner services..."
if [ -d "python-runner" ]; then
cd python-runner
make stop || echo "WARNING: Failed to stop python runner"
fi
shell: bash
- name: Upload python-runner logs
if: ${{inputs.upload-logs == 'true' && inputs.logs-artifact-suffix != ''}}
uses: actions/upload-artifact@v4
with:
name: python-runner-logs-${{inputs.logs-artifact-suffix}}
path: |
python-runner.out.log
python-runner.err.log
retention-days: 1
if-no-files-found: warn

View File

@@ -74,7 +74,7 @@ runs:
git push -u origin ${BACKPORT_BRANCH}
BACKPORT_PR_URL=$(gh pr create --base "${TARGET_BRANCH}" --head "${BACKPORT_BRANCH}" --label "was-backported" --assignee "${GITHUB_ACTOR}" --title "🤖 backported \"${ORIGINAL_TITLE}\"" --body "${PR_BODY}")
BACKPORT_PR_URL=$(gh pr create --base "${TARGET_BRANCH}" --head "${BACKPORT_BRANCH}" --label "was-backported" --assignee "${{ github.event.pull_request.user.login }}" --title "🤖 backported \"${ORIGINAL_TITLE}\"" --body "${PR_BODY}")
BACKPORT_PR_NUMBER=${BACKPORT_PR_URL##*/}
echo "backport_pr_number=$BACKPORT_PR_NUMBER" >> $GITHUB_OUTPUT

View File

@@ -0,0 +1,27 @@
name: Setup Python Runner
description: Setup python-runner for tests
inputs:
metabase-automation-token:
description: Token for accessing the python-runner repository
required: true
python-runner-version:
description: Git tag or commit of the python-runner repository to checkout
required: false
default: 'v0.0.1'
runs:
using: composite
steps:
- name: Clone and setup python-runner
run: |
echo "Cloning python-runner repository..."
git clone --depth 1 --branch ${{ inputs.python-runner-version }} \
https://${{ inputs.metabase-automation-token }}@github.com/metabase/python-runner-container.git python-runner
echo "Starting python-runner..."
cd python-runner
make run-ci 1> ../python-runner.out.log 2> ../python-runner.err.log
make logs 1>> ../python-runner.out.log 2>> ../python-runner.err.log &
cd ..
shell: bash
env:
METABASE_AUTOMATION_USER_TOKEN: ${{ inputs.metabase-automation-token }}

172
.github/scripts/average-e2e-timings.js vendored Normal file
View File

@@ -0,0 +1,172 @@
const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
const collectAndAverageTimings = async ({
github,
context,
daysBack = 7,
existingTimingsPath = "e2e/support/timings.json",
}) => {
try {
const artifacts = await findMergedTimingArtifacts({
github,
context,
daysBack,
});
if (artifacts.length === 0) {
throw new Error("No timing artifacts found in the specified time range");
}
const timingData = await downloadAndExtractArtifacts(
artifacts,
token,
github,
context,
);
if (timingData.length === 0) {
throw new Error("No valid timing data extracted from artifacts");
}
const averagedTimings = averageTimings(timingData);
averagedTimings.durations.sort((a, b) => a.spec.localeCompare(b.spec));
fs.writeFileSync(
existingTimingsPath,
JSON.stringify(averagedTimings, null, 2),
);
console.log(`✅ Updated ${existingTimingsPath} with new timing data`);
return { artifactCount: timingData.length };
} catch (error) {
console.error("❌ Error in collectAndAverageTimings:", error.message);
throw error;
}
};
const findMergedTimingArtifacts = async ({ github, context, daysBack }) => {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - daysBack);
console.log(
`Searching for merged timing artifacts created after ${cutoffDate.toISOString()}`,
);
const artifacts = [];
let page = 1;
while (true) {
try {
const { data } = await github.rest.actions.listArtifactsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
name: "merged-e2e-timings",
per_page: 100,
page,
});
const validArtifacts = data.artifacts
.filter((a) => new Date(a.created_at) > cutoffDate && !a.expired)
.map(({ name, created_at, id }) => ({ name, created_at, id }));
artifacts.push(...validArtifacts);
if (
data.artifacts.some((a) => new Date(a.created_at) <= cutoffDate) ||
data.artifacts.length < 100
) {
break;
}
page++;
} catch (error) {
console.log(
`Error fetching artifacts page ${page - 1}: ${error.message}`,
);
break;
}
}
console.log(`Found ${artifacts.length} merged timing artifacts total`);
return artifacts;
};
const downloadAndExtractArtifacts = async (artifacts, github, context) => {
const tempDir = "timing-artifacts-temp";
fs.mkdirSync(tempDir, { recursive: true });
const timingData = [];
for (const artifact of artifacts) {
try {
console.log(`Downloading artifact: ${artifact.name}`);
const zipPath = path.join(tempDir, `${artifact.name}.zip`);
const extractPath = path.join(tempDir, artifact.name);
const { data } = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: artifact.id,
archive_format: "zip",
});
fs.writeFileSync(zipPath, Buffer.from(data));
fs.mkdirSync(extractPath, { recursive: true });
execSync(`unzip -q "${zipPath}" -d "${extractPath}"`);
const timingFilePath = path.join(extractPath, "runTimings.json");
if (fs.existsSync(timingFilePath)) {
const content = JSON.parse(fs.readFileSync(timingFilePath, "utf8"));
if (content.durations?.length) {
timingData.push(content);
console.log(
`✅ Extracted timing data from ${artifact.name} (${content.durations.length} specs)`,
);
} else {
console.log(`⚠ Invalid timing data structure in ${artifact.name}`);
}
} else {
console.log(`⚠ No timing data found in ${artifact.name}`);
}
fs.rmSync(extractPath, { recursive: true });
} catch (error) {
console.log(`❌ Error processing ${artifact.name}: ${error.message}`);
}
}
fs.rmSync(tempDir, { recursive: true });
console.log(
`Successfully extracted timing data from ${timingData.length}/${artifacts.length} artifacts`,
);
return timingData;
};
const averageTimings = (timingDataArray) => {
if (!timingDataArray.length) {
throw new Error("No timing data to process");
}
const specTimings = timingDataArray
.flatMap((data) => data.durations)
.filter((item) => item.spec && typeof item.duration === "number")
.reduce((acc, { spec, duration }) => {
(acc[spec] = acc[spec] || []).push(duration);
return acc;
}, {});
const durations = Object.entries(specTimings).map(([spec, durations]) => ({
spec,
duration: Math.round(
durations.reduce((sum, d) => sum + d, 0) / durations.length,
),
}));
return { durations };
};
module.exports = { collectAndAverageTimings, averageTimings };

View File

@@ -0,0 +1,132 @@
const { averageTimings } = require("./average-e2e-timings");
describe("averageTimings", () => {
it("should throw error when given empty array", () => {
expect(() => averageTimings([])).toThrow("No timing data to process");
});
it("should work for n=1", () => {
const input = [
{
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
},
];
const result = averageTimings(input);
expect(result.durations).toHaveLength(2);
expect(result.durations).toContainEqual({
spec: "test1.cy.js",
duration: 1000,
});
expect(result.durations).toContainEqual({
spec: "test2.cy.js",
duration: 2000,
});
});
it("should calculate average for multiple specs", () => {
const input = [
{
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
},
{
durations: [
{ spec: "test1.cy.js", duration: 2000 },
{ spec: "test2.cy.js", duration: 4000 },
],
},
];
const result = averageTimings(input);
expect(result.durations).toHaveLength(2);
expect(result.durations).toContainEqual({
spec: "test1.cy.js",
duration: 1500,
});
expect(result.durations).toContainEqual({
spec: "test2.cy.js",
duration: 3000,
});
});
it("should round averages to nearest integer", () => {
const input = [
{
durations: [{ spec: "test1.cy.js", duration: 1001 }],
},
{
durations: [{ spec: "test1.cy.js", duration: 1002 }],
},
];
const result = averageTimings(input);
expect(result.durations[0].duration).toBe(1002);
});
it("should ignore invalid entries", () => {
const input = [
{
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: "invalid" },
{ duration: 2000 }, // missing spec
{ spec: "test3.cy.js", duration: 3000 },
],
},
];
const result = averageTimings(input);
expect(result.durations).toHaveLength(2);
expect(result.durations).toContainEqual({
spec: "test1.cy.js",
duration: 1000,
});
expect(result.durations).toContainEqual({
spec: "test3.cy.js",
duration: 3000,
});
});
it("should handle merging different specs", () => {
const input = [
{
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
},
{
durations: [
{ spec: "test1.cy.js", duration: 3000 },
{ spec: "test3.cy.js", duration: 1000 },
],
},
];
const result = averageTimings(input);
expect(result.durations).toHaveLength(3);
expect(result.durations).toContainEqual({
spec: "test1.cy.js",
duration: 2000,
});
expect(result.durations).toContainEqual({
spec: "test2.cy.js",
duration: 2000,
});
expect(result.durations).toContainEqual({
spec: "test3.cy.js",
duration: 1000,
});
});
});

View File

@@ -0,0 +1,39 @@
const extractChangedTimings = ({ oldTimings, newTimings }) => {
const oldTimingMap =
oldTimings.durations?.reduce((map, item) => {
if (item.spec) {
map[item.spec] = item.duration;
}
return map;
}, {}) || {};
const changedDurations = newTimings.durations
.filter((item) => {
if (!item || !item.spec || typeof item.duration !== "number") {
return false;
}
const newSpec = convertPathFormat(item.spec);
const oldDuration = oldTimingMap[newSpec] || oldTimingMap[item.spec];
// Include if it's a new spec or the duration has changed
return oldDuration === undefined || oldDuration !== item.duration;
})
.map((item) => ({
spec: convertPathFormat(item.spec),
duration: item.duration,
}));
return {
changedTimings: { durations: changedDurations },
hasChanges: changedDurations.length > 0,
};
};
// Convert cypress-split path format to timings.json path format
// from "e2e/test/scenarios/..." to "../test/scenarios/..."
function convertPathFormat(specPath) {
return specPath.startsWith("e2e/test/")
? specPath.replace("e2e/test/", "../test/")
: specPath;
}
module.exports = { extractChangedTimings };

View File

@@ -0,0 +1,195 @@
const { extractChangedTimings } = require("./extract-changed-timings");
describe("extractChangedTimings", () => {
it("should return empty durations when no changes", () => {
const oldTimings = {
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
};
const newTimings = {
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
};
const result = extractChangedTimings({ oldTimings, newTimings });
expect(result.changedTimings.durations).toHaveLength(0);
expect(result.hasChanges).toBe(false);
});
it("should detect new specs", () => {
const oldTimings = {
durations: [{ spec: "test1.cy.js", duration: 1000 }],
};
const newTimings = {
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
};
const result = extractChangedTimings({ oldTimings, newTimings });
expect(result.changedTimings.durations).toHaveLength(1);
expect(result.changedTimings.durations[0]).toEqual({
spec: "test2.cy.js",
duration: 2000,
});
expect(result.hasChanges).toBe(true);
});
it("should detect duration changes", () => {
const oldTimings = {
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
};
const newTimings = {
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2200 },
],
};
const result = extractChangedTimings({ oldTimings, newTimings });
expect(result.changedTimings.durations).toHaveLength(1);
expect(result.changedTimings.durations[0]).toEqual({
spec: "test2.cy.js",
duration: 2200,
});
expect(result.hasChanges).toBe(true);
});
it("should handle missing old timings", () => {
const oldTimings = { durations: [] };
const newTimings = {
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
};
const result = extractChangedTimings({ oldTimings, newTimings });
// All timings should be considered "changed" since old timings is empty
expect(result.changedTimings.durations).toHaveLength(2);
expect(result.changedTimings.durations).toContainEqual({
spec: "test1.cy.js",
duration: 1000,
});
expect(result.changedTimings.durations).toContainEqual({
spec: "test2.cy.js",
duration: 2000,
});
expect(result.hasChanges).toBe(true);
});
it("should handle invalid timing entries", () => {
const oldTimings = {
durations: [{ spec: "test1.cy.js", duration: 1000 }],
};
const newTimings = {
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: "invalid" },
{ duration: 2000 }, // missing spec
{ spec: "test3.cy.js", duration: 3000 },
],
};
const result = extractChangedTimings({ oldTimings, newTimings });
// Only test3.cy.js should be included (new spec with valid data)
expect(result.changedTimings.durations).toHaveLength(1);
expect(result.changedTimings.durations[0]).toEqual({
spec: "test3.cy.js",
duration: 3000,
});
expect(result.hasChanges).toBe(true);
});
it("should handle timing data with different specs", () => {
const oldTimings = {
durations: [
{ spec: "test1.cy.js", duration: 1000 },
{ spec: "test2.cy.js", duration: 2000 },
],
};
const newTimings = {
durations: [
{ spec: "test1.cy.js", duration: 3000 },
{ spec: "test3.cy.js", duration: 1000 },
],
};
const result = extractChangedTimings({ oldTimings, newTimings });
expect(result.changedTimings.durations).toHaveLength(2);
expect(result.changedTimings.durations).toContainEqual({
spec: "test1.cy.js",
duration: 3000,
});
expect(result.changedTimings.durations).toContainEqual({
spec: "test3.cy.js",
duration: 1000,
});
expect(result.hasChanges).toBe(true);
});
it("should convert cypress-split paths to relative paths", () => {
const oldTimings = {
durations: [
{
spec: "../test/scenarios/dashboard/dashboard.cy.spec.js",
duration: 1000,
},
{
spec: "../test/scenarios/admin/databases.cy.spec.js",
duration: 2000,
},
],
};
const newTimings = {
durations: [
{
spec: "e2e/test/scenarios/dashboard/dashboard.cy.spec.js",
duration: 1200,
},
{
spec: "e2e/test/scenarios/admin/databases.cy.spec.js",
duration: 2000,
},
{
spec: "e2e/test/scenarios/collections/collections.cy.spec.js",
duration: 1500,
},
],
};
const result = extractChangedTimings({ oldTimings, newTimings });
expect(result.changedTimings.durations).toHaveLength(2);
expect(result.changedTimings.durations).toContainEqual({
spec: "../test/scenarios/dashboard/dashboard.cy.spec.js",
duration: 1200,
});
expect(result.changedTimings.durations).toContainEqual({
spec: "../test/scenarios/collections/collections.cy.spec.js",
duration: 1500,
});
expect(result.hasChanges).toBe(true);
});
});

30
.github/scripts/setup-python-runner.sh vendored Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
set -e
# Parse command line arguments
SKIP_START=false
while [[ $# -gt 0 ]]; do
case $1 in
--skip-start)
SKIP_START=true
shift
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--skip-start]"
exit 1
;;
esac
done
echo "Cloning python-runner repository..."
git clone --depth 1 https://${METABASE_AUTOMATION_USER_TOKEN}@github.com/metabase/python-runner-container.git python-runner
if [ "$SKIP_START" = false ]; then
echo "Starting python-runner..."
cd python-runner
make run-ci 1> ../python-runner.out.log 2> ../python-runner.err.log
make logs 1>> ../python-runner.out.log 2>> ../python-runner.err.log &
cd ..
fi

View File

@@ -35,21 +35,21 @@ jobs:
build-static-viz: false
test-args: >-
:only '"enterprise/backend/test"'
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
- name: EE App DB Tests (Part 1)
build-static-viz: true
test-args: >-
:only '"test"'
:partition/total 2
:partition/index 0
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
- name: EE App DB Tests (Part 2)
build-static-viz: true
test-args: >-
:only '"test"'
:partition/total 2
:partition/index 1
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
services:
mysql:
@@ -147,21 +147,21 @@ jobs:
build-static-viz: false
test-args: >-
:only '"enterprise/backend/test"'
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
- name: EE App DB Tests (Part 1)
build-static-viz: true
test-args: >-
:only '"test"'
:partition/total 2
:partition/index 0
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
- name: EE App DB Tests (Part 2)
build-static-viz: true
test-args: >-
:only '"test"'
:partition/total 2
:partition/index 1
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
services:
mysql:
@@ -259,11 +259,13 @@ jobs:
build-static-viz: false
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
exclude-tag: ':mb/transforms-python-test'
- name: Enterprise Tests
build-static-viz: false
test-args: >-
:only '"enterprise/backend/test"'
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
- name: EE App DB Tests (Part 1)
build-static-viz: true
test-args: >-
@@ -271,14 +273,14 @@ jobs:
:exclude-tags [:mb/driver-tests]
:partition/total 2
:partition/index 0
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
- name: EE App DB Tests (Part 2)
build-static-viz: true
test-args: >-
:only '"test"'
:partition/total 2
:partition/index 1
exclude-tag: ':mb/driver-tests'
exclude-tag: ':mb/driver-tests :mb/transforms-python-test'
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
env:
# Only run old migrations tests on pushes to master or release branches. All other branches should skip tests

View File

@@ -6,11 +6,19 @@ on:
jobs:
create-backport:
if: | # the PR must be merged and have a backport label
if:
| # the PR must have a backport label when it's merged, or be labeled with a backport label after merge
github.event.pull_request.merged == true && (
contains(github.event.pull_request.labels.*.name, 'backport') ||
contains(github.event.pull_request.labels.*.name, 'double-backport') ||
contains(github.event.pull_request.labels.*.name, 'triple-backport')
github.event.action == 'closed' && (
contains(github.event.pull_request.labels.*.name, 'backport') ||
contains(github.event.pull_request.labels.*.name, 'double-backport') ||
contains(github.event.pull_request.labels.*.name, 'triple-backport')
) ||
github.event.action == 'labeled' && (
github.event.label.name == 'backport' ||
github.event.label.name == 'double-backport' ||
github.event.label.name == 'triple-backport'
)
)
runs-on: ubuntu-latest
steps:

View File

@@ -689,25 +689,57 @@ jobs:
junit-name: 'be-tests-starburst-ee'
test-args: ":only ${{ inputs.test }} :times ${{ inputs.times }}"
# TODO(rileythomp, 2025-08-20): Re-enable vertica tests once the docker image is updated
# be-tests-vertica-ee:
# if: ${{ false && inputs.driver == 'Vertica' }}
# runs-on: ubuntu-22.04
# timeout-minutes: 90
# env:
# CI: 'true'
# DRIVERS: vertica
# services:
# vertica:
# image: vertica/vertica-ce:12.0.2-0
# ports:
# - "5433:5433"
# steps:
# - uses: actions/checkout@v4
# - name: Make plugins directory
# run: mkdir plugins
# - name: Test Vertica driver
# uses: ./.github/actions/test-driver
# with:
# junit-name: 'be-tests-vertica-ee'
# test-args: ":only ${{ inputs.test }} :times ${{ inputs.times }}"
login-to-ecr:
if: inputs.driver == 'Vertica'
runs-on: ubuntu-22.04
timeout-minutes: 15
permissions:
id-token: write
contents: read
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.CI_IAM_ROLE }}
role-session-name: GitHub_to_AWS_via_FederatedOIDC
aws-region: us-east-1
- name: Get ECR password
id: login-ecr
run: |
PASSWORD=$(aws ecr get-login-password --region us-east-1)
REGISTRY="$(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com"
echo "docker_username=AWS" >> $GITHUB_OUTPUT
echo "docker_password=$PASSWORD" >> $GITHUB_OUTPUT
echo "registry=$REGISTRY" >> $GITHUB_OUTPUT
outputs:
registry: ${{ steps.login-ecr.outputs.registry }}
docker_username: ${{ steps.login-ecr.outputs.docker_username }}
docker_password: ${{ steps.login-ecr.outputs.docker_password }}
be-tests-vertica-ee:
if: inputs.driver == 'Vertica'
runs-on: ubuntu-22.04
needs: login-to-ecr
timeout-minutes: 90
env:
CI: 'true'
DRIVERS: vertica
services:
vertica:
image: ${{ needs.login-to-ecr.outputs.registry }}/vertica-ce:25.3.0-0
ports:
- "5433:5433"
credentials:
username: ${{ needs.login-to-ecr.outputs.docker_username }}
password: ${{ needs.login-to-ecr.outputs.docker_password }}
steps:
- uses: actions/checkout@v4
- name: Make plugins directory
run: mkdir plugins
- name: Test Vertica driver
uses: ./.github/actions/test-driver
with:
junit-name: 'be-tests-vertica-ee'
test-args: ":only ${{ inputs.test }} :times ${{ inputs.times }}"

View File

@@ -6,6 +6,10 @@ on:
skip:
type: boolean
default: false
python-runner-version:
type: string
default: 'v0.0.1'
description: 'Git tag or commit of python-runner repository to use'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}-drivers
@@ -90,6 +94,7 @@ jobs:
junit-name: 'be-tests-athena-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -106,6 +111,19 @@ jobs:
if: ${{ !inputs.skip }}
runs-on: ubuntu-22.04
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
job:
- name: Driver Tests
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
# DS 2025-09-26 temporarily disabled while we diagnose flakes
# - name: Transforms Python Tests
# test-args: >-
# :only-tags [:mb/transforms-python-test]
# needs-python-runner: true
env:
CI: 'true'
DRIVERS: bigquery-cloud-sdk
@@ -116,15 +134,21 @@ jobs:
MB_BIGQUERY_TEST_REFRESH_TOKEN: ${{ secrets.MB_BIGQUERY_TEST_REFRESH_TOKEN }}
MB_BIGQUERY_CLOUD_SDK_TEST_SERVICE_ACCOUNT_JSON: ${{ secrets.MB_BIGQUERY_CLOUD_SDK_TEST_SERVICE_ACCOUNT_JSON }}
MB_BIGQUERY_CLOUD_SDK_TEST_SERVICE_ACCOUNT_JSON_ROUTING: ${{ secrets.MB_BIGQUERY_CLOUD_SDK_TEST_SERVICE_ACCOUNT_JSON_ROUTING }}
name: BigQuery
name: BigQuery ${{ matrix.job.name }}
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
if: ${{ matrix.job.needs-python-runner == true }}
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Test BigQuery Cloud SDK driver
id: test-driver
uses: ./.github/actions/test-driver
with:
junit-name: 'be-tests-bigquery-cloud-sdk-ee'
test-args: >-
:only-tags [:mb/driver-tests]
test-args: ${{ matrix.job.test-args }}
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -136,11 +160,29 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: ${{ always() && matrix.job.needs-python-runner == true }}
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
be-tests-clickhouse-ee:
if: ${{ !inputs.skip }}
runs-on: ubuntu-22.04
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
job:
- name: Driver Tests
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Transforms Python Tests
test-args: >-
:only-tags [:mb/transforms-python-test]
needs-python-runner: true
env:
CI: 'true'
DRIVERS: clickhouse
@@ -148,9 +190,15 @@ jobs:
MB_CLICKHOUSE_TEST_PORT: 8123
MB_CLICKHOUSE_TEST_OLD_PORT: 8124
MB_CLICKHOUSE_TEST_NGINX_PORT: 8127
name: Clickhouse
name: Clickhouse ${{ matrix.job.name }}
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
if: ${{ matrix.job.needs-python-runner == true }}
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Add ClickHouse TLS instance to /etc/hosts
run: |
sudo echo "127.0.0.1 server.clickhouseconnect.test" | sudo tee -a /etc/hosts
@@ -167,11 +215,11 @@ jobs:
clickhouse_cluster_node2
nginx
- name: Test Clickhouse driver
id: test-driver
uses: ./.github/actions/test-driver
with:
junit-name: 'be-tests-clickhouse-ee'
test-args: >-
:only-tags [:mb/driver-tests]
test-args: ${{ matrix.job.test-args }}
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -183,6 +231,12 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: ${{ always() && matrix.job.needs-python-runner == true }}
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
be-tests-druid-ee:
needs: determine-driver-skips
@@ -208,6 +262,7 @@ jobs:
junit-name: 'be-tests-druid-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -244,6 +299,7 @@ jobs:
junit-name: 'be-tests-druid-jdbc-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -280,6 +336,7 @@ jobs:
junit-name: 'be-tests-databricks-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -317,6 +374,7 @@ jobs:
junit-name: 'be-tests-databricks-multi-catalog-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -338,12 +396,19 @@ jobs:
name: H2
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Test H2 driver
id: test-driver
uses: ./.github/actions/test-driver
with:
junit-name: 'be-tests-h2'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -355,6 +420,12 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: always()
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
be-tests-mysql-mariadb:
if: ${{ !inputs.skip }}
@@ -388,6 +459,11 @@ jobs:
- name: Driver Tests
test-args: >-
:only-tags [:mb/driver-tests]
exclude-tag: ':mb/transforms-python-test'
- name: Transforms Python Tests
test-args: >-
:only-tags [:mb/transforms-python-test]
needs-python-runner: true
services:
mysql:
@@ -442,7 +518,14 @@ jobs:
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
if: ${{ matrix.job.needs-python-runner == true }}
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Test ${{ matrix.version.name }}
id: test-driver
uses: ./.github/actions/test-driver
with:
junit-name: ${{ matrix.version.junit-name }}
@@ -460,6 +543,12 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: always()
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
be-tests-mongo:
needs: determine-driver-skips
@@ -476,6 +565,15 @@ jobs:
- name: MongoDB Latest
junit-name: be-tests-mongo-latest-ee
image: mongo:latest
job:
- name: Driver Tests
test-args: >-
:exclude-tags '[:mongo-sharded-cluster-tests :mb/transforms-python-test]'
:only-tags [:mb/driver-tests]
- name: Transforms Python Tests
test-args: >-
:only-tags [:mb/transforms-python-test]
needs-python-runner: true
env:
CI: 'true'
DRIVERS: mongo
@@ -489,16 +587,21 @@ jobs:
env:
MONGO_INITDB_ROOT_USERNAME: metabase
MONGO_INITDB_ROOT_PASSWORD: metasample123
name: ${{ matrix.version.name }}
name: ${{ matrix.version.name }} ${{ matrix.job.name }}
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
if: ${{ matrix.job.needs-python-runner == true }}
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Test ${{ matrix.version.name }}
id: test-driver
uses: ./.github/actions/test-driver
with:
junit-name: ${{ matrix.version.junit-name }}
test-args: >-
:exclude-tags [:mongo-sharded-cluster-tests]
:only-tags [:mb/driver-tests]
test-args: ${{ matrix.job.test-args }}
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -510,6 +613,12 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: ${{ always() && matrix.job.needs-python-runner == true }}
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
be-tests-mongo-ssl:
needs: determine-driver-skips
@@ -562,7 +671,7 @@ jobs:
with:
junit-name: ${{ matrix.version.junit-name }}
test-args: >-
:exclude-tags [:mongo-sharded-cluster-tests]
:exclude-tags '[:mongo-sharded-cluster-tests :mb/transforms-python-test]'
:only-tags [:mb/driver-tests]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
@@ -670,6 +779,7 @@ jobs:
junit-name: ${{ matrix.version.junit-name }}
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -704,6 +814,11 @@ jobs:
- name: Driver Tests
test-args: >-
:only-tags [:mb/driver-tests]
exclude-tag: ':mb/transforms-python-test'
- name: Transforms Python Tests
test-args: >-
:only-tags [:mb/transforms-python-test]
needs-python-runner: true
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
env:
# Only run old migrations tests on pushes to master or release branches. All other branches should skip tests
@@ -745,7 +860,14 @@ jobs:
POSTGRES_HOST_AUTH_METHOD: trust
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
if: ${{ matrix.job.needs-python-runner == true }}
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Test ${{ matrix.version.name }} (${{ matrix.job.name }})
id: test-driver
uses: ./.github/actions/test-driver
with:
junit-name: 'be-tests-${{ matrix.version.junit-name }}'
@@ -763,6 +885,12 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: always()
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
be-tests-presto-jdbc-ee:
needs: determine-driver-skips
@@ -821,6 +949,7 @@ jobs:
junit-name: 'be-tests-presto-jdbc-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -850,8 +979,14 @@ jobs:
skip: false
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/upload-tests]
:exclude-tags '[:mb/upload-tests :mb/transforms-python-test]'
:fail-fast? true
- name: Redshift Transforms Python Tests
skip: false
test-args: >-
:only-tags [:mb/transforms-python-test]
:fail-fast? true
needs-python-runner: true
env:
CI: 'true'
@@ -864,7 +999,14 @@ jobs:
name: ${{ matrix.job.name }}
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
if: ${{ matrix.job.needs-python-runner == true }}
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Test ${{ matrix.job.name }}
id: test-driver
if: ${{ !matrix.job.skip }}
uses: ./.github/actions/test-driver
with:
@@ -882,11 +1024,30 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: ${{ always() && matrix.job.needs-python-runner == true }}
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
be-tests-snowflake-ee:
if: ${{ !inputs.skip }}
runs-on: ubuntu-22.04
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
job:
- name: Driver Tests
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
# DS 2025-09-26 temporarily disabled while we diagnose flakes
# - name: Transforms Python Tests
# test-args: >-
# :only-tags [:mb/transforms-python-test]
# needs-python-runner: true
env:
CI: 'true'
DRIVERS: snowflake
@@ -905,15 +1066,21 @@ jobs:
MB_SNOWFLAKE_TEST_RSA_ROLE_TEST_CUSTOM_USER: RSA_ROLE_TEST_CUSTOM_USER
MB_SNOWFLAKE_TEST_RSA_ROLE_TEST_ROLE: RSA_ROLE_TEST_ROLE
MB_SNOWFLAKE_TEST_RSA_ROLE_TEST_DB: RSA_ROLE_TEST_DB
name: Snowflake
name: Snowflake ${{ matrix.job.name }}
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
if: ${{ matrix.job.needs-python-runner == true }}
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Test Snowflake driver
id: test-driver
uses: ./.github/actions/test-driver
with:
junit-name: 'be-tests-snowflake-ee'
test-args: >-
:only-tags [:mb/driver-tests]
test-args: ${{ matrix.job.test-args }}
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -925,6 +1092,12 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: ${{ always() && matrix.job.needs-python-runner == true }}
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
be-tests-sparksql-ee:
needs: determine-driver-skips
@@ -948,6 +1121,7 @@ jobs:
junit-name: 'be-tests-sparksql-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -977,6 +1151,7 @@ jobs:
junit-name: 'be-tests-sqlite-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -1004,6 +1179,15 @@ jobs:
- name: SQL Server 2022
junit-name: be-tests-sqlserver-2022-ee
image: mcr.microsoft.com/mssql/server:2022-latest
job:
- name: Driver Tests
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Transforms Python Tests
test-args: >-
:only-tags [:mb/transforms-python-test]
needs-python-runner: true
env:
CI: 'true'
DRIVERS: sqlserver
@@ -1019,15 +1203,21 @@ jobs:
ACCEPT_EULA: Y
SA_PASSWORD: 'P@ssw0rd'
MSSQL_MEMORY_LIMIT_MB: 1024
name: ${{ matrix.version.name }}
name: ${{ matrix.version.name }} ${{ matrix.job.name }}
steps:
- uses: actions/checkout@v4
- name: Setup python-runner
if: ${{ matrix.job.needs-python-runner == true }}
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Test ${{ matrix.version.name }}
id: test-driver
uses: ./.github/actions/test-driver
with:
junit-name: ${{ matrix.version.junit-name }}
test-args: >-
:only-tags [:mb/driver-tests]
test-args: ${{ matrix.job.test-args }}
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
@@ -1039,6 +1229,12 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
- name: Cleanup python-runner
if: ${{ always() && matrix.job.needs-python-runner == true }}
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: ${{ steps.test-driver.outcome == 'failure' }}
logs-artifact-suffix: ${{ matrix.job.name }} ${{ matrix.version.name }}
# TODO(dpsutton, 2025-08-20): Re-enable starburst when we figure out why it randomly dies in CI
# be-tests-starburst-ee:
@@ -1079,42 +1275,75 @@ jobs:
# aws-region: ${{ vars.AWS_REGION }}
# trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
# TODO(rileythomp, 2025-08-20): Re-enable vertica tests once the docker image is updated
# be-tests-vertica-ee:
# needs: determine-driver-skips
# if: ${{ false && !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
# runs-on: ubuntu-22.04
# timeout-minutes: 60
# env:
# CI: 'true'
# DRIVERS: vertica
# services:
# vertica:
# image: vertica/vertica-ce:12.0.2-0
# ports:
# - "5433:5433"
# name: Vertica
# steps:
# - uses: actions/checkout@v4
# - name: Make plugins directory
# run: mkdir plugins
# - name: Test Vertica driver
# uses: ./.github/actions/test-driver
# with:
# junit-name: 'be-tests-vertica-ee'
# test-args: >-
# :only-tags [:mb/driver-tests]
# - name: Upload Test Results
# uses: ./.github/actions/upload-test-results
# if: always()
# with:
# input-path: ./target/junit/
# output-name: ${{ github.job }}
# bucket: ${{ vars.AWS_S3_TEST_RESULTS_BUCKET }}
# aws-access-key-id: ${{ secrets.AWS_TEST_RESULTS_ACCESS_KEY_ID }}
# aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
# aws-region: ${{ vars.AWS_REGION }}
# trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
login-to-ecr:
needs: determine-driver-skips
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
runs-on: ubuntu-22.04
timeout-minutes: 15
permissions:
id-token: write
contents: read
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.CI_IAM_ROLE }}
role-session-name: GitHub_to_AWS_via_FederatedOIDC
aws-region: us-east-1
- name: Get ECR password
id: login-ecr
run: |
PASSWORD=$(aws ecr get-login-password --region us-east-1)
REGISTRY="$(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com"
echo "docker_username=AWS" >> $GITHUB_OUTPUT
echo "docker_password=$PASSWORD" >> $GITHUB_OUTPUT
echo "registry=$REGISTRY" >> $GITHUB_OUTPUT
outputs:
registry: ${{ steps.login-ecr.outputs.registry }}
docker_username: ${{ steps.login-ecr.outputs.docker_username }}
docker_password: ${{ steps.login-ecr.outputs.docker_password }}
be-tests-vertica-ee:
needs: [determine-driver-skips, login-to-ecr]
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
runs-on: ubuntu-22.04
timeout-minutes: 60
env:
CI: 'true'
DRIVERS: vertica
services:
vertica:
image: ${{ needs.login-to-ecr.outputs.registry }}/vertica-ce:25.3.0-0
ports:
- "5433:5433"
credentials:
username: ${{ needs.login-to-ecr.outputs.docker_username }}
password: ${{ needs.login-to-ecr.outputs.docker_password }}
name: Vertica
steps:
- uses: actions/checkout@v4
- name: Make plugins directory
run: mkdir plugins
- name: Test Vertica driver
uses: ./.github/actions/test-driver
with:
junit-name: 'be-tests-vertica-ee'
test-args: >-
:only-tags [:mb/driver-tests]
:exclude-tags [:mb/transforms-python-test]
- name: Upload Test Results
uses: ./.github/actions/upload-test-results
if: always()
with:
input-path: ./target/junit/
output-name: ${{ github.job }}
bucket: ${{ vars.AWS_S3_TEST_RESULTS_BUCKET }}
aws-access-key-id: ${{ secrets.AWS_TEST_RESULTS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
drivers-tests-result:
needs:

View File

@@ -28,6 +28,11 @@ on:
split_index: # index of the chunk
required: false
type: number
python-runner-version:
type: string
default: 'v0.0.1'
description: 'Git tag or commit of python-runner repository to use'
required: false
jobs:
e2e-tests:
@@ -60,6 +65,15 @@ jobs:
CYPRESS_IS_EMBEDDING_SDK: "${{ inputs.name == 'embedding-sdk' }}"
steps:
- uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
- name: Setup python-runner
uses: ./.github/actions/setup-python-runner
with:
metabase-automation-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
python-runner-version: ${{ inputs.python-runner-version }}
- name: Prepare Docker containers
uses: ./.github/actions/e2e-prepare-containers
@@ -123,7 +137,7 @@ jobs:
SPLIT_INDEX: ${{ inputs.split_index }}
SPLIT_FILE: "./e2e/support/timings.json"
SPLIT_OUTPUT_FILE: "newTimes.json"
SPLIT_TIME_THRESHOLD: 5.0
SPLIT_TIME_THRESHOLD: 0.01 # 1% threshold for changes
# do not write cypress-split summary to github
SPLIT_SUMMARY: false
SPEC_PATH: ${{ env.specs || inputs.specs }}
@@ -143,7 +157,7 @@ jobs:
run: |
echo "Running tests with specs: $SPEC_PATH"
node e2e/runner/run_cypress_ci.js e2e \
--env grepTags="${{inputs.tags}}+-@skip",grepOmitFiltered=true \
--env grepTags="${{inputs.tags && format('{0}+-@skip', inputs.tags) || '-@skip'}}",grepOmitFiltered=true \
--spec "$SPEC_PATH" \
--browser ${{ steps.cypress-prep.outputs.chrome-path }}
@@ -177,6 +191,51 @@ jobs:
name: failed-tests-${{ inputs.name }}-${{ inputs.edition }}
path: ./cypress/test-results
- name: Extract chunk-specific changed timings
id: extract-timings
if: inputs.split_index >= 0 && github.ref == 'refs/heads/master'
continue-on-error: true
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const oldTimingsPath = "./e2e/support/timings.json";
const newTimingsPath = "./e2e/support/newTimes.json";
if (!fs.existsSync(newTimingsPath)) {
throw new Error(`newTimes.json not found - cypress-split may not have generated it`);
}
if (!fs.existsSync(oldTimingsPath)) {
throw new Error(`Original timings file ${oldTimingsPath} not found`);
}
const oldTimings = fs.existsSync(oldTimingsPath)
? JSON.parse(fs.readFileSync(oldTimingsPath, "utf8"))
: { durations: [] };
const newTimings = fs.existsSync(newTimingsPath)
? JSON.parse(fs.readFileSync(newTimingsPath, "utf8"))
: { durations: [] };
const { extractChangedTimings } = require('${{ github.workspace }}/.github/scripts/extract-changed-timings.js');
const result = extractChangedTimings({ oldTimings, newTimings });
if (result.hasChanges) {
core.setOutput('has-changes', 'true');
fs.writeFileSync('chunkTimings.json', JSON.stringify(result.changedTimings, null, 2));
console.log(`Extracted ${Object.keys(result.changedTimings).length} changed timings for chunk index ${{ inputs.split_index }}`);
}
- name: Upload Timing Data
uses: actions/upload-artifact@v4
if: steps.extract-timings.outcome == 'success' && steps.extract-timings.outputs.has-changes == 'true'
with:
name: timing-data-${{ inputs.name }}-${{ inputs.split_index }}
path: chunkTimings.json
retention-days: 1 # gets merged immediately by parent workflow
- name: Publish Summary
if: failure()
uses: actions/github-script@v7
@@ -193,3 +252,9 @@ jobs:
const summary = formatSummary(results);
await core.summary.addRaw(summary).write();
- name: Cleanup python-runner
if: always()
uses: ./.github/actions/cleanup-python-runner
with:
upload-logs: false

View File

@@ -87,6 +87,67 @@ jobs:
name: Flaky
tags: "@flaky"
collect-timings:
name: Collect E2E Timings
runs-on: ubuntu-22.04
timeout-minutes: 10
needs: e2e-tests
if: always() && !cancelled() && github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: |
.github
e2e/support
sparse-checkout-cone-mode: false
- name: Download all timing artifacts
uses: actions/download-artifact@v4
with:
pattern: timing-data-*
path: timing-files
merge-multiple: false
continue-on-error: true
- name: Merge split timings
id: merge
continue-on-error: true
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
const chunkFiles = glob.sync('timing-files/*/chunkTimings.json');
const specs = new Map();
chunkFiles.forEach(file => {
const { durations = [] } = JSON.parse(fs.readFileSync(file, 'utf8'));
durations.forEach(({ spec, duration }) => specs.set(spec, duration));
});
if (specs.size === 0) {
throw new Error('No timing data found - no specs had timing changes');
}
const outputPath = 'e2e/support/runTimings.json';
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
const runTimings = {
durations: [...specs].map(([spec, duration]) => ({ spec, duration }))
};
fs.writeFileSync(outputPath, JSON.stringify(runTimings, null, 2));
console.log(`Merged timing data for ${specs.size} specs`);
- name: Upload merged timing files
if: steps.merge.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: merged-e2e-timings
path: e2e/support/runTimings.json
retention-days: 7
e2e-tests-result:
needs:
- e2e-tests

View File

@@ -26,26 +26,8 @@ jobs:
- name: Compile CLJS
run: yarn build-pure:cljs
- name: Build Storybook
# We won't be able to use Storybook play's `userEvent` with production build
# see https://github.com/storybookjs/storybook/issues/19758
run: NODE_ENV=development yarn build-storybook
- name: Serve Storybook
run: yarn http-server storybook-static -p 6006 &
shell: bash
- name: Wait for Storybook to become available
run: |
echo "Waiting for Storybook to be served..."
while ! curl --silent --fail http://localhost:6006; do
sleep 5
echo "Retrying..."
done
echo "Storybook is being served!"
- name: Update Loki Snapshots
run: yarn test-visual:loki || yarn test-visual:loki-approve-diff && yarn test-visual:loki-prune
run: yarn test-visual:loki:ci || yarn test-visual:loki-approve-diff && yarn test-visual:loki-prune
- name: Check for changes
id: check-changes

View File

@@ -53,14 +53,8 @@ jobs:
- name: Compile CLJS
run: NODE_ENV=development yarn build-pure:cljs
- name: Build Storybook
# We won't be able to use Storybook play's `userEvent` with production build
# see https://github.com/storybookjs/storybook/issues/19758
run: NODE_ENV=development yarn build-storybook
- name: Run Loki Visual Tests
run: |
yarn loki --requireReference --reactUri file:./storybook-static --chromeFlags='--headless --disable-gpu' --verboseRenderer
run: yarn test-visual:loki:ci
- name: Generate Visual Report on Failure
if: failure()

View File

@@ -8,6 +8,7 @@ on:
pull_request:
types: [opened, synchronize, reopened]
merge_group:
workflow_dispatch:
jobs:
files-changed:
@@ -74,7 +75,7 @@ jobs:
secrets: inherit
backend-tests:
if: ${{ !cancelled() }}
if: ${{ !cancelled() && needs.files-changed.result == 'success' }}
needs: [files-changed, static-viz-files-changed]
uses: ./.github/workflows/backend.yml
secrets: inherit
@@ -112,7 +113,7 @@ jobs:
e2e-tests:
needs: [files-changed, uberjar]
if: always() && !cancelled()
if: always() && !cancelled() && needs.files-changed.result == 'success'
uses: ./.github/workflows/e2e-tests.yml
secrets: inherit
with:

View File

@@ -0,0 +1,92 @@
name: Update E2E Timings
permissions:
contents: write
pull-requests: write
on:
workflow_dispatch:
inputs:
days_back:
description: "Number of days to look back for timing artifacts"
type: number
default: 7
required: false
schedule:
# Run weekly on Sundays at 6 AM UTC
- cron: "0 6 * * 0"
jobs:
collect-and-average-timings:
runs-on: ubuntu-22.04
timeout-minutes: 30
env:
DAYS_BACK: ${{ inputs.days_back || 7 }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Collect and average timing data
id: collect-timings
uses: actions/github-script@v7
with:
script: |
const { collectAndAverageTimings } = require('${{ github.workspace }}/.github/scripts/average-e2e-timings.js');
const result = await collectAndAverageTimings({
github,
context,
token: '${{ secrets.GITHUB_TOKEN }}',
daysBack: ${{ env.DAYS_BACK }},
existingTimingsPath: 'e2e/support/timings.json'
});
core.setOutput('artifact-count', result.artifactCount);
- name: Set up git configuration
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
BRANCH_NAME="update-e2e-timings-$(date +%Y%m%d-%H%M%S)"
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
echo "Branch name will be: $BRANCH_NAME"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ env.BRANCH_NAME }}
base: master
commit-message: |
Update E2E test timings with averaged data
Collected timing data from ${{ env.DAYS_BACK }} days of test runs.
All specs with timing data were included (simple averages).
🤖 Generated automatically by update-e2e-timings workflow
Co-Authored-By: GitHub Actions <actions@github.com>
committer: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
title: "[chore] Update E2E test timings with recent data"
body: |
## Summary
This PR updates the E2E test timing data with averaged values from recent test runs.
## Details
- Collected data from the last **${{ env.DAYS_BACK }} days** of test runs
- Averaged timing data from **${{ steps.collect-timings.outputs.artifact-count }}** test runs
## Generated automatically
🤖 This PR was created automatically by the `update-e2e-timings` workflow.
The timing data helps cypress-split optimize test distribution across parallel jobs.
Co-Authored-By: GitHub Actions <actions@github.com>
labels: |
.CI & Tests
add-paths: e2e/support/timings.json

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Some files were not shown because too many files have changed in this diff Show More