Compare commits

...

286 Commits

Author SHA1 Message Date
Jeff Bruemmer
caa9484148 update changelog links 2025-11-12 15:06:34 -05:00
Alex Yarosh
bef0a89f9f docs: dependencies polish (#65754)
* dependencies polish

* Optimized 2 images, saved 109.1 KB (48.5% smaller)

* reword

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
2025-11-12 18:06:15 +00:00
Ryan Laurie
63f2359659 upload checksums with releases (#65712) 2025-11-12 08:43:01 -07:00
Mahatthana (Kelvin) Nomsawadi
62fe686ffc Fix static embedding or public embed outside iframe not working with #theme (#65740)
* Fix static embedding or public embed outside iframe not working with #theme

* Add tests

* Make embedding prefix/suffix naming consistent
2025-11-12 15:29:45 +00:00
Mahatthana (Kelvin) Nomsawadi
8c5cac2369 Update the delete button copy for better UX (#65688)
* Update the delete button copy for better UX

* Apply suggestions from code review

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

---------

Co-authored-by: Phoomparin Mano <poom@metabase.com>
2025-11-12 12:53:27 +00:00
Sébastien
d514efc3c3 feat(sdk): Convert plugin system to deferred initialization (#65142)
* Convert plugin system to deferred initialization with undo capability

* fixed wrong rebase

* better initialization

* .

* fixed unit tests

* .

* duh

* added back whitelabel overrides for SDK

* fixup

* fixed unit test

* cleanup
2025-11-12 11:48:59 +01:00
Oleksandr Solovyov
f4c15ce5d7 unstemmed words should still appear in search (#64560)
This is done by putting them in the full-text index using a 'simple' stemmer, just with a lower priority than a normal
stemmed words are.

Fixes #60649
2025-11-12 12:38:47 +02:00
Fraser
1c649fb56f deps: Remove redux-promise and reduce-reducers (#64945) 2025-11-12 11:35:51 +01:00
Fraser
6d349fd1b2 Drop react-copy-to-clipboard (#65674) 2025-11-12 23:17:37 +13:00
Sébastien
5660df7a85 Closes UXW-2237 click on admin logo error (#65581) 2025-11-12 07:07:50 +01:00
Jeff Bruemmer
1951cfe3f7 add command documentation generation (#65727) 2025-11-11 18:00:31 -05:00
Jeff Bruemmer
ea03f4819b changelog link (#65717) 2025-11-11 16:20:51 -05:00
Brad Anderson
af548d9daa Fix: UXW-2235 Prevents 403s from SmartLinks from hiding the whole document (#65609)
* UXW-2235 Prevents 403s from SmartLinks from preventing the whole document from showing (SmartLink renders with "No access" version instead)

* UXW-2235 Adds e2e tests
2025-11-11 15:56:18 -05:00
Rodrigo López Dato
f568cc793b Add /livez and /readyz endpoints (#64479)
* Add /livez and /readyz endpoints

* nit comment

* Update tests with new endpoints

* Update src/metabase/server/routes.clj

Co-authored-by: metabase-bot[bot] <109303359+metabase-bot[bot]@users.noreply.github.com>

* bad bot

* fix tests

* fix license test failure

https://github.com/metabase/metabase/pull/65034 bumped some jetty deps
from 12.0.24 to 12.1.3. Along for the ride came a new org:

```
org.eclipse.jetty.ee9.websocket/jetty-ee9-websocket-jetty-server 12.1.3
  X org.eclipse.jetty.ee9/jetty-ee9-servlet 12.1.3 :use-top
  . org.eclipse.jetty.ee9/jetty-ee9-webapp 12.1.3
    . org.eclipse.jetty/jetty-xml 12.1.3
      . org.eclipse.jetty/jetty-util 12.1.3
      X org.slf4j/slf4j-api 2.0.17 :use-top
    . org.eclipse.jetty.ee/jetty-ee-webapp 12.1.3 <--- new
```

This has a new org of `org.eclipse.jetty.ee` and no discernable license
in the pom or the jar.

Refresher we look in the pom for things like

```
  <licenses>
    <license>
      <name>The Apache Software License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
```

or in the jar for some common names of licenses, like in this mysql
connector jar:

```
  -rw-r--r--     134  18-Sep-2023 19:11:56  INFO_SRC
  -rw-r--r--   71049  18-Sep-2023 19:11:56  LICENSE
  -rw-r--r--    1624  18-Sep-2023 19:11:56  README
  -rw-r--r--     846  18-Sep-2023 19:12:04  META-INF/INDEX.LIST
```

I didn't see a license at either of these spots, but consulted
https://mvnrepository.com/artifact/org.eclipse.jetty.ee/jetty-ee-webapp
to see it listed as Apache 2.0 and EPL 2.0

---------

Co-authored-by: metabase-bot[bot] <109303359+metabase-bot[bot]@users.noreply.github.com>
Co-authored-by: dan sutton <dan@dpsutton.com>
2025-11-11 16:55:08 -03:00
Ryan Laurie
0cfcfd561e fix auto patches again (#65708)
* fix auto patches again

* revert ??
2025-11-11 11:36:51 -07:00
Uladzimir Havenchyk
046df0694e chore: upgrade mantine/core patch to match installed version (#65340)
* chore: update mantine patch package

* fixup

* fixup

* fixup
2025-11-11 20:48:37 +03:00
Jeff Bruemmer
257f23f104 generate command docs (#65608)
* generate command dox

* clean-up

* restore command.md

* clean-up
2025-11-11 11:53:58 -05:00
Braden Shepherdson
f78cf1648f [perf] Improve quadratic lookups in add-alias-info (#65595)
Part of #64774.

Replaces quadratic (refs * columns) search in `add-alias-info` with map lookups
by ID and `:lib/source-column-alias`. They don't always succeed, but I ran the tests with a fallback case
that checked the old quadratic way too - in no case does the new match fail but the old way succeed.

- Speeds up the basic query of wide tables (see `qp.perf-test`) about 7x, from 8825ms to 1435ms.
- Reduces the big user query from #64774 from 205ms to 145ms on my machine.
2025-11-11 16:23:08 +00:00
Oleksandr Solovyov
559d3357a2 request cancelation: this time for real (#65660)
Transfer-Encoding: chunked will cause Apache HttpClient to wrap body in ContentLengthInputStream,
which, in turn, quote: "NEVER closes the underlying stream".

So 'with-open' closing the stream was never propagated. And the new test with transfer-encoding
header captures that.
2025-11-11 18:12:56 +02:00
Braden Shepherdson
9584d61b16 [perf] Remove unnecessary MBQL 4 -> 5 -> 4 round trips in SQL drivers (#65509)
Part of #64774.

Now that most of the query processor machinery has been ported to use MBQL 5 and the `metabase.lib.core`
functionality, there were several needless round trips between MBQL 4 and 5.

The `driver.sql.qp/preprocess` function was converting queries from MBQL 5 to 4 up front,
and then each of three inner operations (now implemented in MBQL 5) were wrapped to convert 4 to 5 and back.

Removing this wasted effort reduced the time on my machine for the big user query from #64774 from 205ms to 145ms.
2025-11-11 14:55:19 +00:00
Mahatthana (Kelvin) Nomsawadi
13e92995df Fix flaky 'models.cy.spec.js' test (#65690) 2025-11-11 14:52:48 +00:00
Edward Paget
a939c427ad docs: Update api changelog (#65663) 2025-11-11 08:47:51 -06:00
Nemanja Glumac
2b7980868d Fix encoding in "tag for release" workflow (#65689) 2025-11-11 11:17:19 +00:00
Chris Truter
3c92dcd071 Minor fixes around semantic search (#65654) 2025-11-11 11:36:24 +02:00
Fraser
e02de4a3bb Drop usage of cancelable and add unit tests (#65455) 2025-11-11 19:33:56 +13:00
Fraser
b5495dc6aa Refactor DeleteSubscriptionAction (#65575) 2025-11-11 15:35:50 +13:00
Fraser
e976b1af84 Drop clipboardy (#65675) 2025-11-11 12:05:51 +13:00
Riley Thompson
1a827eb9a0 Fix postgres bytea truncation (#65569)
* fix postgres bytea truncation

* use = over =?

* Add issue ref in test
2025-11-10 22:27:17 +00:00
Sloan Sparger
ecd803f067 [Metabot] Misc. bug fixes (#65255)
* fix cut not removing text from input

* ensure we fetch all data for all possible models for smart links

* remove unused comment

* fixes smart links in metabot input sometimes degrading into their text representation and fixes some cases where wrong model name ("model" instead of "dataset") was used for metabot links

* fix unit tests

* fix phantom selection when cutting value from input (context: https://github.com/metabase/metabase/pull/65255\#pullrequestreview-3436250849)
2025-11-10 14:57:58 -06:00
dpsutton
00ee60d8ed Cell count for notifications temp storage (#65518)
* ditch our manual batches of rows for bufferedwriter

Q: Why did we use a manual batch at first?
A: i noticed it was super slow and worked around this. Then realized i
was gzipping it so that was the actual slowdown. The batching was
already done and it didn't hurt anything.

Q: Why get rid of it then?
A: want to move to "cell" based counting. Rows are fine until they get
really wide and then 300 columns * 5,000 rows = 1,500,000 cells in
memory at once. Put some strings in there and we blow up. So lets switch
to cell counting rather than row counting. This is way easier if we only
care about number of rows or cells when holding them in memory. Don't
have to count the batch ourself when streaming. So if that goes row by
row, we just watch for the number of cells as the trigger to switch to
streaming and we are done.

```clojure
temp-storage-test=> (time
                      (mt/test-driver :postgres
                        (select-keys (mt/process-query (mt/native-query {:query "SELECT
    row_num AS id,
    -- Random Integer between 1 and 100000
    floor(random() * 100000 + 1)::INTEGER AS random_int,
    -- Random Float
    (random() * 1000)::NUMERIC(10, 4) AS random_float,
    -- Random Date within the last 5 years
    (current_date - (random() * 5 * 365)::INTEGER)::DATE AS random_date,
    -- Random Timestamp within the last 30 days
    (NOW() - (random() * 30 * '1 day'::interval)) AS random_timestamp,
    -- Random String: Generates a random alphanumeric string about 1000 characters long
    (
        SELECT string_agg(
            chr(
                (CASE WHEN random() < 0.5 THEN 65 ELSE 97 END) + (random() * 25)::INTEGER
            ),
            ''
        )
        FROM generate_series(1, 1000)
    ) AS random_string
FROM
    generate_series(1, 500000) AS row_num;"})
                                                       (temp-storage/notification-rff 2000 :testing))
                                     [:row_count :status :data.rows-file-size :notification/truncated?])))
"Elapsed time: 1457.921083 msecs"
{:row_count 15184,
 :status :completed,
 :data.rows-file-size 16369108,
 :notification/truncated? true}
```

* Switch to cell based counts, not rows

We found in practice some people might have queries with 300
columns. When we keep 5,000 of those in memory, we end up having
1,500,000 cells in memory at once. We then are open again to OOM
issues. So this swaps over to a cell basec count rather than rows to be
a bit more granular.

* Change from 2,000 rows to 20,000 cells

the thinking here is 2,000 rows with 10 values. It's pretty arbitrary though

* rename var for cells to disk threshold

* i have to delete this test because i used `time` in a comment block

* formatting fix
2025-11-10 13:59:26 -06:00
Fraser
a2a31bd9e3 Replace usages of deprecated useSafeAsyncFunction (#65406) 2025-11-11 08:44:29 +13:00
William
c1e548ca9e Remove-replace cleans up empty first stages when reasonable (#65565)
If you have an empty first stage followed by "real" later stages, the frontend produces duplicate buttons in the query
builder.  Cleaning those stages up removes those buttons.
2025-11-10 19:43:18 +00:00
github-automation-metabase
d32fb5f798 Bump com.nimbusds/nimbus-jose-jwt from 10.4.2 to 10.5 (#63228)
Inspect dependency changes here:

Co-authored-by: Cam Saul <1455846+camsaul@users.noreply.github.com>
2025-11-10 19:00:15 +00:00
github-automation-metabase
a8345c94f8 Bump com.github.seancorfield/honeysql from 2.7.1340 to 2.7.1350 (#63219)
Inspect dependency changes here: https://github.com/seancorfield/honeysql/blob/v2.7.1350/CHANGELOG.md

Co-authored-by: Cam Saul <1455846+camsaul@users.noreply.github.com>
2025-11-10 18:48:23 +00:00
Cam Saul
734949f267 BE modularization decoupling Halloween edition (#65236)
* BE modularization: decouple `server` from `core`

* Split up enterprise/api and enterprise/api-routes

* Split up `settings` and `settings-rest`

* Dox for new util

* Add another util function

* Split `permissions` and `permissions-rest`

* Code fixes and additional utils

* Improved deps graph dox
2025-11-10 10:04:36 -08:00
William
14d2f55fa2 Display "previous results" when a join's conditions specify multiple lhs tables (#65239)
When a join's conditions came from multiple tables, we used the first table as the table name, even though some of the cols came from a different table. We now display "Previous results" to denote that the lhs columns are from different tables.
2025-11-10 17:43:33 +00:00
Anderson
e8d760345b Include headers when copying table rows (#65439)
* Include headers when copying table rows

* Fix e2e test

* Fix headers and values out of order when when cells are selected backwards or individually
2025-11-10 13:25:34 -03:00
Ryan Laurie
d52732d113 Fix Collection Tree Collapsing (#65620)
* actually just be smart

* consistent change detection

* remove dead code
2025-11-10 07:56:45 -07:00
Edward Paget
fcacb480e0 fix: batch delete data perms (#65567)
* fix: batch delete data perms

To workaround postgresql parameter limits in the delete query

* Update src/metabase/permissions/models/data_permissions.clj

Co-authored-by: Chris Truter <crisptrutski@users.noreply.github.com>

* Update src/metabase/permissions/models/data_permissions.clj

Co-authored-by: Chris Truter <crisptrutski@users.noreply.github.com>

* Update data_permissions.clj

---------

Co-authored-by: Chris Truter <crisptrutski@users.noreply.github.com>
2025-11-10 14:50:20 +00:00
Timofey Kachalov
321d9266f2 Close New Modals when pathname is changing (#65472) 2025-11-10 18:27:04 +04:00
github-automation-metabase
4ff0d16f78 Update generated docs (master) (#65643)
Co-authored-by: github-actions <github-actions@github.com>
2025-11-10 09:16:56 -05:00
Timofey Kachalov
7a5a24a347 Adjust reviewers in sdk-release CI workflow (#65652) 2025-11-10 16:56:42 +04:00
Chris Truter
f506b2ce36 Simplify default search engine and active index logic (#65604) 2025-11-10 12:10:21 +00:00
Chris Truter
d7d4141e19 Support search weight overrides per request for tool calls (#65592) 2025-11-10 09:47:17 +00:00
Filipe Silva
d4bbf59cc0 fix: update harbormaster API use, and support public openapi schema (#65549)
* fix: update harbormaster API use

The Harbormaster API was updated to use snake_case in all params
and returns in https://github.com/metabase/harbormaster/pull/6663.

There's an backwards compatible interim period where it will support both kebab-case and snake_case in params, and keep existing returns.
The changes in this PR will make Metabase forwards and backwards compatible with the Harbormaster API changes.

After the interim period, the Harbormaster API will only take and return snake_case data.

* feat: support missing api key on hm.client/call

The OpenAPI spec is now public and the api key is not mandatory.
2025-11-10 09:34:14 +00:00
Fraser
22ebb53487 Refactor SegmentActionSelect (#65576) 2025-11-10 12:07:21 +13:00
Fraser
4e1d6c0796 Refactor edit header (#65577) 2025-11-10 12:07:07 +13:00
Oleksandr Yakushev
cec321e06c [insights] Convert BigDecimals into Doubles early in the pipeline (#65234) 2025-11-10 00:23:44 +02:00
Oleksandr Yakushev
fcce676094 [normalize] Optimize metabase.lib.schema.util (#63470) 2025-11-08 23:50:36 +02:00
Noah Moss
450dddb456 Ensure we normalize queries before detecting transform source type (#65541) 2025-11-08 12:32:01 -05:00
Sébastien
acadfded3e Closes EMB-970 move some callbacks to MetabaseGlobalPluginsConfig (#65590)
* Closes EMB-970 move some callbacks to MetabaseGlobalPluginsConfig

* types
2025-11-08 07:14:54 +01:00
Anderson
4578d66e2e Fix some modals not closing properly without browser history (#65370)
* Fix some modals not closing properly without browser history

* Add e2e test

* Fix tsc
2025-11-07 21:00:49 -03:00
Alex Yarosh
ff2b3d80ff docs: new sdk click and link behavior (#65627)
* new click and link behavior

* Apply suggestions from code review

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

* handle handlelink

* fix typo

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-11-07 18:18:04 -05:00
Nick Fitzpatrick
d3efd21c50 Gdgt 910 rework look and feel of color settings in gauge (#65552)
* updated segments ui

* sober up the needle

* setting up unit tests

* make gauge needle opaque

* remove key, update unit test
2025-11-07 21:15:36 +00:00
Jeff Bruemmer
4d54ae84d5 docs - remote sync edit (#65625)
* turning off remote sync

* theme toggling in command palette

* edtis
2025-11-07 16:13:52 -05:00
Nick Fitzpatrick
15f92af504 Use transparency instead of white for table color ranges (#65426)
* Use transparency instead of white for table color ranges

* adding visual tests
2025-11-07 17:00:07 -04:00
Alex Yarosh
9408112eeb Document supported databases for model persistence (#65621)
Added section listing databases that support model persistence.
2025-11-07 14:21:48 -05:00
Nemanja Glumac
b614b64281 Remove special embedding-sdk e2e test case (#65594) 2025-11-07 19:30:52 +01:00
Timofey Kachalov
7e19ce967f fix(sdk): Accept an entity id as a target collection id for CreateQuestionModal (#64601) 2025-11-07 21:45:08 +04:00
Nicolò Pretto
671e406c28 fix(modular): fix downloads on dashboards loaded by entityIds (#65613)
* fix(modular): fix downloads on dashboards loaded by entityIds

* tests
2025-11-07 17:39:43 +00:00
github-automation-metabase
3dd2b5a7ac Update generated docs (master) (#65596)
Co-authored-by: github-actions <github-actions@github.com>
2025-11-07 11:52:43 -05:00
Nick Fitzpatrick
761e01ff71 update color scheme for google button (#65558)
* update color scheme for google button

* Adding a comment like I was supposed to
2025-11-07 09:36:51 -07:00
Braden Shepherdson
16c875265c [perf] New MetadataProvider and query derived from a real perf issue (#65508)
This has been a very valuable benchmark for processing complex queries,
especially large `:case` statements and nested aggregations.

Adding it with some REPL-able benchmarks in `query-processor.perf-test`.
2025-11-07 15:34:34 +00:00
Sébastien
f2610651a1 fixed flaky (#65599) 2025-11-07 16:01:27 +01:00
Farhanul Haque Khan
5dc4b8809a Add logging configuration to Docker setup (#65521)
---------

Co-authored-by: Rodrigo López Dato <rodrigo@metabase.com>
2025-11-07 14:20:51 +00:00
Jeff Bruemmer
f70a7b3a7f update doc workflow to add manual input (#65597) 2025-11-07 14:18:08 +00:00
Nicola Mometto
5a7f27262d small bugfixes for mysql aws iam support (#65585) 2025-11-07 12:15:37 +00:00
Phoomparin Mano
f893c48fde fix(embed-js): black background is shown on systems with dark mode preferences (#65534)
* reverts the color-scheme meta tag

* adds the color scheme meta tag if entry point is not embed-sdk

* add backend tests for color-scheme meta tags

* add a cypress test for color-scheme
2025-11-07 12:06:18 +00:00
Oleksandr Solovyov
f91fa374af metabot request cancelation (#65538)
this time it is actually working and tests are synchronized with real-world behavior
2025-11-07 13:32:24 +02:00
Dan Stone
aec03f0e37 Avoid DDL races in redshift sync (relation does not exist error) (#65546)
- catalog metadata is not transactional in redshift
- calls like pg_catalog.has_schema_privilege when using a string argument will resolve the oid of the schema/table etc
- if the oid cannot be resolved (e.g. table/schema does not exist) an error is thrown

We occasionally see sync failed due to relation does not exist, one cause might be concurrent test runs / cleanup deleting tables/schemas while running.

I have fixed the first half of the union to use the oid form of these calls which will result in NULL instead of an error while racing with DDL in other runs.

Need to research on external tables before changing the external table sub-query: probably want to join to svv_external_schemas and use the oid there, but not 100% yet.
2025-11-07 10:58:11 +00:00
Nemanja Glumac
ee9dd41cd2 Fall back to the staging token check (#65474) 2025-11-07 09:07:06 +01:00
dpsutton
97206bcf80 Fix docs scalar version (#65553)
* Fix docs

it throws an error in the js console about webassembly not having the
right permissions

Two ways to fix: give permissions, or rollback to a version that works.

I'm pinning to a version that works since we are close to a release.

39.2 breaks, 39.1 works.
I'm also including the recommended stylesheets

In the meantime, i'm going to investigate
resources/openapi/index_external.html.mustache as i'm not sure what uses
this and if it needs to be updated or deleted. Perhaps used by `clojure
-M:ee:doc api-documentation`?

* switch template to pinned 39.1 version
2025-11-06 23:32:45 -05:00
Riley Thompson
02eec9c5b3 Update mongo test after driver upgrade (#65560)
* adjust exception assertion

* make exception msg regex more generic
2025-11-07 01:05:31 +00:00
Denis Berezin
d3f45bcced UXW-2179 Replace 'Add to dashboard' modal with a toast (#65400)
* UXW-2179 Replace 'Add to dashboard' modal with a toast

* fix some e2e tests

* Fix more e2e tests

* Fix more e2e tests

* Fix more e2e tests

* Design fix

* Fix e2e
2025-11-07 02:11:42 +03:00
Jeff Bruemmer
0d3bae5103 docs - metabot can use the glossary (#65562)
* metabot can use the glossary

* link to glossary
2025-11-06 16:50:29 -05:00
Alex Yarosh
410c4aeb12 docs: for for for for for for (#65559)
* Fix typo in 'Checking for breaking changes' section

* Fix typo in 'Checking for breaking changes' section
2025-11-06 16:11:54 -05:00
Alex Yarosh
92a25096ae docs: dependencies on save (#65450)
* Add breaking changes detection information

Added section on checking for breaking changes when saving questions, models, or metrics.

* Add breaking changes check to model editing documentation

Added section on checking for breaking changes when saving a model.

* Apply suggestions from code review

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

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-11-06 15:21:33 -05:00
Chris Truter
5937d3bb38 Add flag to skip search reindexing on import (#65537)
* Add flag to skip search reindexing when loading entities

* Test flag
2025-11-06 15:06:51 -05:00
github-automation-metabase
85ff7199c0 Bump org.mongodb/mongodb-driver-sync from 5.5.1 to 5.6.1 (#64667)
Inspect dependency changes here: https://github.com/mongodb/mongo-java-driver/compare/r5.5.1...r5.6.1
2025-11-06 18:55:15 +00:00
Jeff Bruemmer
9731625cc4 docs - remote sync (#65443)
* embedding collections

* image, edits, and embedding example

* various edits

* edits

* edits and images

* more edits

* Optimized 4 images, saved 235.2 KB (36.0% smaller)

* library to synced collection

* fix links

* Update docs/installation-and-operation/remote-sync.md

Co-authored-by: Alex Yarosh <alexandra@metabase.com>

* Update docs/installation-and-operation/remote-sync.md

Co-authored-by: Alex Yarosh <alexandra@metabase.com>

* edits

* edits

Co-authored-by: Alex Yarosh <alexandra@metabase.com>

* edits

* more edits

* clean up

* edit

* clean up

* dev instance

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
Co-authored-by: Alex Yarosh <alexandra@metabase.com>
2025-11-06 17:34:41 +00:00
Nicola Mometto
ff099455d0 Add AWS IAM Authentication Support for PostgreSQL and MySQL (#65418)
* add aws jdbc wrapper

* add aws-iam option to auth-provider-options

* WIP: hook ssl iam in postgres

* wip

* working

* style

* postgres appdb aws iam support

* auth-provider-options-only-aws

* aws iam for mysql

* ssl

* warnings

* as error

* support appdb uri

* add unit tests

* warning

* don't automatically include useSSL

* support ssl-cert configs for mysql appdb

* more unit tests

* refactor

* integration test

* fix: always set useSSL for aws-iam in mysql appdb

* fix mysql uri

* chore

* style

* fix

* connection tests

* setup for CI

* temporarily disable until secrets are setup

* chore: set

* add warning

* Revert "temporarily disable until secrets are setup"

This reverts commit 4ca6eb4607.
2025-11-06 16:26:32 +00:00
Alex Yarosh
5037eec437 Update impersonation.md to include Starburst/Trino (#65542)
Added Starburst/Trino to the list of supported databases for impersonation.
2025-11-06 10:34:54 -05:00
Aleksandr Lesnenko
a5db416a8a use new library icon for remote-synced collections (#65251)
* show new library icon

* UXW-2115 Address PR feedback - makes it so only the Library uses the synced collection icon, not the nested subdirectories

* UXW-2115 Fix getCollectionType condition

* UXW-2115 Removes unnecessary type changes

* UXW-2115 Reverts changes for synced collection icon

---------

Co-authored-by: Brad Anderson <brad@metabase.com>
2025-11-06 14:26:50 +00:00
Timofey Kachalov
b9df4f2f7e Enhance onBeforeRequest into onBeforeRequestHandlers for Api class (#65195) 2025-11-06 13:13:26 +04:00
Riley Thompson
b9f50ff543 Fix databricks tests after driver upgrade (#65498)
* fix databricks tests

* Assert query works with invalid user agent

* Address comments
2025-11-06 02:36:48 +00:00
Sloan Sparger
71f0ce1469 [Dark Mode] Update Metabot illustration (#65185)
* refactor HomeGreeting and convert to use css module over styled components

* update colors for metabot illustration

* bad ai

* rename

* pr feedback

* small adjustments
2025-11-05 20:06:56 -06:00
github-automation-metabase
1969873cb0 Bump com.github.oliyh/martian-clj-http from 0.1.31 to 0.2.1 (#64394)
Inspect dependency changes here: https://github.com/oliyh/martian/compare/0.1.31...0.2.1
2025-11-06 00:29:30 +00:00
github-automation-metabase
8bde92165a Bump net.snowflake/snowflake-jdbc-thin from 3.26.1 to 3.27.0 (#64668)
Inspect dependency changes here:
2025-11-06 00:29:11 +00:00
Nemanja Glumac
4591f96f57 Remove unneeded tests after #65485 (#65517) 2025-11-06 00:10:20 +01:00
dpsutton
08a43180d7 spark failure fix (#65502)
* spark failure fix

I cannot run spark locally so from CI:

```
FAIL in metabase.driver.sparksql-test/friendly-inline-strings-in-convert-to-sql-test (sparksql_test.clj:67)

:sparksql
 The native query returned in query results should use user-friendly splicing
expected: "SELECT COUNT(*) AS `count` FROM `test_data`.`venues` AS `t1` WHERE `t1`.`name` = 'wow'"
  actual: "SELECT COUNT(*) AS `count` FROM `test_data`.`venues` AS `t1` WHERE `t1`.`name` = 'wow'"
    diff:
expected: "SELECT COUNT(*) AS `count` FROM `test_data`.`venues` AS `t1` WHERE `t1`.`name` = 'wow'"
  actual: "SELECT COUNT(*) AS `count` FROM `test_data`.`venues` AS `t1` WHERE `t1`.`name` = decode(unhex('776f77'), 'utf-8')"
```

Locally hit this on an m1 mac:

```
impl.get-or-create :: create-database! failed; destroying :sparksql database “test-data” {mb-test=metabase.driver.sparksql-test/friendly-inline-strings-in-convert-to-sql-test}
java.util.concurrent.TimeoutException: Timed out after 30.0 mins
```

* fix license test failure

https://github.com/metabase/metabase/pull/65034 bumped some jetty deps
from 12.0.24 to 12.1.3. Along for the ride came a new org:

```
org.eclipse.jetty.ee9.websocket/jetty-ee9-websocket-jetty-server 12.1.3
  X org.eclipse.jetty.ee9/jetty-ee9-servlet 12.1.3 :use-top
  . org.eclipse.jetty.ee9/jetty-ee9-webapp 12.1.3
    . org.eclipse.jetty/jetty-xml 12.1.3
      . org.eclipse.jetty/jetty-util 12.1.3
      X org.slf4j/slf4j-api 2.0.17 :use-top
    . org.eclipse.jetty.ee/jetty-ee-webapp 12.1.3 <--- new
```

This has a new org of `org.eclipse.jetty.ee` and no discernable license
in the pom or the jar.

Refresher we look in the pom for things like

```
  <licenses>
    <license>
      <name>The Apache Software License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
```

or in the jar for some common names of licenses, like in this mysql
connector jar:

```
  -rw-r--r--     134  18-Sep-2023 19:11:56  INFO_SRC
  -rw-r--r--   71049  18-Sep-2023 19:11:56  LICENSE
  -rw-r--r--    1624  18-Sep-2023 19:11:56  README
  -rw-r--r--     846  18-Sep-2023 19:12:04  META-INF/INDEX.LIST
```

I didn't see a license at either of these spots, but consulted
https://mvnrepository.com/artifact/org.eclipse.jetty.ee/jetty-ee-webapp
to see it listed as Apache 2.0 and EPL 2.0
2025-11-05 16:56:07 -06:00
Nemanja Glumac
8a9a134989 Make Trunk analytics always run (#65451)
* Make Trunk analytics always run

This prevents false positives because Trunk analytics actio will now
always analyze test results, and compare them with their own test
quarantine list. It uses this information to know if it should fail the
job or let it pass.

* Introduce dry-run

When a PR is in a draft mode, we don't want to upload results but still
have to quarantine tests.
2025-11-05 23:34:48 +01:00
github-automation-metabase
f6582c78d1 Bump org.clojure/clojure from 1.12.2 to 1.12.3 (#64158)
Inspect dependency changes here: https://github.com/clojure/clojure/blob/clojure-1.12.3/changes.md

Co-authored-by: Cam Saul <1455846+camsaul@users.noreply.github.com>
2025-11-05 21:46:55 +00:00
Nick Fitzpatrick
10deae2a03 removing new badge for move questions into their dashboards (#65485) 2025-11-05 17:39:06 -04:00
Braden Shepherdson
b910dc5566 chore: removing a stub CLJC file that got included accidentally (#65437) 2025-11-05 21:05:39 +00:00
Cam Saul
65a4a7c9e8 Fix kondo failure in master (#65496) 2025-11-05 13:04:47 -08:00
Alex Yarosh
8ab634d497 docs : clarify subscription settings (#65179)
* Update wording for subscriptions and alerts section

* Update docs/permissions/application.md

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

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-11-05 19:08:06 +00:00
github-automation-metabase
9431038a75 Update generated docs (master) (#65453)
Co-authored-by: github-actions <github-actions@github.com>
2025-11-05 14:01:21 -05:00
github-automation-metabase
cccb11b0d2 Bump org.eclipse.jetty/jetty-server from 12.0.24 to 12.1.3 (#65034)
* Bump org.eclipse.jetty/jetty-server from 12.0.24 to 12.1.3

Inspect dependency changes here:

* Add other Jetty deps bumps

---------

Co-authored-by: Cam Saul <github@camsaul.com>
2025-11-05 18:19:16 +00:00
github-automation-metabase
53a2da3c62 Bump org.graalvm.polyglot/polyglot from 24.2.2 to 25.0.1 (#65038)
* Bump org.graalvm.polyglot/polyglot from 24.2.2 to 25.0.1

Inspect dependency changes here: https://github.com/oracle/graal/compare/graal-24.2.2...graal-25.0.1

* Consolidate deps bumps

---------

Co-authored-by: Cam Saul <github@camsaul.com>
2025-11-05 18:18:37 +00:00
github-automation-metabase
8be450aa19 Bump io.netty/netty-common from 4.1.124.Final to 4.2.7.Final (#64827)
* Bump io.netty/netty-common from 4.1.124.Final to 4.2.7.Final

Inspect dependency changes here:

* Consolidate deps bumps

---------

Co-authored-by: Cam Saul <github@camsaul.com>
2025-11-05 17:55:34 +00:00
Oleksandr Yakushev
22929ac32b [mage] Use Babashka to run cljfmt on staged files in git pre-commit hook (#65026) 2025-11-05 19:23:53 +02:00
Oleksandr Yakushev
b2b5720843 [flake] Increase test timeout in metabase.app-db.liquibase-test (#64814) 2025-11-05 19:04:08 +02:00
Oleksandr Yakushev
8abb1420e0 [qp] Reuse oridinarily compiled query as inline if it doesn't have params (#64651) 2025-11-05 18:59:22 +02:00
Ryan Laurie
23287f9f28 Toggle dark mode from command palette (#65359)
* toggle dark mode from command palette

* I'm sorry I built this in a dumb way Ryan

---------

Co-authored-by: Nick Fitzpatrick <nickfitz.582@gmail.com>
2025-11-05 16:32:46 +00:00
Noah Moss
06e016fe4e Surface collection descriptions to metabot in search (#65442)
* Surface collection descriptions to metabot in search

* Fetch descriptions as a post-processing step as they're not indexed
2025-11-05 11:15:24 -05:00
Jakub Chodorowicz
be8686b577 feat: make metabot logo follow the bran colors (#65358)
# Conflicts:
#	frontend/src/metabase/common/components/MetabotLogo/MetabotLogo.stories.tsx

# Conflicts:
#	loki.config.js
2025-11-05 16:51:58 +01:00
Aleksandr Lesnenko
71eb726eb5 upgrade to echarts v6 (#64139)
* upgrade to echarts v6

* Update Loki Snapshots

* Fix BE test

* update gridlines helper function

* adjust test

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
Co-authored-by: Nick Fitzpatrick <nickfitz.582@gmail.com>
2025-11-05 11:45:47 -04:00
Anderson
60c65add21 Make sure /dirty is called when moving an entity out of the library (#65259)
* Make sure /dirty is called when moving an entity out of the library

* Untouch embedding code / Clean up / Add some tests

* Check cache from both entities and RTK / Undo unnecessary changes

* Make sure getCollectionFromCollectionsTree gets collection from latest query
2025-11-05 11:22:47 -03:00
Stas Gavrylov
e65f73716c GDGT-1185: Columns appear twice in model list view until action taken (#65412)
* List View: Fix incorrect bg color initialization

* GDGT-1185: Fix columns list initiation in ListView configuration screen

* GDGT-1185: Update e2e test

* GDGT-1185: Fix lint

* GDGT-1185: Fix unit tests

* GDGT-1185: Address PR comments

* GDGT-1185: Minor refactoring
2025-11-05 16:14:56 +02:00
Ngoc Khuat
be8790142c Proxy apis for store to get plan and addons (#65423) 2025-11-05 13:02:39 +00:00
Uladzimir Havenchyk
d04a2452f4 chore: ignore e2e embedding host apps from linting (#65467) 2025-11-05 15:58:27 +03:00
Oleksandr Solovyov
6ff47bfe22 metabot: handle (and propagate) request cancellation (#65461) 2025-11-05 14:37:27 +02:00
Timofey Kachalov
2df9e2645f Fix getNextSdkVersion helper (#65466) 2025-11-05 16:26:48 +04:00
Nicolò Pretto
1e997d6d5c ci: allow running stress tests on sdk tests (#64759)
* ci: allow running stress tests on sdk tests

* type choice

* yeah this should work 🤞

* ok we should also build the sdk

* maybe this time

* do we need to setup the BE?

* Revert "do we need to setup the BE?"

This reverts commit 7e9092e2c3.

* trying the auto infer thing out

* refactor and move the logic up to dedup it

* rename output

* move up env?

* Revert "move up env?"

This reverts commit f78f72e396.

* increase timeout to make stress test with throttling pass

* increase the timeout even more :shrugs:
2025-11-05 10:31:41 +01:00
Timofey Kachalov
381d156ca6 Use stableStringify for PublicOrEmbedDashboardView story + add StrictUnion type (#65411) 2025-11-05 12:51:48 +04:00
Nemanja Glumac
43301c49ad Stabilize and deduplicate eslint cache (#65410) 2025-11-05 09:31:47 +01:00
Nathan Voxland
a133b31fc4 Renamed Library to Synced Collection (#65447)
Renamed Library to Synced Collection
2025-11-04 23:32:13 -06:00
github-automation-metabase
d632109808 Bump cider/piggieback from 0.6.0 to 0.6.1 (#63218)
Inspect dependency changes here:

Co-authored-by: Cam Saul <1455846+camsaul@users.noreply.github.com>
2025-11-05 00:49:45 +00:00
github-automation-metabase
a316b1d9d3 Bump com.metabase/athena-jdbc from 3.5.0 to 3.6.0 (#64166)
Inspect dependency changes here:

Co-authored-by: Cam Saul <1455846+camsaul@users.noreply.github.com>
2025-11-05 00:41:06 +00:00
github-automation-metabase
d7a97b5704 Bump com.google.cloud/google-cloud-bigquery from 2.54.2 to 2.55.3 (#65041)
Inspect dependency changes here: https://github.com/googleapis/java-bigquery/blob/v2.55.3/CHANGELOG.md
2025-11-05 00:28:05 +00:00
github-automation-metabase
53fdb817c4 Bump io.github.clojure/tools.build from 0.10.10 to 0.10.11 (#65334)
Inspect dependency changes here: https://github.com/clojure/tools.build/blob/v0.10.11/CHANGELOG.md
2025-11-05 00:21:57 +00:00
github-automation-metabase
ead22c46a3 Bump ch.qos.logback/logback-classic from 1.5.18 to 1.5.20 (#64819)
Inspect dependency changes here:
2025-11-05 00:13:30 +00:00
github-automation-metabase
1615c60cbf Bump org.apache.sshd/sshd-core from 2.16.0 to 3.0.0-M2 (#65031)
Inspect dependency changes here:
2025-11-05 00:08:47 +00:00
github-automation-metabase
b3fa75c941 Bump dk.ative/docjure from 1.21.0 to 1.22.0 (#64821)
Inspect dependency changes here: https://github.com/mjul/docjure/blob/v1.22.0/CHANGELOG.md
2025-11-04 16:05:24 -08:00
github-automation-metabase
2821954e9b Bump software.amazon.awssdk/s3 from 2.33.0 to 2.36.2 (#65039)
* Bump software.amazon.awssdk/s3 from 2.33.0 to 2.36.2

Inspect dependency changes here:

* Consolidate deps bumps

---------

Co-authored-by: Cam Saul <github@camsaul.com>
2025-11-05 00:02:22 +00:00
github-automation-metabase
d4acb644ee Bump com.microsoft.sqlserver/mssql-jdbc from 13.2.0.jre11 to 13.2.1.jre11 (#64831)
Inspect dependency changes here:
2025-11-04 23:58:12 +00:00
github-automation-metabase
1236a70059 Bump nrepl/nrepl from 1.4.0 to 1.5.1 (#64823)
Inspect dependency changes here: https://github.com/nrepl/nrepl/blob/v1.5.1/CHANGELOG.md
2025-11-04 15:53:52 -08:00
github-automation-metabase
ab8fcd54b0 Bump com.facebook.presto/presto-jdbc from 0.294 to 0.295 (#64829)
Inspect dependency changes here:
2025-11-04 15:49:09 -08:00
github-automation-metabase
6dbe6594a7 Bump com.databricks/databricks-jdbc from 2.7.3 to 3.0.1 (#64828)
Inspect dependency changes here:
2025-11-04 15:37:15 -08:00
github-automation-metabase
f83b585668 Bump com.amazonaws/aws-java-sdk-core from 1.12.788 to 1.12.792 (#64403)
Inspect dependency changes here:
2025-11-04 15:19:09 -08:00
github-automation-metabase
53d01c5274 Bump cider/cider-nrepl from 0.57.0 to 0.58.0 (#64820)
Inspect dependency changes here: https://github.com/clojure-emacs/cider-nrepl/blob/v0.58.0/CHANGELOG.md
2025-11-04 15:07:32 -08:00
Timofey Kachalov
8137d490b3 Adjust parameter_mappings for a text dashcard when its variable is removed (#64463) 2025-11-05 02:53:44 +04:00
metamben
e39c2119d2 Add creator_id for transform (#65388)
* Add creator_id for transform

Closes QUE-2715
2025-11-05 01:46:34 +03:00
Nathan Voxland
c471c5640d Improve tracking for new objects that get deleted before sync (#65433) 2025-11-04 16:36:55 -06:00
Fraser
2f49744ee1 Remove parsing from file download e2e tests (#65081)
* Make e2e download tests more lightweight

* Fix helper to handle redirects
2025-11-05 10:18:43 +13:00
Nick Fitzpatrick
283eae65b6 Adding collection name to recent documents (#65376)
* Adding collection name to recent documents

* re-arranging e2e test
2025-11-04 17:07:36 -04:00
Braden Shepherdson
1217fca9a4 [perf] Add lib.computed, optimize wide tables and deep user queries (#65364)
Part of #64774.

Hopefully this is sufficient to unblock users seeing the high CPU times
like in #64774. I discovered other, less significant performance issues
during this investigation that I'll be addressing in follow-up PRs.

### Investigation Notes

The problem query and relevant table metadata from a helpful customer
was taking 950ms to preprocess and compile on my 2022 M1 Max, running
Metabase in dev mode but with Malli schema enforcement disabled.

The query is pretty big! It uses 3 tables with 200-300 columns each,
has several stages including some from a joined card, and ends up with
several stages doing two levels of aggregation. It also includes
several *huge* `:case` expressions.

The optimizations below have reduce the time required from 950ms to 310ms
on my machine. A 3x improvement, but I think there's more to be gained in
the follow-up PRs I mentioned.

### Optimizations

Main optimizations:

- `lib.util/find-stage-index-and-clause-by-uuid` pre-computed and cached
  on each stage, saved 120ms on the above query.
- `lib.metadata.cached-provider/fields` attempts to pre-load the cache
  of individual `lib.metadata/field` calls, having just fetched them
  all, but it used the wrong key and they were all misses instead!
- `expression-metadata` and `aggregation-metadata` are recomputed over
  and over again by their stage and later stages; cache them by value
- `returned-columns` was cached at the top level and frequently missed
  because of dumb details like explicit stage 1 vs. -1 for last stage.
  - Switched it to caching on individual `returned-columns-method`s
    with more precise cache keys.

#### New Caching Approach

Both of the latter two are using a new caching approach: a weak map
using queries as keys. Since CLJ(S) maps are immutable, any change to
the query means a new pointer.

That's still far more eviction than optimal! Most edits to a query
don't actually invalidate most of the cached values! But it's a lot
better than what we had before, and because the map's keys are weak
references, the queries and their cached data are not retained any
longer than the query itself.

### New Benchmarking Tools

I also added a `qp.perf-test` namespace with some metadata providers
with 10-, 100-, 1000- and 10,000-column tables for testing.

So far the tests it performs are quite basic, though. I'll be adapting
the user-provided query into a test case in the future, since it's an
excellent real-world example of a complex but not pathological query.
2025-11-04 20:49:25 +00:00
Jeff Bruemmer
5884bfe547 docs - various edits (#65422)
* various edits

* edits
2025-11-04 14:39:26 -05:00
Aleksandr Lesnenko
9d1d534e51 remote sync analytics (#65129) 2025-11-04 18:38:23 +00:00
Nick Fitzpatrick
2fb4793c24 fix large command palette subtext elements, add loki testing (#65369)
* fix large command palette subtext elements, add loki testing

* how did I miss this?

* updating Overlay demo
2025-11-04 13:23:12 -04:00
Nathan Voxland
954857c036 Clean up remote sync source vs. snapshot APIs (#65122) 2025-11-04 11:00:45 -06:00
Oleksandr Yakushev
6d1d618fff [util] Explicitly test for BigDecimals in real-number? (#65202) 2025-11-04 18:24:45 +02:00
Aleksandr Lesnenko
785c418578 allow disabling remote sync (#65175) 2025-11-04 15:45:41 +00:00
Ryan Laurie
9d1c3c0ab4 Release Log Upgrades (#65186)
* support tag refs in version log

* release log upgrades

* use html url

* no thanks

* update tests

* ok review bot, you win
2025-11-04 08:33:21 -07:00
Brad Anderson
57daa4d5dc Fix #50044 - Updates dashcard loading state so it shows the correct title while it's loading (#65363) 2025-11-04 10:19:19 -05:00
Chris Truter
805badeb79 Flake protection 🥐 (#65415) 2025-11-04 12:27:56 +00:00
Nemanja Glumac
5ea9541981 Fix the auto-patch workflow (#65417) 2025-11-04 13:12:53 +01:00
Abed Habli
72a7ebec91 V57 docs: updating Alerts + Model view (#65353)
* update screenshot

* Updating model list view

* updating screenshots to Model view

* Optimized 4 images, saved 406.0 KB (50.9% smaller)

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
2025-11-04 12:16:11 +01:00
Nemanja Glumac
cdb6640ea4 Resolve a missing pre-release output (#65413)
[ci skip]
2025-11-04 12:07:38 +01:00
Chris Truter
8b90ffd906 Exclude other users collections in metabot search (#65348)
Closes BOT-496
2025-11-04 11:54:34 +02:00
Timofey Kachalov
3758d88539 Add embedding_type field for card/dashboard (#65209) 2025-11-04 12:45:57 +04:00
Aleksandr Lesnenko
d6397e205e skip flaky UpsellBigCard loki specs (#65404)
* skip flaky UpsellBigCard loki specs

* Update Loki Snapshots

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
2025-11-04 08:21:26 +03:00
Noah Moss
01f7eeb023 Recreate model index quartz triggers on job initialization when needed (#65394)
* Recreate model index quartz triggers on job initialization when needed

* whitespace

* rename var + add comment
2025-11-03 19:32:49 -05:00
Nathan Voxland
8f3730dd45 Improving git management for remote sync (#65249) 2025-11-03 16:19:31 -06:00
dpsutton
5e92088c7d remove useless log (#65390)
```
Updating table metadata for Table 5465 ''properati_ar.properties_rent_201607'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5465 ''properati_ar.properties_rent_201607'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5485 ''properati_ar.properties_sell_201706'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5485 ''properati_ar.properties_sell_201706'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5468 ''properati_ar.properties_rent_201602'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5468 ''properati_ar.properties_rent_201602'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5511 ''properati_ar.properties_rent_201612'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5511 ''properati_ar.properties_rent_201612'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5431 ''properati_ar.properties_sell_201802'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5431 ''properati_ar.properties_sell_201802'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5441 ''properati_ar.properties_sell_201707'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5441 ''properati_ar.properties_sell_201707'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5467 ''personal_bq_repro.events_20230519'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5467 ''personal_bq_repro.events_20230519'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5484 ''properati_ar.properties_sell_201708'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5484 ''properati_ar.properties_sell_201708'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5434 ''properati_ar.resultados_apto_credito'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5434 ''properati_ar.resultados_apto_credito'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5501 ''properati_ar.properties_sell_201704'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5501 ''properati_ar.properties_sell_201704'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5433 ''properati_ar.properties_rent_201604'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5433 ''properati_ar.properties_rent_201604'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5478 ''properati_ar.properties_sell_201702'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5478 ''properati_ar.properties_sell_201702'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5498 ''properati_ar.properties_sell_201512'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5498 ''properati_ar.properties_sell_201512'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5447 ''properati_ar.properties_rent_201709'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5447 ''properati_ar.properties_rent_201709'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5463 ''properati_ar.properties_rent_201609'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5463 ''properati_ar.properties_rent_201609'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
Updating table metadata for Table 5448 ''properati_ar.properties_rent_201509'' {mb-quartz-job-type=SyncAndAnalyzeDatabase}
:is_writable of Table 5448 ''properati_ar.properties_rent_201509'' changed from null to null {mb-quartz-job-type=SyncAndAnalyzeDatabase}
```

We unconditionally say we are updating table metadata, but then when we
actually change anything we of course include the table name.

Note here there is some kind of bug that we are changing the
table (which property??) from null to null.
2025-11-03 16:02:18 -06:00
Jeff Bruemmer
2da5fb8aa8 token data (#65396) 2025-11-03 21:43:00 +00:00
Uladzimir Havenchyk
a94a70fe46 chore: cleanup warnings from postcss (#64954)
* chore: cleanup warnings from postcss

* Update frontend/src/metabase/common/components/EmojiPicker/EmojiPicker.module.css

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

---------

Co-authored-by: Nemanja Glumac <31325167+nemanjaglumac@users.noreply.github.com>
2025-11-04 00:08:22 +03:00
Oleksandr Yakushev
5880342225 Remove unused metabase.util.formatting.numbers and metabase.util.formatting.time (#63791) 2025-11-03 22:37:47 +02:00
Jeff Bruemmer
89adf23ef7 update api docs (#65382) 2025-11-03 14:30:57 -05:00
Denis Berezin
7c7241d350 UXW-2182 fix codemirror editor suggestions styles in light mode (#65367) 2025-11-03 22:03:53 +03:00
Jeff Bruemmer
9638db8b02 json from data-url (#65374) 2025-11-03 18:47:47 +00:00
AlessioLaiso
bace3da926 Updates 6 illustrations for dark mode (#65375) 2025-11-03 14:31:13 -04:00
Ryan Laurie
898c82ad4c add v57 to version-helpers (#65227) 2025-11-03 18:29:18 +00:00
Ryan Laurie
c9792f6604 Restore calendar hover styles (#65361)
* restore calendar hover styles

* fix calendar picker hover states

* remove unnecessary rule
2025-11-03 11:28:02 -07:00
Noah Moss
ec0bc5e081 Comment out BackfillTransformSourceType migration (#65147) 2025-11-03 13:20:13 -05:00
Nathan Voxland
9b4c474e11 Remote sync should ignore system git settings (#65293) 2025-11-03 11:38:47 -06:00
metamben
8f10457e32 Add archived flag to graph endpoints (#65366)
Fixes QUE-2708
2025-11-03 16:43:27 +00:00
AlessioLaiso
20b3834269 Updates 35 SVG illustrations (#65232)
* Updates 35 SVG illustrations

The same asset now works well for both light and dark mode.

* branding OnboardingIllustration, adding cloug and bug metabot to metabot logo

* PR Feedback

---------

Co-authored-by: Nick Fitzpatrick <nickfitz.582@gmail.com>
2025-11-03 12:24:40 -04:00
Denis Berezin
0150dcfe07 UXW-2170 cleanup chart brush (#65313) 2025-11-03 18:49:40 +03:00
Riley Thompson
2b2a22b86d filter for active fields (#65245) 2025-11-03 15:11:08 +00:00
Noah Moss
d3e976ed53 Annotate draft transforms in user_is_viewing context with source type when possible (#65283)
* Annotate draft transforms in user_is_viewing context with source type when possible

* add unit tests

* Move transform-source-type helper to transform utils; some refactor

* switch to use lib/native-only-query; change default transform query in tests to use mbql5

* switch batch to using lib.query/native?

* switch back to native-only-query?

* clean ns
2025-11-03 09:56:29 -05:00
lbrdnk
c950dad7eb Fix suggested prompts schema and add test (#65299) 2025-11-03 15:33:50 +01:00
lbrdnk
2693173e7f Compute param values from card results (#64318)
* Compute param values from card results

seq for bool

Tests, multi-stage queries

Compute values also for params on nested stages

whitespace

Unused ns

Last stage check first

Docstring

Drop base query's last stage clauses

Address review remarks

Apply suggestions from code review

Co-authored-by: metamben <103100869+metamben@users.noreply.github.com>

Remove redundant ops

Adjust for test

Search for col also in aggregated result columns

Look for breakoutable column only if source-uuid is present

* symb

* Rebase fix

* fix rebase, remove unused module

* post rebase, fix getting database id

* kondo

* Revamp

* limit

* Adjust the solution for impl joins

* Fix e2e

* Comment

* Cleanup

* Cleanup

* comment

* comment

* Update src/metabase/parameters/dashboard.clj

Co-authored-by: metamben <103100869+metamben@users.noreply.github.com>

* indent

---------

Co-authored-by: metamben <103100869+metamben@users.noreply.github.com>
2025-11-03 15:33:39 +01:00
Denis Berezin
3ca4c5a2ee UXW-175 Fix visualization mode switch for pivot table (#65252) 2025-11-03 17:18:36 +03:00
Denis Berezin
9c0910f652 UXW-2172 UXW-2174 remove Document cards click actions (#65191)
* UXW-2172 UXW-2174 remove Document cards click actions

* Fix e2e

* UXW-2172 fix broken click actions for Document cards

* Restore e2e

* Fix typecheck

* review fixes
2025-11-03 17:18:21 +03:00
Mahatthana (Kelvin) Nomsawadi
cbf7579c4c Correct interactive embed query execution count (#65336)
* Simplify the FE API code

* Exclude static embed preview from being counted in analytics

* Update frontend/src/metabase/lib/api.js

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

* Clarify comments

* Add tests

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-03 13:11:10 +00:00
Nemanja Glumac
5ec5c9a9d3 Fix and revive the backend cloverage workflow (#65341) 2025-11-03 11:22:02 +01:00
github-automation-metabase
9ee26d70fd Bump com.ibm.icu/icu4j from 77.1 to 78.1 (#65332)
Inspect dependency changes here:
2025-11-03 09:30:00 +00:00
github-automation-metabase
73aab1d129 Bump djblue/portal from 0.61.0 to 0.62.0 (#65333)
Inspect dependency changes here: https://github.com/djblue/portal/blob/0.62.0/CHANGELOG.md
2025-11-03 09:29:14 +00:00
Oleksandr Yakushev
6375368c92 [kondo] Encourage more m.util.performance functions in perf-sensitive namespaces (#65331) 2025-11-03 11:09:43 +02:00
Nemanja Glumac
ee3cfb7e68 Disable CodeQL trap caching (#65275) 2025-11-03 09:52:34 +01:00
metamben
e62903b72a Add test case missing from #65240 (#65327)
The PR #65240 got merged without this test.
2025-11-02 02:58:31 +02:00
metamben
652f725d41 Make transforms available in search for admins only (#65240)
* Make transforms available in search for admins only

Fixes QUE-2710

* Fix test
2025-11-01 02:42:23 +03:00
Dan Stone
2c49eb977d Add missing .result to script output lookup in pre-release (#65298) 2025-10-31 23:02:21 +00:00
Brad Anderson
b70e091fe8 Fix #64685 - Update brand colors in UI without needing refresh (#65292)
* UXW-1991 Fixes various issues both new and old with the Branding page like the colors not updating until refresh and swatches not updating when setting colors back to their defaults

* UXW-1991 Uses hex format for brand colors placeholders

* UXW-1991 Fix persistence issues with setting/unsetting accent colors
2025-10-31 18:39:08 -04:00
Brad Anderson
dff2d77981 UXW-2183 Remove fullscreen dashboard night mode toggle (#65312) 2025-10-31 18:16:07 -04:00
Robert Kosara
60ec838229 Remove mention of "night mode" and image (#65318)
* Remove mention of "night mode" and image

Removed mention of 'Night mode' from fullscreen dashboard instructions.

* Delete dark mode/night mode image
2025-10-31 21:44:44 +00:00
dpsutton
830a6d5c83 Don't count app-db not setup errors in circuit breaker (#65295)
we want to not hammer the network when things are down. But during
startup we don't need to circuit break these errors that we throw before
the app-db is read
2025-10-31 16:33:27 -05:00
github-actions[bot]
e0ebddd4f2 Update translations 2025-10-30 (#65213)
* Update translation sources 2025-10-30

* Update translations

---------

Co-authored-by: github-actions <github-actions@github.com>
2025-10-31 20:45:47 +00:00
metamben
79b350eca6 Make sure enough info about transforms is selected (#65291)
Fixes QUE-2731
2025-10-31 23:41:25 +03:00
Riley Thompson
af1be91a28 Implement connection impersonation for starburst (#64972)
* implemenet impersonation driver methods

* replace starburst impersonation

* use user as default role

* clean up

* enable starburst tests

* mount files to container

* add config files

* fix rules.json

* add starburst impersonation tests

* try fix

* remove old tests

* debug

* Debug'

* add volumes original way

* try again

* revert

* try docker run

* remove services

* add back accessc control

* enable impersonation

* exclude starburst tests again
2025-10-31 18:29:05 +00:00
Robert Kosara
6322ffc3b3 Small edits to v57 docs about Glossary, dark mode, and progress bars (#65253)
* Enhance glossary section with context for definitions

This is a smaller change than I expected, since glossary terms don't show up in searches yet. Might just cut this if it doesn't add anything useful. I also wasn't sure if we should mention Metabot here.

* Add dark mode options

Adds the available options and explains that you don't have to reload the page

* Add a little clarification to the computed goal example

This confused me, so I'm adding this little clarification

* Jeff's suggested change

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

* Remove the bit about LLMs again

---------

Co-authored-by: Jeff Bruemmer <jeff.bruemmer@gmail.com>
2025-10-31 18:17:36 +00:00
Edward Paget
e657e83c3e fix: allow stacktraces to be suppressed in API (#65215)
* fix: allow stacktraces to be suppressed in API

Allows administrators to configure their metabase instance using
MB_HIDE_STACKTRACES to prevent stacktraces from appearing in API
response. For standard responses it replaces unhandled exceptiosn with a
generic message and 500 response. For streaming responses it leaves the
error message and strips out the trace/via keys to prevent exception
info from leaking.

* fixup! dissoc traces from map errors
2025-10-31 09:12:45 -05:00
Nemanja Glumac
4b3c293f04 Remove superfluous python setup from H2 driver test (#65272) 2025-10-31 15:09:48 +01:00
Brad Anderson
1447fa0e95 Fix: UXW-2171 Prevents "Edit Query" from clearing name on chart (#65224) 2025-10-31 09:38:55 -04:00
Edward Paget
cb2510a55d fix: pivoting json values (#65183)
* fix: pivoting json values

* fixup! kondos in test

* Update frontend/src/metabase/lib/data_grid.js

Co-authored-by: Ryan Laurie <30528226+iethree@users.noreply.github.com>

---------

Co-authored-by: Ryan Laurie <30528226+iethree@users.noreply.github.com>
2025-10-31 08:35:55 -05:00
Nemanja Glumac
90f2e42b19 Sunset e2e cross-version tests (#65269)
Context: https://metaboat.slack.com/archives/C0669P4AF9N/p1761905881175819

The requirements for new and updated attempt at solving this problem are documented in:
https://linear.app/metabase/issue/DEV-1042/design-reliable-cross-version-upgradedowngrade-test-strategy
2025-10-31 14:34:09 +01:00
Mahatthana (Kelvin) Nomsawadi
cbcb70a438 Fix deleted documents were editable (#65136)
* Prevent trashed documents from being edited

* Add test

* Soften the test name tone

* Disallow even updating document when archived via API

* Add BE test

* Fix Cypress test issue reference

* Update tests after merging master

* Only check for archived when not unarchiving

* Don't check archived documents when archiving or unarchiving them

* Add missing condition from merging
2025-10-31 19:15:46 +07:00
lbrdnk
e47e51c229 Metabot glossary integration (#65223)
* Return glossary with user info

* Test glossary in response
2025-10-31 12:25:34 +01:00
Jeff Bruemmer
e6a3974c9a Fix env var doc gen (#65230)
* fix issue with env var gen and some cleanup

* cleanup
2025-10-31 07:00:20 -04:00
Dan Stone
247db60bb7 Increase sync timeout in execution test (#65205)
Redshift sync of even one table can take a really long time (sometimes
over 5 seconds).

Increased to 10 seconds for now.
2025-10-31 10:40:35 +00:00
Jeff Bruemmer
619d9350cc remove registry (#65242) 2025-10-31 03:14:57 +00:00
Nemanja Glumac
9b53db936e Fix logs upload for drivers (#65257)
* Fix logs upload for drivers

When we introduced `continue-on-error` to the "test" step, we had to
update the conditionals for the test report steps as well. I've
introduced a bug by checking for a failure, instead of saying - upload
test reports whenever the job is not successful.

Hint: test.outcome means "step status BEFORE continue-on-error overrides
the exit code"
2025-10-31 02:33:06 +01:00
Nemanja Glumac
024d197e3e Upgrade CodeQL action version (#65250) 2025-10-31 14:04:55 +13:00
metamben
7937c6888c Optimize graph API endpoints (#65172) 2025-10-30 19:41:16 -04:00
github-actions[bot]
3369bf7d15 Update E2E test timings with averaged data (#65024)
Collected timing data from 7 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[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Actions <actions@github.com>
2025-10-30 22:58:27 +00:00
Uladzimir Havenchyk
c7fb07c387 deps: drop react-beautiful-dnd (#64713)
Co-authored-by: Fraser <fraser@metabase.com>
2025-10-31 11:24:41 +13:00
Noah Moss
525dec7eb0 Metabot /debug mode to show tool calls (#64811)
* add debug message type for tool calls

* rename toolCalls -> activeToolCalls

* Basic debug mode slash command to hide/show tool calls

* ToolCallDetailsModal + better formatting

* Fix type

* Fix types, some simplification

* Address minor bot comments

* small changes

* move AgentToolCallMessage into its own file and add copy buttons + tool call id to modal

* fix copied value

* add unit tests

* move failure case further downstream to mitigate any possible customer issue

* ci fixes

---------

Co-authored-by: Sloan Sparger <sloansparger@gmail.com>
2025-10-30 17:20:39 -05:00
Ryan Laurie
f4dde2f744 fix comma in pre-release workflow (#65248) 2025-10-30 20:51:46 +00:00
Nemanja Glumac
c81e28e240 Support releases with different token testing strategies (#65203) 2025-10-30 21:29:02 +01:00
Alexander Polyankin
b859cbfd59 Extract QueryEditor from transforms (#65160) 2025-10-30 20:03:01 +00:00
Nick Fitzpatrick
99a736360b update document title compare to determine dirty state (#65229) 2025-10-30 19:50:30 +00:00
Alexander Polyankin
93d099427e Enable dependency graph UI (#65210) 2025-10-30 19:38:58 +00:00
Nick Fitzpatrick
6fafafe082 fix falsey check when removing card embed from document (#65222) 2025-10-30 16:36:25 -03:00
Nick Fitzpatrick
1a2035d5a4 update hover colors in UserListElement (#65174)
* update hover colors in UserListElement

* adjusting colors

* updating comment
2025-10-30 16:35:27 -03:00
Phoomparin Mano
186df5d802 fix(sdk): non-editable dashboard should not have "add a chart" button and title should be read-only (#65102) 2025-10-31 02:24:32 +07:00
Sloan Sparger
27d13486ac [Metabot] Copy change for suggested prompts setting description (#65163)
* update copy

* adjust copy for embedded metabot

* oops

* remove randomly

* fix test

* feedback
2025-10-30 13:53:33 -05:00
Edward Paget
41ba6ce845 Fix renamed test helper in documents (#65233) 2025-10-30 18:51:32 +00:00
Riley Thompson
1eb96fc1ec return false instead of throw (#65225) 2025-10-30 18:45:40 +00:00
Edward Paget
bbc81e20b3 test a document creation in personal collection (#65118)
* test a document creation in personal collection

* fixup! ws
2025-10-30 12:33:41 -05:00
Stas Gavrylov
fafc53e645 GDGT-1083: Improve visual design for new List view in Stats before v57 (#64957)
* GDGT-1083: Add new icons

* Remove subtitle column. Restyle inputs. Extend icon selection

* GDGT-1083: Fix minor tags input styling issues

* GDGT-1083: Replace semantic colors with accent colors

* GDGT-1083: Add image column selection option

* GDGT-1083: Add placeholder for image column icon. Fix bug with selected icon

* GDGT-1083: Update formatted column values rendering rules

* GDGT-1083: Fix incorrect entity icon initialization

* GDGT-1083: Add range viz rendering for quantity/score columns

* GDGT-1083: Fix drag from ListViewColumnsSidebar

* GDGT-1083: Fix list header grid

* GDGT-1083: Fix State column styling

* GDGT-1083: Fix incorrect rendering for boolean columns

* GDGT-1083: Fix incorrect column rendering for empty cells

* GDGT-1083: Address design review comments

* GDGT-1083: Fix TS error

* GDGT-1083: Fix image column rendering

* GDGT-1083: Minor refactoring

* GDGT-1083: Update e2e est

* GDGT-1083: Add unit test for ListViewItem component

* GDGT-1083: Fix linter

* Fix eslint

* GDGT-1083: Resolve metabot comments

* GDGT-1083: Get rid of split_currency setting

* wip

* GDGT-1083: Address PR comments

* GDGT-1083: Address PR comments

* GDGT-1083: Replace switch logic with fns. Fix header layout bug

* GDGT-1083: Fix badges cursor in list view

* GDGT-1083: Fix cursor styling when dragging over full tags input

* GDGT-1083: Remove max-width

* GDGT-1083: Fix linter

* GDGT-1083: Fix lint

* GDGT-1083: Fix incorrect imgURL/avatarURL column rendering after refactoring

* Fix incorrect icon background color

* Fix incorrect category columns rendering

* Update Loki Snapshots

---------

Co-authored-by: Metabase Automation <github-automation@metabase.com>
2025-10-30 16:58:37 +00:00
Nathan Voxland
d0f5d01eea Create appdb tables in its own connection (#65171) 2025-10-30 10:33:35 -05:00
Nicolò Pretto
a04b79857f remove border from dashboard header where header=false and no tabs (#65161)
* remove border from dashboard header where header=false and no tabs

* move css code up to keep no border in fullscreen
2025-10-30 16:00:07 +01:00
Denis Berezin
9f0f6eb78c UXW-2091 user without collection access to Our Analytics can't save documents (#65159)
* UXW-2091 user without collection access to Our Analytics can't save documents

* fix typecheck

* Fix types

* Add e2e tests
2025-10-30 17:56:02 +03:00
Edward Paget
7ea1d83a67 fix: skip join in stats handler test (#64639) 2025-10-30 09:27:17 -05:00
Edward Paget
9aa6611557 fix: improve collections graph performance (#65098)
* fix: improve collections graph performance

Fixes performance generating and updating a collection graph by avoiding
the cross join of all negative permissions (blocks) between groups and
collections. Instead it builds sparse graph where missing entries for
group/collection paris can be assumed to be :none permissions.

In practice this drops a collection permission update on a graph of 5K
groups and 5K collections from a greater than 10min operation on my
local machine against MySQL to a .5s operation.

* fixup! explicilty disj :root in other places

* fixup! improve some docs

* fixup! improve more docs

* fixup! seq checks

* fixup! blank lines

* fixup! convert raw sql concat into honeysql

* fixup! e2e test
2025-10-30 09:26:26 -05:00
Edward Paget
a7b420eeba Update error message for remote sync dep checking (#65148)
* Update error message for remote sync dep checking

Try to make these error messages less jargony because they are presented
by the user interface when dependency checking content fails.

Closes UXW-2142 and UXW-1879.

* Update some missed tests
2025-10-30 09:25:33 -05:00
dpsutton
7b8edfbad4 Token grace period (#64938)
* Add a grace period to token checks

There's more work on this namespace to be done i think, but this is a
first cut at it. There's a lot of control flow by exceptions which is
how we jump around in here. Fundamentally this should be far
simpler. Will take a crack at that shortly. I also don't love that this
just hammers the `fetch-token-status` function and then memoizes inside
of that. Would prefer simpler layout of `token-features` function and
that can be aware of population issues.

Adds a simple protocol: GracePeriod, which has two functions: save! and
retrieve. On successful token check, we `save!` the response. On errors,
we `retrieve` previous responses. This obviously can be nil in the case
we have never had a successful response, and will become nil once the
grace period's internal notion of time expires.

This implementation is based on guava's cache which has a nifty
expireafterwrite functionality.

```
 (*token-features*) ;; call this function to simulate the check of features
Checking with the MetaStore to see whether token 'f325...d01a' is valid...
Reporting Metabase stats: {... user counts etc}
 -> #{"features come back"}
 ;; meanwhile clear cache to simulate elapsing of 12 hours

 (*token-features*) ;; call function again to simulate check of features
2025-10-22 21:30:26,620 INFO premium-features.token-check :: Checking with the MetaStore to see whether token 'f325...d01a' is valid...
2025-10-22 21:30:26,622 ERROR premium-features.token-check :: Error fetching token status from https://token-check.metabase.com:
clojure.lang.ExceptionInfo: network issues ;; hit network issue

2025-10-22 21:30:26,632 INFO premium-features.token-check :: Using token from grace period
->> #{graceperiod network features}
...

;; here after 5 seconds (in real life will be 36 hours)
2025-10-22 21:31:00,064 WARN premium-features.token-check :: Removing token: f325...d01a from grace period cache {mb-quartz-job-type=Cache}
```

* tests that updating value populates grace period cache

* couple changes

protect against storing nil value. guava cache doesn't like it so gone
it is.

added some tests:

```clojure
(testing "Setting a new value populates the grace period cache"
    (let [new-token (tu/random-token)]
      (binding [http/request (fn [& _] {:status 200
                                        :body "{\"valid\":true,\"status\":\"fake\",\"features\":[\"fake\",\"features\"]}"})]
        (mt/discard-setting-changes [premium-embedding-token]
          (premium-features.settings/premium-embedding-token! new-token)
          (is (= #{"fake" "features"} (token-check/*token-features*)))
          (is (= {:valid true :status "fake" :features ["fake" "features"]}
                 (token-check/retrieve token-check/grace-period new-token)))))))
```

But this ended up leaving a setting table value for this value. i don't
feel like looking into discard setting changes so i'm gonna just remove it

* attempt to simplify the api a bit

the thee important functions are now `token-information`, `harness` and
`decode-token`.

Everyone should use token-information. Harness hooks up the grace period
and retry strategies, and `decode-token` only cares about decoding a
token. It should return the token-status map {:valid true ...} or throw.

* fixup test

* clean up tests and rename a bit

* remove comment block

* remove commented out grace period

* bit of cleanup

* fix with-random-premium-token! macro

* function composes them instead of caller

rather than a caller needing to know all of the layers, i thread them
for you and let you provide all arugments in one function call.

dynamic var for needing to customize layers in tests. largely for
removing the circuit-breaker which is stateful and hard to restart if
you want to simulate errors in tests

* rename test
2025-10-30 08:51:56 -05:00
Damien Chambe
07172f56f7 Update DB2 driver and IBM i driver (#65190)
IBM i has a separate driver , different from DB2 LUW ( linux/unix/windows )
2025-10-30 08:56:12 -04:00
Ngoc Khuat
9f93683518 Usage analytics update v57 (#65055)
* Add documents to content view

* add document to audit_log

* added comment events to the audit log, publish events

* wip: transform events

* glossary

* reversion the content migrations

* include transforms in content

* remote sync audit events

* wip: action v2 event

* kondo

* fix action tests

* transform run event

* add tests for new events

* bump

* tests

* task data

* let's not change the old migration in case we might break the hashsum

* typo

* more typos

* fix bugs in h2/mysql

* add :previous-object

* fix tests

* move branch into details

* fix test

* fix: run tests only on ee

---------

Co-authored-by: Nicola Mometto <nicola.mometto@metabase.com>
2025-10-30 10:43:48 +00:00
Sébastien
23574a80d5 Closes UXW-1993 tooltip columns in visualizer (#65042) 2025-10-30 07:05:27 +01:00
appleby
74113f603b Add :order-by to metabase-enterprise.transforms.api/get-transforms (#65162)
To ensure transforms are returned in a consistent order to and reduce test flakes.

https://metaboat.slack.com/archives/C5XHN8GLW/p1761753664842279
2025-10-30 01:11:13 +00:00
Cam Saul
622125d9d9 Disable Claude code review bot by default (#65184) 2025-10-29 21:04:51 -04:00
Sébastien Corbin
f6b1864d91 Add color-scheme meta tag for light and dark modes (#64324) 2025-10-29 18:20:16 -06:00
metamben
6b098da5de Normalize parameter type category/= to category (#65158)
* Normalize parameter type category/= to category

Stats had exactly one dashboard with one such parameter and that dashboard was immutable because the
before-update hook failed before any update could happen.
2025-10-29 23:42:40 +00:00
Ryan Laurie
6b09c0476c dont break scheduled patches (#65165) 2025-10-29 16:30:18 -06:00
Nathan Voxland
a94c284625 Remote-sync error handling improvements (#65072)
* - Improve remote-sync error messages
- Do a fetch when checking git settings to ensure the current version can be read and is being checked

* Validate git url

* Validate branch name in production mode

* Validate branch name in production mode

* Removed unneeded assoc

* Fixed formatting

* Code improvements

* Code improvements

* Allow direct path URLs

* Allow direct path URLs

* E2e Fixes

* E2e Fixes

* Allow empty branch to be passed
2025-10-29 14:15:33 -07:00
Nick Fitzpatrick
fdac82dba2 show a warning message when removing items from the library (#65169) 2025-10-29 14:00:31 -07:00
Denis Berezin
46b8b2791d UXW-1872 Fix some tooltips text color in dark theme (#65182) 2025-10-29 23:52:59 +03:00
Cam Saul
fd476e892b Fix slow metabase.core.modules-test/modules-config-up-to-date-test (#65168)
* Fix slow `metabase.core.modules-test/modules-config-up-to-date-test`

* Fix docstring location

* The bot caught something else
2025-10-29 12:30:22 -07:00
Timofey Kachalov
63f85c3706 feat(embed-js): Convert EmbedJS wizard into a modal (#65113) 2025-10-29 23:03:34 +04:00
Nick Fitzpatrick
9c6e1d1b7d Dark mode day 5 patch (#65099)
* Dark Mode Dashboard PDFS, bad solution for google login

* various fixes

* handfull of fixes

* PR Feedback

* stupid linter
2025-10-29 11:33:22 -07:00
Cam Saul
7d879a9a86 Legacy MBQL normalization overhaul: 3x faster and bug fixes (#65018)
* Legacy MBQL normalization overhaul

* Kondo + test fixes 🔧

* Cleanup and test fixes 🔧

* Code cleanup

* Test fixes 🔧

* Extra test 🔧

* Some test fixes 🔧

* Test fixes 🔧

* Test fixes 🔧

* Test fixes 🔧

* Fix SerDes test failure

* cljfmt

* Code cleanup

* Fix normalizing :datetime with bytes modes

* Fix legacy MBQL normalization of :datetime

* Handle broken case clauses

* Set Card metadata to nil when invalid

* Fixx

* Fix Kondo
2025-10-29 11:18:28 -07:00
Marcos
80ac5931a0 Fix x axis range calculation when undefined values are present (#65125)
* fix x axis range calculation when null values are present

* only remove undefined values

* rename variable instead of mutating function param
2025-10-29 15:11:14 -03:00
Jeff Bruemmer
fabb975482 docs - public documents and downloads (#65155)
* document public links and downloads

* edits

* link fixes

* Update docs/embedding/public-links.md
2025-10-29 17:57:05 +00:00
Timofey Kachalov
d1c40b6c81 Restore sdk backward compat tests (#65154) 2025-10-29 19:20:08 +04:00
Nemanja Glumac
95fa314e44 Delete superfluous test (#65153)
This is already covered in LicenseAndBillingSettings.unit.spec.tsx
2025-10-29 14:51:55 +00:00
Nick Fitzpatrick
5ded6d9623 Remote sync e2e followup (#65061)
* Fix/unskip some tests / try to make flaky FE test to pass in CI

* adding branching tests, unskipping admin tests

* PR Feedback

* PR Feedback

---------

Co-authored-by: Anderson <anderson@metabase.com>
2025-10-29 11:37:29 -03:00
Nick Fitzpatrick
4c160134ba only delay modal dismiss on success (#65127) 2025-10-29 11:29:06 -03:00
Nemanja Glumac
46894a8008 Update module ownership (#65150) 2025-10-29 15:11:48 +01:00
Nemanja Glumac
215a3c6c49 Fix the hard coded store api url in billing (#65135) 2025-10-29 14:05:30 +00:00
Jeff Bruemmer
4d14b02aa2 documents - add public links (#64630) 2025-10-29 13:38:57 +00:00
Noah Moss
6bcfc60eff Add source_type field to transforms with temporary backfill job (#64970)
* Add type field to transforms with temporary backfill job

* add a default value for tests

* add some new tests, fix serdes

* lint

* remove debugging defs

* revert serdes spec change

* Revert "remove transforms from serdes baseline (?)"

This reverts commit e8fc8fe80bfe15e00eb031b4050877f271b8081f.

* try again to fix serialization tests

* address bot comments

* Revert "try again to fix serialization tests"

This reverts commit 13d78664b79b7f13406d89e1f8f910610ea2cce9.

* Fix search ingestion functions to use :type field + some cleanup

* Update baseline to fix serialization test

* Revert "Update baseline to fix serialization test"

This reverts commit 60cb7909e5a73d04c42d36c915a32bb28d684e37.

* fix up comment

* reset serialization_baseline to version on master

* let's try this again: manually update baseline to add type field

* fix search tests by adding correct types to transfomrs

* update metabot tool apis

* fix revision test

* simplify test

* address feedback - move type setting to the model layer

* simplify tests

* Fix up transform serdes tests: remove top-level type fields and updated_at from being serialized, and fix shape of transforms in extraction tests

* set :type after select just in case; fix serdes tests again

* guard against empty source on select

* remove redundant search spec for transforms (introduced via a previous merge)

* switch from type to source_type to avoid conflict with type field on the frontend

* add better error handling
2025-10-29 08:51:20 -04:00
Timofey Kachalov
1bbe525200 Adjust sample-apps runner for the new token check (#65139) 2025-10-29 16:39:55 +04:00
Phoomparin Mano
83b0eb3174 fix(sdk): secondary background color is not mapped to theme (#65116) 2025-10-29 19:14:15 +07:00
Nicolò Pretto
eeb44b4b5a remove .local reference from rspack as .local lookup is slow and we can (#65060)
use .localhost
2025-10-29 12:08:53 +01:00
Nicola Mometto
0e20f5a8b8 respect column definition order for transform create-table (#65089)
* feat: respect column definition order for transform create-table

* add test
2025-10-29 10:10:51 +00:00
Sébastien
92dad88e6a Closes UXW-2112 preserve default colors when renaming breakout values in cartesian charts (#65053)
* Add tests for getSeriesColors with custom titles

* Closes UXW-2112 custom colors breakout labels

* .
2025-10-29 07:16:52 +01:00
Mahatthana (Kelvin) Nomsawadi
94e1c1e387 fix(sdk): Avoid portal root taking space under flex parents (#65088)
* Avoid portal root taking space under flex parents

* Add missing comment

* Preserve format
2025-10-29 02:32:02 +00:00
Nemanja Glumac
6c6b702b29 Enable Trunk Quarantine for general backend tests (#65128) 2025-10-29 02:17:39 +01:00
Aleksandr Lesnenko
38e2e81388 refetch settings after updating remote sync settings (#65124)
* refetch settings after updating remote sync settings

* specs
2025-10-29 01:00:45 +00:00
Nemanja Glumac
5b2fd35367 Enable Trunk Quarantine for drivers (#64995) 2025-10-29 01:24:54 +01:00
Cam Saul
527b8e8e9a Add custom Kondo linter for defendpoint query parameter naming (#65114)
* Add custom Kondo linter for defendpoint query parameter naming

* cljfmt
2025-10-28 17:17:25 -07:00
William
82ea0f4f7e Fix default tag values for temporal template tags (#65112)
This should stop the log spam and fix dependency backfilling
2025-10-28 17:31:41 -05:00
William
39ceced98f Add support for table-functions and selecting tables directly (#65074)
Basically, the same case found two unrelated bugs.  For one, we don't support table functions like `select * from
my_function()`.  For another, `select orders from orders` is also unsupported but apparently legal (at least in
postgres).  This updates sql parsing/validation to support both things.
2025-10-28 17:31:21 -05:00
Ryan Laurie
a67ad3b258 Correct tooltips across map zoom levels (#65080)
* better event handler attachment logic to account for array size change

* test tooltip correctness
2025-10-28 16:31:07 -06:00
Oleksandr Solovyov
bc6694c1a1 no more Workflows team (#64983) 2025-10-29 00:28:39 +02:00
Jeff Bruemmer
c257c954fb docs -remote sync (#65009)
* draft

* notes

* edits

* edits

* updates

* numbering and links

* edits

* edits

* typos
2025-10-28 22:00:23 +00:00
Nemanja Glumac
689d4f0e9b Run e2e tests using staging tokens (#65044)
This pull request updates the configuration and environment handling for E2E and compatibility tests, mainly to support running tests against a staging license/token server and to improve test reliability. The changes affect GitHub Actions workflows, environment variables, and some test and backend logic.

*Backend Logic for E2E Mode*

Added `is-e2e?` flag in core.clj to distinguish E2E test runs from dev/prod/test modes, allowing for custom behavior in E2E scenarios.
Modified token check logic in token_check.clj to allow E2E tests to use a staging server for license validation.
Changed store API settings in settings.clj to use staging endpoints when in dev or E2E mode, ensuring tests interact with the correct backend.
2025-10-28 22:57:14 +01:00
eliotmetabase
c831d2cabf Update error message to make it more obvious things will be deleted (#65117)
* Update error message to make it more obvious things will be deleted

* Better copy

Co-authored-by: Ryan Laurie <30528226+iethree@users.noreply.github.com>

* Update button text as well

---------

Co-authored-by: Ryan Laurie <30528226+iethree@users.noreply.github.com>
2025-10-28 14:50:46 -07:00
metamben
bbb0074de4 Fix dependencies backfilling: ignore analysis errors (#65078)
* Fix dependencies backfilling: ignore analysis errors

Fixes QUE-2714

* Catch everything that can fly

* Rename error ignoring macro
2025-10-28 21:12:06 +00:00
Ryan Laurie
d3b69c4c86 DANGEROUSLY allow patches on red commits (#58260)
* DANGEROUSLY allow patches on red commits

* allow override sha

* throw on invalid override

* handle undefined
2025-10-28 13:34:57 -06:00
Cam Saul
ae17be3ee1 Add custom Kondo linter to enforce kebab-case in REST API routes (#65100)
* Add Kondo linter to enforce kebab-case in REST API routes

* Remove Claude guidelines (no longer needed)
2025-10-28 19:01:34 +00:00
Nathan Voxland
4f9dc213ed Fix some indexing race conditions (#64783) 2025-10-28 13:47:15 -05:00
Riley Thompson
280e416af4 exclude databricks from database-schema-filtering-test (#65106) 2025-10-28 18:35:43 +00:00
Alex Yarosh
5db25732ee Update documentation for MB_ATTACHMENT_ROW_LIMIT (#65104) 2025-10-28 18:16:34 +00:00
Oleksandr Yakushev
c51d5b5f79 [malli] Don't include docstrings in mu/defn when compiling CLJS (#63793) 2025-10-28 19:53:35 +02:00
Alexander Polyankin
5b8a087754 Fix search with documents (#65000) 2025-10-28 17:42:09 +00:00
Vamsi Peri
7611b467f3 Remove some instructions from CLAUDE.md (#65103)
Removed instructions and comments regarding emoji usage, spelling conventions, tarot card readings, and formatting for specific users.
2025-10-28 13:29:51 -04:00
Nicolò Pretto
9ac8f80da8 feat(sdk): adds handleLink to customize how links should be open (#64960)
* poc of handleLink

* safer implementation

* make it return a boolean to prevent default

* fix types?

* fix static viz build

* adds tests

* make tests more consistents with fns

* test return value undefined

* Update enterprise/frontend/src/embedding-sdk-shared/lib/sdk-global-plugins.ts

Co-authored-by: metabase-bot[bot] <109303359+metabase-bot[bot]@users.noreply.github.com>

* refactor plugin call

* fix types

* removed reduntant test

* change the api to use `{handled: boolean}`

* support links rendered as anchor tags, refactor the logic and tests

* add story

---------

Co-authored-by: metabase-bot[bot] <109303359+metabase-bot[bot]@users.noreply.github.com>
2025-10-28 18:05:28 +01:00
Alexander Polyankin
6ef2472613 Prepare dependencies for v57 (#65093) 2025-10-28 16:25:13 +00:00
Phoomparin Mano
c24bea6939 Make HoverCard dropdown default to bg-primary (#65047)
Co-authored-by: Ryan Laurie <iethree@gmail.com>
2025-10-28 23:19:13 +07:00
Edward Paget
8d09595bb8 Remove the instruction to indent docstrings (#65094)
* Remove the instruction to indent docstrings

* Remove example
2025-10-28 10:57:41 -05:00
Riley Thompson
4a23fc0ee0 Fix add interval honeysql form (#65091)
* add back driver hierarchy

* use driver instead of db-type
2025-10-28 15:28:54 +00:00
Sébastien
e23658dd9a Closes EMB-928 sdk popover flashing at 0,0 (#65086) 2025-10-28 16:17:45 +01:00
Mahatthana (Kelvin) Nomsawadi
afaee50a4c fix(sdk): Fix missing SDK CSS custom properties (#65084)
* Follow core app color order

* Add missing CSS custom properties

* Revert "Follow core app color order"

This reverts commit 01a6a17483.
2025-10-28 14:06:23 +00:00
1394 changed files with 640794 additions and 552365 deletions

View File

@@ -56,20 +56,22 @@
;;
;; globally-enabled custom linters
;;
:metabase/check-defmulti-arglists {:level :warning}
:metabase/check-me-humanize {:level :warning}
:metabase/defsetting-must-specify-export {:level :warning}
:metabase/defsetting-namespace {:level :warning}
:metabase/mbql-query-first-arg {:level :warning}
:metabase/missing-test-expr-requires-in-cljs {:level :warning}
:metabase/modules {:level :warning} ; more config in `.clj-kondo/config/modules/config.edn`
:metabase/namespace-name {:level :warning}
:metabase/require-shape-checker {:level :warning}
:metabase/test-helpers-use-non-thread-safe-functions {:level :warning} ; more config in `.clj-kondo/config/test-helpers/config.edn`
:metabase/validate-logging {:level :warning}
:metabase/validate-mb-driver-tests {:level :warning}
:metabase/validate-mb-once {:level :warning}
:metabase/discourage-millis-duration {:level :warning}
:metabase/check-defmulti-arglists {:level :warning}
:metabase/check-me-humanize {:level :warning}
:metabase/defsetting-must-specify-export {:level :warning}
:metabase/defsetting-namespace {:level :warning}
:metabase/discourage-millis-duration {:level :warning}
:metabase/mbql-query-first-arg {:level :warning}
:metabase/missing-test-expr-requires-in-cljs {:level :warning}
:metabase/modules {:level :warning} ; more config in `.clj-kondo/config/modules/config.edn`
:metabase/namespace-name {:level :warning}
:metabase/require-shape-checker {:level :warning}
:metabase/test-helpers-use-non-thread-safe-functions {:level :warning} ; more config in `.clj-kondo/config/test-helpers/config.edn`
:metabase/validate-defendpoint-route-uses-kebab-case {:level :warning}
:metabase/validate-defendpoint-query-params-use-kebab-case {:level :warning}
:metabase/validate-logging {:level :warning}
:metabase/validate-mb-driver-tests {:level :warning}
:metabase/validate-mb-once {:level :warning}
:metabase/validate-deftest
{:level :warning
@@ -551,6 +553,8 @@
metabase.embedding.api.embed-test/with-temp-card hooks.common/let-one-with-optional-value
metabase.embedding.api.embed-test/with-temp-dashcard hooks.common/let-one-with-optional-value
metabase.legacy-mbql.schema.macros/defclause hooks.metabase.legacy-mbql.schemas.macros/defclause
metabase.legacy-mbql.schema.macros/defclause* hooks.metabase.legacy-mbql.schemas.macros/defclause*
metabase.legacy-mbql.schema.macros/one-of hooks.metabase.legacy-mbql.schemas.macros/one-of
metabase.lib.schema.mbql-clause/define-catn-mbql-clause hooks.metabase.lib.schema.mbql-clause/define-mbql-clause
metabase.lib.schema.mbql-clause/define-mbql-clause hooks.metabase.lib.schema.mbql-clause/define-mbql-clause
metabase.lib.schema.mbql-clause/define-tuple-mbql-clause hooks.metabase.lib.schema.mbql-clause/define-mbql-clause
@@ -898,7 +902,9 @@
performance-sensitive
{:linters
{:discouraged-var
{clojure.core/every? {:message "Use metabase.util.performance/every?"}
{clojure.core/empty? {:message "Use metabase.util.performance/empty?"}
clojure.core/not-empty {:message "Use metabase.util.performance/not-empty"}
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"}
@@ -907,7 +913,9 @@
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"}}}}
clojure.walk/walk {:message "Use metabase.util.performance/walk"}
clojure.walk/for {:message "Use metabase.util.performance/for"}
clojure.walk/doseq {:message "Use metabase.util.performance/doseq"}}}}
qp-and-driver-source-namespaces
{:linters

View File

@@ -46,7 +46,7 @@
;; you need to make
{:metabase/modules
{actions
{:team "Workflows"
{:team "Gadget"
:api #{metabase.actions.api
metabase.actions.args
metabase.actions.core
@@ -249,7 +249,7 @@
;; TODO -- way too many API namespaces.
channel
{:team "Workflows"
{:team "Gadget"
:api #{metabase.channel.api
metabase.channel.core
metabase.channel.email
@@ -381,7 +381,7 @@
core
{:team "UX West"
:api #{metabase.core.initialization-status}
:api #{}
:uses :any}
dashboards
@@ -557,9 +557,10 @@
util}}
glossary
{:team "Workflows"
{:team "Gadget"
:api #{metabase.glossary.api}
:uses #{api
events
models
util}}
@@ -584,6 +585,11 @@
task
util}}
initialization-status
{:team "UX West"
:api #{metabase.initialization-status.core}
:uses #{}}
internal-stats
{:team "UX West"
:api #{metabase.internal-stats.core}
@@ -604,6 +610,7 @@
:api #{metabase.lib.binning
metabase.lib.binning.util
metabase.lib.card
metabase.lib.computed ; temporarily so that `qp.compile` can use it as lib memoization evolves
metabase.lib.core
metabase.lib.equality
metabase.lib.field
@@ -740,7 +747,7 @@
util}}
notification
{:team "Workflows"
{:team "Gadget"
:api #{metabase.notification.api
metabase.notification.core
metabase.notification.init
@@ -794,9 +801,9 @@
permissions
{:team "UX West"
:api #{metabase.permissions.api
metabase.permissions.core
metabase.permissions.init}
:api #{metabase.permissions.core
metabase.permissions.init
metabase.permissions.schema}
:uses #{api
app-db
audit-app
@@ -807,11 +814,21 @@
models
premium-features
remote-sync
request
settings
util
enterprise/advanced-permissions}}
permissions-rest
{:team "UX West"
:api #{metabase.permissions-rest.api}
:uses #{api
audit-app
events
permissions
premium-features
request
util}}
pivot
{:team "UX West"
:api #{metabase.pivot.core}
@@ -875,7 +892,7 @@
util}}
pulse
{:team "Workflows"
{:team "Gadget"
:api #{metabase.pulse.api
metabase.pulse.core
metabase.pulse.init}
@@ -906,7 +923,7 @@
metabase.queries.core
metabase.queries.init
metabase.queries.models.query ; TODO FIXME
metabase.queries.schema} ; TODO FIXME
metabase.queries.schema} ; TODO FIXME
:uses #{analytics
analyze
api
@@ -1035,7 +1052,7 @@
:uses #{api
config
embedding
permissions ; FIXME
permissions ; FIXME
session
settings
users
@@ -1131,9 +1148,9 @@
app-db
appearance
config
core
driver
embedding
initialization-status
lib-be
premium-features
query-processor
@@ -1150,7 +1167,7 @@
metabase.session.core
metabase.session.init
metabase.session.models.session ; TODO -- shouldn't be exposed as an API namespace
metabase.session.settings} ; TODO -- shouldn't be exposed as an API namespace
metabase.session.settings} ; TODO -- shouldn't be exposed as an API namespace
:uses #{api
app-db
channel
@@ -1167,19 +1184,25 @@
settings
{:team "DevEx"
:api #{metabase.settings.api
metabase.settings.core
:api #{metabase.settings.core
metabase.settings.init}
:uses #{api
app-db
config
events
models
permissions
premium-features
util
enterprise/advanced-permissions}}
settings-rest
{:team "DevEx"
:api #{metabase.settings-rest.api}
:uses #{api
permissions
settings
util}}
setup
{:team "UX West"
:api #{metabase.setup.api
@@ -1503,12 +1526,13 @@
warehouse-schema}}
enterprise/action-v2
{:team "Workflows"
{:team "Gadget"
:api #{metabase-enterprise.action-v2.api
metabase-enterprise.action-v2.init}
:uses #{actions
api
driver
events
lib
models
query-processor
@@ -1584,8 +1608,14 @@
enterprise/api
{:team "UX West"
:api #{metabase-enterprise.api.routes
metabase-enterprise.api.routes.common}
:api #{metabase-enterprise.api.core}
:uses #{api
premium-features
util}}
enterprise/api-routes
{:team "UX West"
:api #{metabase-enterprise.api-routes.routes}
:uses :any}
enterprise/audit-app
@@ -1621,7 +1651,9 @@
{:team "UX West"
:api #{metabase-enterprise.billing.api.routes}
:uses #{api
premium-features util}}
premium-features
store-api
util}}
enterprise/bookmarks
{:team "UX West"
@@ -1643,11 +1675,12 @@
:uses #{api
events
premium-features
store-api
util
enterprise/harbormaster}}
enterprise/comments
{:team "Workflows"
{:team "UX West"
:api #{metabase-enterprise.comments.api
metabase-enterprise.comments.init}
:uses #{analytics
@@ -1683,7 +1716,7 @@
:uses :any}
enterprise/dashboard-subscription-filters
{:team "Workflows"
{:team "Querying"
:api #{}
:uses #{premium-features}}
@@ -1731,6 +1764,7 @@
lib-be
models
native-query-snippets
permissions
premium-features
queries
query-processor
@@ -1754,8 +1788,10 @@
events
models
premium-features
public-sharing
queries
query-permissions
query-processor
revisions
search
util
@@ -1887,6 +1923,16 @@
:uses #{premium-features
util}}
enterprise/public-sharing
{:team "UX West"
:api #{metabase-enterprise.public-sharing.api}
:uses #{api
events
premium-features
public-sharing
query-processor
util}}
enterprise/remote-sync
{:team "UX West"
:api #{metabase-enterprise.remote-sync.api
@@ -1900,8 +1946,8 @@
models
premium-features
settings
startup
task
task-history
util
enterprise/serialization}}
@@ -1972,7 +2018,7 @@
enterprise/metabot-v3}}
enterprise/serialization
{:team "Workflows"
{:team "Querying"
:api #{metabase-enterprise.serialization.api
metabase-enterprise.serialization.cmd
metabase-enterprise.serialization.core

View File

@@ -1,7 +1,67 @@
(ns hooks.metabase.api.macros
(:require
[clj-kondo.hooks-api :as api]
[hooks.common]))
[clojure.string :as str]))
(defn- validate-route!
"Make sure the route uses kebab-case rather than snake_case."
[route]
(letfn [(validate-route-string! [route-string]
(when (and (api/string-node? route-string)
(str/includes? (api/sexpr route-string) "_"))
(api/reg-finding! (assoc (meta route-string)
:message "REST API routes and query params should use kebab-case, not snake_case"
:type :metabase/validate-defendpoint-route-uses-kebab-case))))]
(cond
(api/string-node? route)
(validate-route-string! route)
;; otherwise route is a vector like ["/abc/:d/" :d <regex>]
(api/vector-node? route)
(validate-route-string! (first (:children route))))))
(defn- validate-query-params!
"Make sure query params use kebab-case rather than snake_case.
This only works on inline schemas for now. If you define the schema elsewhere then we'd have to implement this
validation in Clojure-land since we can't resolve the schemas in Kondo. It should however still work on complicated
schemas like
[:merge <map-1> <map-2>]"
[query-param-schema-node]
(letfn [(map-schema? [node]
(and (api/vector-node? node)
(when-let [first-child (first (:children node))]
(and (api/keyword-node? first-child)
(= (api/sexpr first-child) :map)))))
(map-schema-keys [{:keys [children], :as _node}]
(let [child-schemas (if (api/map-node? (second children))
(drop 2 children)
(drop 1 children))]
(keep (fn [child-schema]
(when (api/vector-node? child-schema)
(when-let [k (first (:children child-schema))]
(when (api/keyword-node? k)
k))))
child-schemas)))
(validate-map-schema! [form]
;; only warn once per endpoint -- just once on the first bad node
(when-let [bad-node (some (fn [key-node]
(when (str/includes? (str (api/sexpr key-node)) "_")
key-node))
(map-schema-keys form))]
(api/reg-finding! (assoc (meta bad-node)
:message "REST API routes and query params should use kebab-case, not snake_case"
:type :metabase/validate-defendpoint-query-params-use-kebab-case))))
(validate! [node]
(cond
(and (api/vector-node? node)
(map-schema? node))
(validate-map-schema! node)
(api/vector-node? node)
(doseq [child (:children node)]
(validate! child))))]
(validate! query-param-schema-node)))
(defn defendpoint
[arg]
@@ -18,16 +78,21 @@
(cons nil more))
[params & body] more
[bindings schemas] (when (api/vector-node? params)
(loop [bindings [], schemas [], [x y & more] (:children params)]
(loop [bindings [], schemas [], [x y z & more] (:children params)]
(cond
(not x)
[bindings schemas]
(= (api/sexpr x) :-)
(recur bindings (conj schemas y) more)
(and (api/keyword-node? y)
(= (api/sexpr y) :-))
(recur (conj bindings x) (conj schemas z) more)
:else
(recur (conj bindings x) schemas (cons y more)))))]
(recur (conj bindings x) (conj schemas nil) (list* y z more)))))]
(validate-route! route)
(let [[_route-param-schema query-param-schema _body-param-schema] schemas]
(when query-param-schema
(validate-query-params! query-param-schema)))
(-> (api/list-node
(list
(api/token-node 'do)
@@ -54,3 +119,27 @@
body))))
(with-meta (meta node)))))]
(update arg :node update-defendpoint)))
(comment
(defn -defendpoint [form]
(-> {:node (-> form pr-str api/parse-string)}
defendpoint
:node
api/sexpr))
(defn x []
(-defendpoint '(api.macros/defendpoint :get "/:id/syncable_schemas" ; snake_case route should trigger a warning
"Returns a list of all syncable schemas found for the database `id`."
[{:keys [id]} :- [:map
[:id ms/PositiveInt]]
;; snake_case query parameter, should trigger a warning
{:keys [filter_by]} :- [:map
[:filter_by {:optional true} :string]]]
(let [db (get-database id)]
(api/check-403 (or (:is_attached_dwh db)
(and (mi/can-write? db)
(mi/can-read? db))))
(->> db
(driver/syncable-schemas (:engine db))
(vec)
(sort)))))))

View File

@@ -33,18 +33,36 @@
(defclause [ag:var var] field-or-expression FieldOrExpressionDef)
=>
(def ag:var [FieldOrExpressionDef])"
[{:keys [node]}]
(let [[_defclause clause-name-form & arg-specs] (:children node)]
{:node (-> (hooks/list-node
(list
(hooks/token-node 'def)
(unwrap-defclause-clause-name clause-name-form)
(hooks/string-node "Docstring.")
(collect-defclause-body-schemas arg-specs)))
(with-meta (meta node)))}))
[{:keys [node], :as x}]
(let [[_defclause clause-name & arg-specs] (:children node)]
(assoc x :node (-> (hooks/list-node
(list
(hooks/token-node 'do)
(-> (hooks/keyword-node (keyword "metabase.legacy-mbql.schema" (name (hooks/sexpr clause-name))))
(with-meta (meta clause-name))
(hooks/reg-keyword! 'metabase.legacy-mbql.schemas.macros/defclause))
(collect-defclause-body-schemas arg-specs)))
(with-meta (meta node))))))
(defn defclause*
"e.g.
(defclause [ag:var var] field-or-expression FieldOrExpressionDef)
=>
(def ag:var [FieldOrExpressionDef])"
[{:keys [node], :as x}]
(let [[_defclause clause-name schema] (:children node)]
(assoc x :node (-> (hooks/list-node
(list
(hooks/token-node 'do)
(-> (hooks/keyword-node (keyword "metabase.legacy-mbql.schema" (name (hooks/sexpr clause-name))))
(with-meta (meta clause-name))
(hooks/reg-keyword! 'metabase.legacy-mbql.schemas.macros/defclause*))
schema))
(with-meta (meta node))))))
(comment
(defn- defclause* [form]
(defn- expand-defclause [form]
(hooks/sexpr
(:node
(defclause
@@ -55,15 +73,35 @@
form)))}))))
(defn- x []
(defclause* '(defclause [ag:var var]
field-or-expression FieldOrExpressionDef)))
(expand-defclause '(defclause var
field-or-expression FieldOrExpressionDef)))
;; =>
(def ag:var "Docstring." [FieldOrExpressionDef])
(do :metabase.legacy-mbql.schema/var [FieldOrExpressionDef])
(defn- y []
(defclause* '(defclause var
x (some-list-schema)
y (optional FieldOrExpressionDef)
z (rest (some-other-schema)))))
(expand-defclause '(defclause var
x (some-list-schema)
y (optional FieldOrExpressionDef)
z (rest (some-other-schema)))))
;; =>
(def var "Docstring." [(some-list-schema) FieldOrExpressionDef (some-other-schema)]))
(do :metabase.legacy-mbql.schema/var [(some-list-schema) FieldOrExpressionDef (some-other-schema)]))
(defn one-of [{:keys [node], :as x}]
(let [[_one-of & schema-nodes] (:children node)
node' (-> (hooks/vector-node
(mapv (fn [schema-node]
(if (and (hooks/token-node? schema-node)
(simple-symbol? (hooks/sexpr schema-node)))
(-> (hooks/keyword-node (keyword "mteabase.legacy-mbql.schema" (name (hooks/sexpr schema-node))))
(with-meta (meta schema-node)))
schema-node))
schema-nodes))
(with-meta (meta node)))]
(assoc x :node node')))
(comment
(defn- expand-one-of [form]
(hooks/sexpr (:node (one-of {:node (hooks/parse-string (with-out-str (clojure.pprint/pprint form)))}))))
(defn- z []
(expand-one-of '(one-of absolute-datetime relative-datetime time))))

View File

@@ -1,6 +1,7 @@
(ns hooks.metabase.api.macros-test
(:require
[clj-kondo.hooks-api :as api]
[clj-kondo.impl.utils]
[clojure.test :refer :all]
[hooks.metabase.api.macros]))
@@ -69,3 +70,41 @@
(respond :x)
(catch Throwable e
(raise e))))))))
(defn- defendpoint [form]
(hooks.metabase.api.macros/defendpoint
{:node (-> form pr-str api/parse-string)}))
(defn- defendpoint-warnings
[form]
(binding [clj-kondo.impl.utils/*ctx* {:config {:linters {:metabase/validate-defendpoint-route-uses-kebab-case {:level :warning}
:metabase/validate-defendpoint-query-params-use-kebab-case {:level :warning}}}
:ignores (atom nil)
:findings (atom [])
:namespaces (atom {})}]
(defendpoint form)
@(:findings clj-kondo.impl.utils/*ctx*)))
(deftest ^:parallel validate-route-kebab-case-test
(is (=? [{:message "REST API routes and query params should use kebab-case, not snake_case"
:type :metabase/validate-defendpoint-route-uses-kebab-case
:row pos-int?
:col pos-int?}]
(defendpoint-warnings
'(api.macros/defendpoint :get "/:id/syncable_schemas" ; snake_case route should trigger a warning
"Returns a list of all syncable schemas found for the database `id`."
[{:keys [id]}]
id)))))
(deftest ^:parallel validate-query-params-kebab-case-test
(is (=? [{:message "REST API routes and query params should use kebab-case, not snake_case",
:type :metabase/validate-defendpoint-query-params-use-kebab-case
:row pos-int?
:col pos-int?}]
(defendpoint-warnings
'(api.macros/defendpoint :get "/:id/syncable-schemas"
"Returns a list of all syncable schemas found for the database `id`."
[{:keys [id]}
{:keys [filter_by]} :- [:map
[:filter_by {:optional true} :string]]]
id)))))

View File

@@ -2,3 +2,4 @@ frontend/src/cljs
frontend/src/cljs_release
e2e/support/cypress_sample_database.js
e2e/support/cypress_sample_instance_data.js
e2e/embedding-sdk-host-apps

View File

@@ -94,10 +94,7 @@ module.exports = {
"react/jsx-no-target-blank": 2,
"react/jsx-key": 2,
"react/forbid-component-props": [2, { forbid: ["sx"] }],
"react-hooks/exhaustive-deps": [
"warn",
{ additionalHooks: "(useSafeAsyncFunction)" },
],
"react-hooks/exhaustive-deps": ["warn"],
"prefer-const": [1, { destructuring: "all" }],
"no-restricted-globals": ["error", "close"],
"no-useless-escape": 0,

View File

@@ -10,6 +10,9 @@ outputs:
node-cache-key:
description: "The cache key for the Node.js cache."
value: ${{ steps.keys-factory.outputs.node-cache-key }}
eslint-cache-key:
description: "The cache key for Eslint cache"
value: ${{ steps.keys-factory.outputs.eslint-cache-key }}
runs:
using: "composite"
@@ -19,9 +22,11 @@ runs:
run: |
M2_CACHE_PREFIX='M2'
NODE_CACHE_PREFIX='node-modules'
ESLINT_CACHE_PREFIX='eslint'
WEEK_OF_YEAR=$(/bin/date "+%G-%V")
CACHE_SUFFIX="${{ runner.os }}-$WEEK_OF_YEAR"
echo "m2-cache-key=$M2_CACHE_PREFIX-$CACHE_SUFFIX" >> $GITHUB_OUTPUT
echo "node-cache-key=$NODE_CACHE_PREFIX-$CACHE_SUFFIX" >> $GITHUB_OUTPUT
echo "eslint-cache-key=$ESLINT_CACHE_PREFIX-$CACHE_SUFFIX" >> $GITHUB_OUTPUT
shell: bash

View File

@@ -1,31 +0,0 @@
name: Run Embedding SDK Storybook
runs:
using: "composite"
steps:
- name: Prepare frontend environment
uses: ./.github/actions/prepare-frontend
- name: Prepare back-end environment
uses: ./.github/actions/prepare-backend
- name: Compile CLJS
run: yarn build-pure:cljs
shell: bash
- name: Build Storybook
run: yarn build-storybook-embedding-sdk
shell: bash
- 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!"
shell: bash

View File

@@ -27,9 +27,17 @@ runs:
- name: Test database driver
run: clojure -X:dev:ci:ee:ee-dev:drivers:drivers-dev:test ${{ inputs.test-args }}
shell: bash
id: run-test
# Trunk Quarantine controls the final state of the run in the CI!
# Even if this step fails we let it pass, and then `trunk-io/analytics-uploader` determines
# whether to fail or to pass the whole job, based on the quarantine list.
continue-on-error: true
- name: Publish Test Report (JUnit)
uses: dorny/test-reporter@v1
if: failure()
# As per the documentation: https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#steps-context
# test.outcome gives us access to the result before `continue-on-error` overrides it and sets it to 'success'.
# We want test reports even if the test step gets cancelled (e.g. times out), hence we match anything that is not a 'success'.
if: steps.run-test.outcome != 'success'
with:
path: "target/junit/**/*_test.xml"
name: JUnit Test Report ${{ inputs.junit-name }}
@@ -38,9 +46,11 @@ runs:
list-tests: failed
fail-on-error: false
- name: Upload Logs on Failure
if: always() && !success()
if: always() && steps.run-test.outcome != 'success'
uses: actions/upload-artifact@v4
with:
name: test-logs-${{ github.job }}
path: logs/test-log.json
retention-days: 1
# Failing to upload the artifact should never affect the outcome of the whole test run.
continue-on-error: true

View File

@@ -48,10 +48,11 @@ runs:
aws s3 cp ${OUTPUT_FILE}.zip s3://$BUCKET/$DATE/$GITHUB_RUN_ID/$GITHUB_RUN_ATTEMPT/
- name: Upload results to Trunk
if: ${{ always() && !(github.event_name == 'pull_request' && github.event.pull_request.draft == true) }}
if: always() # Important! This step must always run because it controls job's exit code.
uses: trunk-io/analytics-uploader@main
with:
junit-paths: ${{ inputs.input-path }}
variant: ${{ inputs.variant || inputs.output-name }}
org-slug: metabase
dry-run: ${{ github.event_name == 'pull_request' && github.event.pull_request.draft == true }} # quarantine, but do not upload results
token: ${{ inputs.trunk-api-token }}

View File

@@ -1,3 +1,5 @@
version: 1
name: "Metabase CodeQL config"
paths-ignore:

View File

@@ -127,10 +127,6 @@ e2e_ci: &e2e_ci
e2e_specs: &e2e_specs
- e2e/!(test-host-app)**/*.cy.*.{js,ts}
e2e_cross_version: &e2e_cross_version
- ".github/workflows/e2e-cross-version.yml"
- "e2e/test/scenarios/cross-version/**"
e2e_embedding_sdk:
- *frontend_embedding_sdk_ci
- *sources
@@ -170,6 +166,7 @@ yaml:
- "**/*.yaml"
codeql:
- ".github/workflows/codeql.yml"
- "frontend/src/**"
- "enterprise/frontend/src/**"

View File

@@ -3,14 +3,8 @@
// grouping some specific tests together, other tests are split into chunks
const DEFAULT_SPEC_PATTERN = "./e2e/test/scenarios/**/*.cy.spec.*";
const EMBEDDING_SDK_SPEC_PATTERN =
"./e2e/test/scenarios/embedding-sdk/**.cy.spec.*";
const specialTestConfigs = [
{
name: "embedding-sdk",
specs: EMBEDDING_SDK_SPEC_PATTERN,
},
{
name: "oss-subset",
edition: "oss",

View File

@@ -11,7 +11,7 @@ describe("buildMatrix", () => {
it("should calculate correct regular chunks with default parameters", () => {
const result = testBuildMatrix("./e2e/test/scenarios/**/*.cy.spec.*", 30);
expect(result.regularChunks).toBe(26);
expect(result.regularChunks).toBe(27);
});
it("should create correct number of configuration objects", () => {
@@ -23,7 +23,7 @@ describe("buildMatrix", () => {
it("should apply default specs path when empty entry is provided", () => {
const result = testBuildMatrix("", 6);
expect(result.regularChunks).toBe(2);
expect(result.regularChunks).toBe(3);
expect(result.config.length).toBe(6);
});
@@ -39,14 +39,13 @@ describe("buildMatrix", () => {
});
it("should handle case when input chunks equals special tests count", () => {
const result = testBuildMatrix("./e2e/test/scenarios/**/*.cy.spec.*", 4);
const result = testBuildMatrix("./e2e/test/scenarios/**/*.cy.spec.*", 3);
expect(result.regularChunks).toBe(0);
expect(result.config.length).toBe(4);
expect(result.config[0].name).toBe("embedding-sdk");
expect(result.config[1].name).toBe("oss-subset");
expect(result.config[2].name).toBe("mongo");
expect(result.config[3].name).toBe("python");
expect(result.config.length).toBe(3);
expect(result.config[0].name).toBe("oss-subset");
expect(result.config[1].name).toBe("mongo");
expect(result.config[2].name).toBe("python");
});
it("should correctly calculate regularChunks for non-default spec pattern", () => {
@@ -84,7 +83,6 @@ describe("buildMatrix", () => {
it("should return special test configs when default spec pattern is provided", () => {
const result = testBuildMatrix("./e2e/test/scenarios/**/*.cy.spec.*", 50);
expect(result.config[46].name).toBe("embedding-sdk");
expect(result.config[47].name).toBe("oss-subset");
expect(result.config[48].name).toBe("mongo");
expect(result.config[49].name).toBe("python");

13
.github/team.json vendored
View File

@@ -32,15 +32,6 @@
"lorem--ipsum"
]
},
{
"name": "Workflows",
"label": ".Team/Workflows",
"members": [
"piranha",
"crisptrutski",
"spalt08"
]
},
{
"name": "Admin Webapp",
"label": ".Team/AdminWebapp",
@@ -69,7 +60,9 @@
"sloansparger",
"somtom",
"tsplude",
"lbrdnk"
"lbrdnk",
"piranha",
"crisptrutski"
]
},
{

View File

@@ -137,11 +137,13 @@ jobs:
image: cimg/mysql:8.0
env:
enable-ssl-tests: 'false'
enable-aws-iam-tests: 'false'
- name: MySQL Latest
junit-name: be-tests-mysql-latest-ee
image: mysql:latest
env:
enable-ssl-tests: 'true'
enable-aws-iam-tests: 'true'
job:
- name: Enterprise Tests
build-static-viz: false
@@ -211,6 +213,14 @@ jobs:
MB_MYSQL_SSL_TEST_SSL_CERT: ${{ secrets.MB_MYSQL_SSL_TEST_SSL_CERT }}
MB_MYSQL_SSL_TEST_USER: metabase
MB_MYSQL_SSL_TEST_PASSWORD: ${{ secrets.MYSQL_RDS_SSL_INSTANCE_PASSWORD }}
MB_MYSQL_AWS_IAM_TEST: ${{ matrix.version.env.enable-aws-iam-tests }}
MB_MYSQL_AWS_IAM_TEST_HOST: ${{ secrets.MYSQL_AURORA_IAM_INSTANCE_HOST }}
MB_MYSQL_AWS_IAM_TEST_PORT: 3306
MB_MYSQL_AWS_IAM_TEST_USER: my_iam_user
MB_MYSQL_AWS_IAM_TEST_DBNAME: test_db
MB_MYSQL_AWS_IAM_TEST_SSL_CERT: trust
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_AURORA_IAM_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_AURORA_IAM_SECRET_ACCESS_KEY }}
# for historic reasons (I don't want to mess around with required jobs) the job name should be something like
# "be-tests-mariadb-10-2-ee (0)"
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
@@ -249,11 +259,13 @@ jobs:
docker-image: postgres:12-alpine
env:
enable-ssl-tests: 'false'
enable-aws-iam-tests: 'false'
- name: Postgres Latest
junit-name: postgres-latest-ee
docker-image: postgres:latest
env:
enable-ssl-tests: 'true'
enable-aws-iam-tests: 'true'
job:
- name: Enterprise Tests
build-static-viz: false
@@ -305,6 +317,13 @@ jobs:
MB_POSTGRES_SSL_TEST_SSL: ${{ matrix.version.env.enable-ssl-tests }}
MB_POSTGRES_SSL_TEST_SSL_MODE: verify-full
MB_POSTGRES_SSL_TEST_SSL_ROOT_CERT_PATH: 'test-resources/certificates/us-east-2-bundle.pem'
MB_POSTGRES_AWS_IAM_TEST: ${{ matrix.version.env.enable-aws-iam-tests }}
MB_POSTGRES_AWS_IAM_TEST_HOST: ${{ secrets.POSTGRES_AURORA_IAM_INSTANCE_HOST }}
MB_POSTGRES_AWS_IAM_TEST_PORT: 5432
MB_POSTGRES_AWS_IAM_TEST_USER: my_iam_user
MB_POSTGRES_AWS_IAM_TEST_DBNAME: test_db
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_AURORA_IAM_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_AURORA_IAM_SECRET_ACCESS_KEY }}
services:
postgres:
image: ${{ matrix.version.docker-image }}

View File

@@ -10,19 +10,202 @@ jobs:
# don't run this workflow on a cron for forks
if: ${{ github.event_name != 'schedule' || github.repository == 'metabase/metabase' }}
runs-on: ubuntu-22.04
timeout-minutes: 90
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
modules:
- actions
- activity-feed
- analytics
- analyze
- api
- api-keys
- api-routes
- app-db
- appearance
- audit-app
- auth-provider
- batch-processing
- bookmarks
- bug-reporting
- cache
- channel
- classloader
- cloud-migration
- cmd
- collections
- config
- connection-pool
- content-translation
- content-verification
- core
- dashboards
- database-routing
- driver
- driver-api
- eid-translation
- embedding
- events
- formatter
- geojson
- glossary
- graph
- indexed-entities
- internal-stats
- legacy-mbql
- lib
- lib-be
- logger
- login-history
- model-persistence
- models
- native-query-snippets
- notification
- parameters
- permissions
- pivot
- plugins
- premium-features
- product-feedback
- public-sharing
- pulse
- queries
- query-permissions
- query-processor
- remote-sync
- request
- revisions
- sample-data
- search
- secrets
- segments
- server
- session
- settings
- setup
- sso
- startup
- store-api
- sync
- system
- task
- task-history
- testing-api
- tiles
- timeline
- types
- upload
- user-key-value
- users
- util
- version
- view-log
- warehouse-schema
- warehouses
- xrays
steps:
- uses: actions/checkout@v4
- name: Prepare front-end environment
uses: ./.github/actions/prepare-frontend
- name: Prepare back-end environment
uses: ./.github/actions/prepare-backend
- name: Build static viz frontend
run: yarn build-static-viz
env:
MB_EDITION: ee
- name: Collect the test coverage
run: clojure -X:dev:ci:ee:ee-dev:test:cloverage
run: |
clojure -X:dev:ci:ee:ee-dev:test:cloverage \
:ns-regex '["^metabase\\.${{ matrix.modules }}\\..*"]' \
:test-ns-path '["test/metabase/${{ matrix.modules }}"]'
continue-on-error: true
- name: Upload coverage to codecov.io
uses: codecov/codecov-action@v4
if: always()
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./target/coverage/codecov.json
flags: back-end
be-linter-cloverage-enterprise:
# don't run this workflow on a cron for forks
if: ${{ github.event_name != 'schedule' || github.repository == 'metabase/metabase' }}
runs-on: ubuntu-22.04
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
modules:
- action-v2
- advanced-config
- advanced-permissions
- ai-entity-analysis
- ai-sql-fixer
- ai-sql-generation
- analytics
- api
- audit-app
- auth-provider
- billing
- bookmarks
- cache
- cloud-add-ons
- comments
- content-translation
- content-verification
- core
- dashboard-subscription-filters
- database-replication
- database-routing
- dependencies
- documents
- email
- embedding-hub
- gsheets
- harbormaster
- impersonation
- internal-stats
- llm
- metabot-v3
- permission-debug
- premium-features
- public-sharing
- remote-sync
- sandbox
- scim
- search
- semantic-search
- serialization
- snippet-collections
- sso
- stale
- transforms
- transforms-python
- upload-management
steps:
- uses: actions/checkout@v4
- name: Prepare front-end environment
uses: ./.github/actions/prepare-frontend
- name: Prepare back-end environment
uses: ./.github/actions/prepare-backend
- name: Build static viz frontend
run: yarn build-static-viz
env:
MB_EDITION: ee
- name: Collect the test coverage
run: |
clojure -X:dev:ci:ee:ee-dev:test:cloverage \
:ns-regex '["^metabase-enterprise\\.${{ matrix.modules }}\\..*"]' \
:test-ns-path '["enterprise/backend/test/metabase/${{ matrix.modules }}"]'
continue-on-error: true
- name: Upload coverage to codecov.io
if: always()
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./target/coverage/codecov.json

View File

@@ -129,6 +129,10 @@ jobs:
clojure -X:dev:ci:test:${{ matrix.job.edition }}:${{ matrix.job.edition }}-dev
:exclude-tags '[:mb/driver-tests ${{ env.__ADDITIONAL_EXCLUDED_TAG__ }}]'
${{ matrix.job.test-args }}
# Trunk Quarantine controls the final state of the run in the CI!
# Even if this step fails we let it pass, and then `trunk-io/analytics-uploader` determines
# whether to fail or to pass the whole job, based on the quarantine list.
continue-on-error: true
- name: Upload Test Results
uses: ./.github/actions/upload-test-results

View File

@@ -48,6 +48,7 @@ jobs:
outputs:
m2-cache-key: ${{ steps.get-cache-keys.outputs.m2-cache-key }}
node-cache-key: ${{ steps.get-cache-keys.outputs.node-cache-key }}
eslint-cache-key: ${{ steps.get-cache-keys.outputs.eslint-cache-key }}
generate-m2-cache:
runs-on: ubuntu-22.04
@@ -73,12 +74,13 @@ jobs:
~/.gitlibs
key: ${{ env.M2_CACHE_KEY }}
generate-node-modules-cache:
generate-frontend-caches:
runs-on: ubuntu-22.04
timeout-minutes: 15
needs: get-cache-keys
env:
NODE_CACHE_KEY: ${{ needs.get-cache-keys.outputs.node-cache-key }}
ESLINT_CACHE_KEY: ${{ needs.get-cache-keys.outputs.eslint-cache-key }}
steps:
- uses: actions/checkout@v4
# `prepare-frontend` action (1) prepares Node.js and (2) fetches the node_modules cache if it exists.
@@ -97,3 +99,9 @@ jobs:
with:
path: node_modules
key: ${{ env.NODE_CACHE_KEY }}
- name: Update eslint cache
uses: ./.github/actions/update-cache
with:
path: .eslintcache
key: ${{ env.ESLINT_CACHE_KEY }}

View File

@@ -2,6 +2,10 @@ name: "Claude Code Review"
on:
pull_request:
types:
- closed
- synchronize
- labeled
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}-claude-code-review
@@ -9,7 +13,12 @@ concurrency:
jobs:
review:
if: github.event.pull_request.draft == false
if: |
(
github.event.action == 'closed' &&
github.event.pull_request.merged == true
) ||
contains(github.event.pull_request.labels.*.name, 'Claude Code Review')
runs-on: ubuntu-latest
permissions:
contents: read

View File

@@ -30,9 +30,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v4
with:
languages: javascript
config-file: ./.github/codeql/codeql-config.yml
trap-caching: false
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v4

View File

@@ -60,6 +60,14 @@ jobs:
clojure -M:ee:doc api-documentation
continue-on-error: false
- name: Generate command documentation
id: generate_command_docs
run: |
set -e # Exit on any error
echo "Generating API documentation..."
clojure -M:ee:doc command-documentation
continue-on-error: false
- name: Check for changes
id: check_changes
run: |

View File

@@ -4,12 +4,18 @@ on:
schedule:
- cron: "0 2 * * 1-5" # Every Monday through Friday at 2 AM UTC
workflow_dispatch:
inputs:
target_branch:
description: "Target branch for documentation update"
required: false
default: "release-x.56.x"
type: string
jobs:
update-release-docs:
name: Call documentation update for release branch
uses: ./.github/workflows/docs-generate-base.yml
with:
target_branch: "release-x.56.x"
target_branch: ${{ inputs.target_branch || 'release-x.56.x' }}
secrets:
automation_token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}

View File

@@ -390,10 +390,6 @@ 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 }}
- name: Test H2 driver
id: test-driver
uses: ./.github/actions/test-driver
@@ -413,12 +409,6 @@ 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 }}
@@ -433,21 +423,25 @@ jobs:
image: circleci/mariadb:10.2.23
env:
enable-ssl-tests: 'false'
enable-aws-iam-tests: 'false'
- name: MariaDB Latest
junit-name: be-tests-mariadb-latest-ee
image: circleci/mariadb:latest
env:
enable-ssl-tests: 'false'
enable-aws-iam-tests: 'false'
- name: MySQL 8.0
junit-name: be-tests-mysql-8-0-ee
image: mysql:8.0
env:
enable-ssl-tests: 'false'
enable-aws-iam-tests: 'false'
- name: MySQL Latest
junit-name: be-tests-mysql-latest-ee
image: mysql:latest
env:
enable-ssl-tests: 'true'
enable-aws-iam-tests: 'true'
job:
- name: Driver Tests
test-args: >-
@@ -506,6 +500,14 @@ jobs:
MB_MYSQL_SSL_TEST_SSL_CERT: ${{ secrets.MB_MYSQL_SSL_TEST_SSL_CERT }}
MB_MYSQL_SSL_TEST_USER: metabase
MB_MYSQL_SSL_TEST_PASSWORD: ${{ secrets.MYSQL_RDS_SSL_INSTANCE_PASSWORD }}
MB_MYSQL_AWS_IAM_TEST: ${{ matrix.version.env.enable-aws-iam-tests }}
MB_MYSQL_AWS_IAM_TEST_HOST: ${{ secrets.MYSQL_AURORA_IAM_INSTANCE_HOST }}
MB_MYSQL_AWS_IAM_TEST_PORT: 3306
MB_MYSQL_AWS_IAM_TEST_USER: my_iam_user
MB_MYSQL_AWS_IAM_TEST_DBNAME: test_db
MB_MYSQL_AWS_IAM_TEST_SSL_CERT: trust
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_AURORA_IAM_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_AURORA_IAM_SECRET_ACCESS_KEY }}
# for historic reasons (I don't want to mess around with required jobs) the job name should be something like
# "be-tests-mariadb-10-2-ee (0)"
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
@@ -796,11 +798,13 @@ jobs:
docker-image: postgres:12-alpine
env:
enable-ssl-tests: 'false'
enable-aws-iam-tests: 'false'
- name: Postgres Latest
junit-name: postgres-latest-ee
docker-image: postgres:latest
env:
enable-ssl-tests: 'true'
enable-aws-iam-tests: 'true'
job:
- name: Driver Tests
test-args: >-
@@ -840,6 +844,13 @@ jobs:
MB_POSTGRES_SSL_TEST_SSL: ${{ matrix.version.env.enable-ssl-tests }}
MB_POSTGRES_SSL_TEST_SSL_MODE: verify-full
MB_POSTGRES_SSL_TEST_SSL_ROOT_CERT_PATH: 'test-resources/certificates/us-east-2-bundle.pem'
MB_POSTGRES_AWS_IAM_TEST: ${{ matrix.version.env.enable-aws-iam-tests }}
MB_POSTGRES_AWS_IAM_TEST_HOST: ${{ secrets.POSTGRES_AURORA_IAM_INSTANCE_HOST }}
MB_POSTGRES_AWS_IAM_TEST_PORT: 5432
MB_POSTGRES_AWS_IAM_TEST_USER: my_iam_user
MB_POSTGRES_AWS_IAM_TEST_DBNAME: test_db
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_AURORA_IAM_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_AURORA_IAM_SECRET_ACCESS_KEY }}
services:
postgres:
image: ${{ matrix.version.docker-image }}

View File

@@ -1,4 +1,4 @@
# Thi workflow does the backward compatibility tests
# This workflow does the backward compatibility tests
# between the Embedding SDK package of version N and Embedding SDK Bundle of version N - 1
# N - 1 is a target of a PR
name: Embedding SDK backward-compatibility E2E Component Tests
@@ -93,13 +93,14 @@ jobs:
env:
MB_EDITION: ee
DISPLAY: ""
MB_RUN_MODE: "e2e"
METASTORE_DEV_SERVER_URL: ${{ secrets.METASTORE_DEV_SERVER_URL }}
# Any env starting with `CYPRESS_` will be available to all Cypress tests via `Cypress.env()`
# Example: you can get `CYPRESS_FOO` with `Cypress.env("FOO")`
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
CYPRESS_PULL_REQUEST_ID: ${{ github.event.pull_request.number || '' }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.STAGING_MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.STAGING_MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.STAGING_MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.STAGING_MB_PRO_SELF_HOSTED_TOKEN }}
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title || github.event.head_commit.message || github.event.head.sha }}
TZ: US/Pacific # to make node match the instance tz
CYPRESS_CI: true

View File

@@ -108,13 +108,14 @@ jobs:
env:
MB_EDITION: ee
DISPLAY: ""
MB_RUN_MODE: "e2e"
METASTORE_DEV_SERVER_URL: ${{ secrets.METASTORE_DEV_SERVER_URL }}
# Any env starting with `CYPRESS_` will be available to all Cypress tests via `Cypress.env()`
# Example: you can get `CYPRESS_FOO` with `Cypress.env("FOO")`
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
CYPRESS_PULL_REQUEST_ID: ${{ github.event.pull_request.number || '' }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.STAGING_MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.STAGING_MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.STAGING_MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.STAGING_MB_PRO_SELF_HOSTED_TOKEN }}
CYPRESS_IS_EMBEDDING_SDK: "true"
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title || github.event.head_commit.message || github.event.head.sha }}
TZ: US/Pacific # to make node match the instance tz

View File

@@ -1,171 +0,0 @@
name: E2E Cross-version Tests
on:
schedule:
- cron: '0 9 * * 1-5'
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
jobs:
files-changed:
name: Check which files changed
# don't run this workflow on a cron for forks
if: ${{ github.event_name != 'schedule' || github.repository == 'metabase/metabase' }}
runs-on: ubuntu-22.04
timeout-minutes: 3
outputs:
e2e_cross_version: ${{ steps.changes.outputs.e2e_cross_version }}
steps:
- uses: actions/checkout@v4
- name: Test which files changed
uses: dorny/paths-filter@v3.0.0
id: changes
with:
token: ${{ github.token }}
filters: .github/file-paths.yaml
cross-version-testing:
needs: files-changed
if: ${{ needs.files-changed.outputs.e2e_cross_version == 'true' || github.event_name == 'schedule'}}
runs-on: ubuntu-22.04
timeout-minutes: 20
strategy:
matrix:
version: [
# Major OSS upgrade
{ source: v0.42.2, target: v0.48.7 },
# OSS upgrade
{ source: v0.41.3.1, target: v0.42.2 },
# EE upgrade
{ source: v1.43.4, target: v1.44.0 },
# EE downgrade
{ source: v1.42.0, target: v1.41.3.1 },
# Cross-edition upgrade
{ source: v0.41.3.1, target: v1.42.2 }
]
fail-fast: false
env:
CROSS_VERSION_SOURCE: ${{ matrix.version.source }}
CROSS_VERSION_TARGET: ${{ matrix.version.target }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set source Docker image to OSS
run: |
echo "DOCKER_SOURCE_IMAGE=metabase/metabase:${{ matrix.version.source }}" >> $GITHUB_ENV
if: startsWith(matrix.version.source, 'v0')
- name: Set source Docker image to EE
run: |
echo "DOCKER_SOURCE_IMAGE=metabase/metabase-enterprise:${{ matrix.version.source }}" >> $GITHUB_ENV
if: startsWith(matrix.version.source, 'v1')
- name: Prepare front-end environment
uses: ./.github/actions/prepare-frontend
- name: Start Metabase ${{ matrix.version.source }}
run: |
docker run -d \
-v $PWD/my-metabase:/metabase.db \
-p 3000:3000 \
-e CYPRESS_MB_ALL_FEATURES_TOKEN=${{ secrets.MB_ALL_FEATURES_TOKEN }} \
-e CYPRESS_MB_STARTER_CLOUD_TOKEN=${{ secrets.MB_STARTER_CLOUD_TOKEN }} \
-e CYPRESS_MB_PRO_CLOUD_TOKEN=${{ secrets.MB_PRO_CLOUD_TOKEN }} \
-e CYPRESS_MB_PRO_SELF_HOSTED_TOKEN=${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }} \
--name metabase-${{ matrix.version.source }} \
${{ env.DOCKER_SOURCE_IMAGE }}
- name: Wait for Metabase to start on port 3000
run: while ! curl -s 'http://localhost:3000/api/health' | grep '{"status":"ok"}'; do sleep 1; done
- name: Prepare Cypress environment
id: cypress-prep
uses: ./.github/actions/prepare-cypress
- name: Run Cypress on the source
run: |
yarn cypress run \
--browser ${{ steps.cypress-prep.outputs.chrome-path }} \
--config-file e2e/test/scenarios/cross-version/source/shared/cross-version-source.config.js \
--spec e2e/test/scenarios/cross-version/source/**/*.cy.spec.js
- name: Stop Metabase ${{ matrix.version.source }}
run: docker stop metabase-${{ matrix.version.source }}
- name: Set target Docker image to OSS
run: |
echo "DOCKER_TARGET_IMAGE=metabase/metabase:${{ matrix.version.source }}" >> $GITHUB_ENV
if: startsWith(matrix.version.source, 'v0')
- name: Set target Docker image to EE
run: |
echo "DOCKER_TARGET_IMAGE=metabase/metabase-enterprise:${{ matrix.version.source }}" >> $GITHUB_ENV
if: startsWith(matrix.version.source, 'v1')
- name: Start Metabase ${{ matrix.version.target }}
run: |
docker run -d \
-v $PWD/my-metabase:/metabase.db \
-p 3001:3000 \
-e CYPRESS_MB_ALL_FEATURES_TOKEN=${{ secrets.MB_ALL_FEATURES_TOKEN }} \
-e CYPRESS_MB_STARTER_CLOUD_TOKEN=${{ secrets.MB_STARTER_CLOUD_TOKEN }} \
-e CYPRESS_MB_PRO_CLOUD_TOKEN=${{ secrets.MB_PRO_CLOUD_TOKEN }} \
-e CYPRESS_MB_PRO_SELF_HOSTED_TOKEN=${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }} \
--name metabase-${{ matrix.version.target }} \
${{ env.DOCKER_TARGET_IMAGE }}
- name: Wait for Metabase to start on port 3001
run: while ! curl -s 'http://localhost:3001/api/health' | grep '{"status":"ok"}'; do sleep 1; done
- name: Run Cypress on the target
run: |
yarn cypress run \
--browser ${{ steps.cypress-prep.outputs.chrome-path }} \
--config-file e2e/test/scenarios/cross-version/target/shared/cross-version-target.config.js \
--spec e2e/test/scenarios/cross-version/target/**/*.cy.spec.js
- name: Upload Cypress Artifacts upon failure
uses: actions/upload-artifact@v4
if: failure()
with:
name: cypress-artifacts-${{ matrix.version.source}}-to-${{ matrix.version.target }}
path: |
./cypress
if-no-files-found: ignore
notify-on-failure:
needs: cross-version-testing
if: ${{ always() && contains(needs.*.result, 'failure') && github.event_name == 'schedule' }}
name: Cross-version test failure
runs-on: ubuntu-22.04
timeout-minutes: 5
steps:
- uses: actions/setup-node@v4
with:
node-version: lts/Jod # 22.x.x
- run: npm install @slack/web-api
- name: notify slack of failure
uses: actions/github-script@v7
with:
script: | # js
const FAILED_RUN_URL = "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}";
const REF_NAME = "${{ github.ref_name }}";
// notify slack of failure
const { WebClient } = require('@slack/web-api');
const slack = new WebClient('${{ secrets.SLACK_BOT_TOKEN }}');
await slack.chat.postMessage({
channel: 'engineering-ci',
text: 'Cross-version Tests Have Failed',
blocks: [
{
"type": "header",
"text": {
"type": "plain_text",
"text": `:broken_heart: Cross-version tests are failing on ${REF_NAME}`,
"emoji": true,
}
},
],
attachments: [{
color: "#BF40BF",
blocks: [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `See <${FAILED_RUN_URL}|failing run details>.`
}
},
]
}]
});

View File

@@ -213,7 +213,9 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number || '' }}
HASH: ${{ github.event.pull_request.head.sha || github.sha }}-${{ github.run_attempt }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
MB_RUN_MODE: e2e
METASTORE_DEV_SERVER_URL: ${{ secrets.METASTORE_DEV_SERVER_URL }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.STAGING_MB_ALL_FEATURES_TOKEN }}
CYPRESS_IS_EMBEDDING_SDK: "true"
TZ: US/Pacific # to make node match the instance tz
CYPRESS_CI: true
@@ -343,7 +345,9 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number || '' }}
HASH: ${{ github.event.pull_request.head.sha || github.sha }}-${{ github.run_attempt }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
MB_RUN_MODE: e2e
METASTORE_DEV_SERVER_URL: ${{ secrets.METASTORE_DEV_SERVER_URL }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.STAGING_MB_ALL_FEATURES_TOKEN }}
CYPRESS_IS_EMBEDDING_SDK: "true"
TZ: US/Pacific # to make node match the instance tz
CYPRESS_CI: true

View File

@@ -37,8 +37,26 @@ on:
default: true
jobs:
determine-suite:
name: Determine test suite
runs-on: ubuntu-22.04
timeout-minutes: 5
outputs:
suite: ${{ steps.detect.outputs.suite }}
steps:
- name: Detect suite from spec path
id: detect
run: |
SPEC='${{ inputs.spec }}'
if [[ "$SPEC" == e2e/test-component/scenarios/embedding-sdk/* ]]; then
echo "suite=component" >> $GITHUB_OUTPUT
else
echo "suite=e2e" >> $GITHUB_OUTPUT
fi
workflow-summary:
name: Stress test inputs
needs: [determine-suite]
runs-on: ubuntu-22.04
timeout-minutes: 5
steps:
@@ -48,6 +66,7 @@ jobs:
echo '' >> $GITHUB_STEP_SUMMARY
echo '- `branch`: ${{ github.ref_name }}' >> $GITHUB_STEP_SUMMARY
echo '- `spec`: ${{ inputs.spec }}' >> $GITHUB_STEP_SUMMARY
echo '- `test_suite` (inferred): ${{ needs.determine-suite.outputs.suite }}' >> $GITHUB_STEP_SUMMARY
echo '- `burn_in`: ${{ inputs.burn_in }}' >> $GITHUB_STEP_SUMMARY
echo '- `grep`: "${{ inputs.grep }}"' >> $GITHUB_STEP_SUMMARY
echo '- `qa_db`: "${{ inputs.qa_db }}"' >> $GITHUB_STEP_SUMMARY
@@ -56,6 +75,7 @@ jobs:
echo 'triggered by: @${{ github.event.sender.login }}' >> $GITHUB_STEP_SUMMARY
stress-test-flake-fix:
needs: [determine-suite]
runs-on: ubuntu-22.04
timeout-minutes: 60
name: Stress test E2E flake fix
@@ -63,10 +83,12 @@ jobs:
DISPLAY: ""
QA_DB_ENABLED: ${{ contains(fromJSON('["sql", "mongo"]'), inputs.qa_db) }}
CYPRESS_QA_DB_MONGO: ${{ inputs.qa_db == 'mongo' }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
MB_RUN_MODE: e2e
METASTORE_DEV_SERVER_URL: ${{ secrets.METASTORE_DEV_SERVER_URL }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.STAGING_MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.STAGING_MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.STAGING_MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.STAGING_MB_PRO_SELF_HOSTED_TOKEN }}
MB_SNOWPLOW_AVAILABLE: true
MB_SNOWPLOW_URL: "http://localhost:9090" # Snowplow micro
MB_EDITION: ${{ inputs.mb_edition }}
@@ -98,6 +120,16 @@ jobs:
- name: Prepare front-end environment
uses: ./.github/actions/prepare-frontend
- name: Prepare back-end environment
if: ${{ needs.determine-suite.outputs.suite == 'component' }}
uses: ./.github/actions/prepare-backend
with:
m2-cache-key: "cljs"
- name: Build Embedding SDK package
if: ${{ needs.determine-suite.outputs.suite == 'component' }}
run: yarn build-embedding-sdk-package
- name: Prepare JDK 21
uses: actions/setup-java@v4
with:
@@ -116,8 +148,9 @@ jobs:
- name: Stress-test ${{ github.event.inputs.spec }} ${{ github.event.inputs.burn_in }} times
env:
GREP: ${{ github.event.inputs.grep }}
CYPRESS_IS_EMBEDDING_SDK: ${{ needs.determine-suite.outputs.suite == 'component' }}
run: |
node e2e/runner/run_cypress_ci.js e2e \
node e2e/runner/run_cypress_ci.js ${{ needs.determine-suite.outputs.suite }} \
--spec '${{ github.event.inputs.spec }}' \
--env burn=${{ github.event.inputs.burn_in }} \
--config-file e2e/support/cypress-stress-test.config.js \

View File

@@ -42,12 +42,14 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HASH: ${{ github.event.pull_request.head.sha || github.sha }}-${{ github.run_attempt }}
JOB_NAME: ${{ inputs.name }}
MB_RUN_MODE: "e2e"
METASTORE_DEV_SERVER_URL: ${{ secrets.METASTORE_DEV_SERVER_URL }}
# Any env starting with `CYPRESS_` will be available to all Cypress tests via `Cypress.env()`
# Example: you can get `CYPRESS_FOO` with `Cypress.env("FOO")`
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.STAGING_MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.STAGING_MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.STAGING_MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.STAGING_MB_PRO_SELF_HOSTED_TOKEN }}
CYPRESS_PULL_REQUEST_ID: ${{ github.event.pull_request.number || '' }}
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title || github.event.head_commit.message || github.event.head.sha }}
MB_EXPERIMENTAL_SEARCH_BLOCK_ON_QUEUE: true
@@ -57,7 +59,6 @@ jobs:
TZ: US/Pacific # to make node match the instance tz
CYPRESS_CI: true
CYPRESS_QA_DB_MONGO: ${{ inputs.name == 'mongo' }}
CYPRESS_IS_EMBEDDING_SDK: "${{ inputs.name == 'embedding-sdk' }}"
steps:
- uses: actions/checkout@v4
with:
@@ -83,10 +84,6 @@ jobs:
mysql: ${{ inputs.name != 'mongo' }}
mongo: ${{ inputs.name == 'mongo' }}
- name: Run Embedding SDK Storybook
if: inputs.name == 'embedding-sdk'
uses: ./.github/actions/run-embedding-sdk-storybook
- name: Retrieve uberjar artifact for ${{ inputs.edition }}
uses: ./.github/actions/fetch-artifact
with:
@@ -144,10 +141,9 @@ jobs:
--spec "$SPEC_PATH" \
--browser ${{ steps.cypress-prep.outputs.chrome-path }}
# Trunk Quarantine controls the final state of the run in the CI!
# Even if this step fails, we let it pass and then `trunk-io/analytics-uploader` determines whether to fail or to
# pass the whole job, based on the quarantine list.
# We only want to "continue on error" (ignore failures) when the Trunk upload is active - i.e. not on drafts!
continue-on-error: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true) }}
# Even if this step fails we let it pass, and then `trunk-io/analytics-uploader` determines
# whether to fail or to pass the whole job, based on the quarantine list.
continue-on-error: true
- name: Run Tagged EE Cypress tests on ${{ inputs.name }}
if: ${{ inputs.specs }}
@@ -161,10 +157,9 @@ jobs:
--spec "$SPEC_PATH" \
--browser ${{ steps.cypress-prep.outputs.chrome-path }}
# Trunk Quarantine controls the final state of the run in the CI!
# Even if this step fails, we let it pass and then `trunk-io/analytics-uploader` determines whether to fail or to
# pass the whole job, based on the quarantine list.
# We only want to "continue on error" (ignore failures) when the Trunk upload is active - i.e. not on drafts!
continue-on-error: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.draft == true) }}
# Even if this step fails we let it pass, and then `trunk-io/analytics-uploader` determines
# whether to fail or to pass the whole job, based on the quarantine list.
continue-on-error: true
- name: Upload Test Results
uses: ./.github/actions/upload-test-results

View File

@@ -35,13 +35,16 @@ jobs:
uses: ./.github/actions/prepare-frontend
- name: Prepare back-end environment
uses: ./.github/actions/prepare-backend
- name: Get Eslint cache key
uses: ./.github/actions/get-cache-keys
id: get-cache-keys
- name: Restore ESLint cache
uses: actions/cache@v4
uses: actions/cache/restore@v4
with:
path: .eslintcache
key: eslintcache-${{ hashFiles('yarn.lock', '.eslintrc.js') }}
restore-keys: |
eslintcache-
key: ${{ steps.get-cache-keys.outputs.eslint-cache-key }}
- name: Compile CLJS
run: yarn build-pure:cljs
- name: Find CSS variables that are used but never defined
@@ -88,8 +91,9 @@ jobs:
uses: ./.github/actions/prepare-backend
- name: Run frontend unit tests
run: yarn run test-unit --silent --shard=${{ matrix.shard }}/${{ env.SHARDS }}
# We want Trunk to still receive test reports even if this job fails.
# It will filter out the quarantined tests, and will control the job exit code based on the analysis.
# Trunk Quarantine controls the final state of the run in the CI!
# Even if this step fails we let it pass, and then `trunk-io/analytics-uploader` determines
# whether to fail or to pass the whole job, based on the quarantine list.
continue-on-error: true
- name: Upload Test Results
uses: ./.github/actions/upload-test-results

View File

@@ -24,6 +24,39 @@ on:
required: true
jobs:
test-mode-config:
runs-on: ubuntu-22.04
timeout-minutes: 5
outputs:
run_mode: ${{ fromJson(steps.config.outputs.result).runMode }}
dev_server: ${{ fromJson(steps.config.outputs.result).metastoreDevServer }}
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: release
- name: Prepare build scripts
run: cd ${{ github.workspace }}/release && yarn && yarn build
# note: this block can be removed after we stop needing to be able to test versions before v55
- name: Get test mode config
id: config
uses: actions/github-script@v7
with:
script: | # js
const { getMajorVersion } = require('${{ github.workspace }}/release/dist/index.cjs');
// Versions before v55 used a single token for testing
// with v55 and later we use enterprise tokens that mirror actual Metabase plans
const MULTIPLE_TEST_TOKEN_THRESHOLD = 55;
const version = '${{ inputs.version }}';
const majorVersion = Number(getMajorVersion(version));
const oldTestToken = majorVersion < MULTIPLE_TEST_TOKEN_THRESHOLD;
return ({
runMode: oldTestToken ? 'prod' : 'e2e',
metastoreDevServer: oldTestToken ? '' : '${{ vars.METASTORE_DEV_SERVER_URL }}'
});
release-artifact:
runs-on: ubuntu-22.04
timeout-minutes: 10
@@ -96,17 +129,19 @@ jobs:
run-sanity-check:
runs-on: ubuntu-22.04
timeout-minutes: 30
needs: [release-artifact]
needs: [test-mode-config, release-artifact]
strategy:
matrix:
edition: [oss, ee]
env:
MB_EDITION: ${{ matrix.edition }}
DISPLAY: ""
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
MB_RUN_MODE: ${{ needs.test-mode-config.outputs.run_mode }}
METASTORE_DEV_SERVER_URL: ${{ needs.test-mode-config.outputs.dev_server }}
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.STAGING_MB_ALL_FEATURES_TOKEN }}
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.STAGING_MB_STARTER_CLOUD_TOKEN }}
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.STAGING_MB_PRO_CLOUD_TOKEN }}
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.STAGING_MB_PRO_SELF_HOSTED_TOKEN }}
# these are needed for backwards compatibility with release branches earlier than v55, since
# this workflow always runs from master, but we run tests from the release branch
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}

View File

@@ -345,8 +345,9 @@ jobs:
GH_TOKEN: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
- name: Edit PR adding useful information (using Metabase bot app)
# metabase/embedding team is added automatically as code owner of updated `package.template.json` file
run: |
gh pr edit --add-reviewer @metabase/embedding,albertoperdomo --add-label no-backport
gh pr edit --add-reviewer albertoperdomo --add-label no-backport
env:
GH_TOKEN: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}

View File

@@ -47,7 +47,7 @@ jobs:
with:
script: | # js
const {
getVersionFromReleaseBranch,
getMajorVersionFromRef,
getMajorVersion,
} = require('${{ github.workspace }}/release/dist/index.cjs');
@@ -60,14 +60,15 @@ jobs:
}
// otherwise, get the version from the release branch name
const branch = context.payload.ref;
const version = getVersionFromReleaseBranch(branch);
const majorVersion = getMajorVersion(version);
const ref = context.payload.ref;
const majorVersion = getMajorVersionFromRef(ref);
console.log({ branch, version, majorVersion });
console.log({ ref, majorVersion });
core.exportVariable('VERSION', majorVersion);
- name: generate release Log
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: cd release && tsx ./src/release-log-run.ts $VERSION > v$VERSION.html
- name: generate release channel log
run: cd release && tsx ./src/release-channel-log.ts > channels.html

View File

@@ -8,6 +8,11 @@ on:
description: 'Major Metabase version (e.g. 45, 52, 68)'
type: number
required: true
override_sha:
description: DANGEROUSLY allow releasing from this commit sha, regardless of the state of CI (can be empty)
type: string
required: false
default: ''
schedule:
- cron: '0 21 * * 1-5' # every weekday at 4 pm EST/5 pm EDT
@@ -37,7 +42,7 @@ jobs:
const lastRelease = currentRelease - 1;
const AUTO_RELEASE_VERSIONS = [lastRelease, currentRelease];
async function releasePatchFor(majorVersion) {
async function releasePatchFor(majorVersion, overrideSha) {
const nextPatch = await getNextPatchVersion({
github,
owner: context.repo.owner,
@@ -45,7 +50,7 @@ jobs:
majorVersion,
});
const goodCommit = await getLatestGreenCommit({
const releaseCommit = overrideSha || await getLatestGreenCommit({
github,
owner: context.repo.owner,
repo: context.repo.repo,
@@ -56,26 +61,27 @@ jobs:
github,
owner: context.repo.owner,
repo: context.repo.repo,
ref: goodCommit,
ref: releaseCommit,
majorVersion: Number(majorVersion),
});
if (nextPatch && goodCommit && !hasBeenReleased) {
console.log(
{ nextPatch, releaseCommit, hasBeenReleased }
);
if (nextPatch && releaseCommit && !hasBeenReleased) {
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'tag-for-release.yml',
ref: 'refs/heads/master',
inputs: {
commit: goodCommit,
commit: releaseCommit,
version: nextPatch,
auto: true,
}
});
}).catch(console.error);
} else {
console.log(
{ nextPatch, goodCommit, hasBeenReleased }
);
console.error(`No new patch version or no green commit found for v${majorVersion}`);
}
}
@@ -88,7 +94,15 @@ jobs:
throw new Error(`Invalid version number: ${inputVersion}`);
}
await releasePatchFor(inputVersion);
// only allow overriding the commit SHA for workflow_dispatch events with a provided sha
const overrideSha = String(context.payload?.inputs?.override_sha ?? '').trim();
const isValidOverride = overrideSha.length === 40;
if (!isValidOverride && overrideSha.length > 0) {
throw new Error(`Invalid override SHA provided: ${overrideSha}`);
}
await releasePatchFor(inputVersion, isValidOverride ? overrideSha : undefined);
} else { // scheduled release of AUTO_RELEASE_VERSIONS
await Promise.all(AUTO_RELEASE_VERSIONS.map(releasePatchFor));
await Promise.all(AUTO_RELEASE_VERSIONS.map(version => releasePatchFor(version)));
}

View File

@@ -189,14 +189,16 @@ jobs:
- name: Upload to s3 ${{ inputs.tag_name }} path
run: | # sh
aws s3 cp \
s3://${{ vars.AWS_S3_DOWNLOADS_BUCKET }}/${{ steps.source_path.outputs.result }}/metabase.jar \
s3://${{ vars.AWS_S3_DOWNLOADS_BUCKET }}/${{ steps.upload_path.outputs.result }}/metabase.jar
s3://${{ vars.AWS_S3_DOWNLOADS_BUCKET }}/${{ steps.source_path.outputs.result }}/ \
s3://${{ vars.AWS_S3_DOWNLOADS_BUCKET }}/${{ steps.upload_path.outputs.result }}/ \
--recursive \
--include "*"
- name: Create cloudfront invalidation
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ vars.AWS_CLOUDFRONT_DOWNLOADS_ID }} \
--paths /${{ steps.upload_path.outputs.result }}/metabase.jar
--paths "/${{ steps.upload_path.outputs.result }}/*"
- name: Download the jars
run: | # sh

View File

@@ -211,13 +211,15 @@ jobs:
return version_path;
- name: Upload to S3
run: aws s3 cp ./metabase.jar s3://${{ vars.AWS_S3_DOWNLOADS_BUCKET }}/${{ steps.version_path.outputs.result }}/metabase.jar
run: |
aws s3 cp ./metabase.jar s3://${{ vars.AWS_S3_DOWNLOADS_BUCKET }}/${{ steps.version_path.outputs.result }}/metabase.jar
aws s3 cp ./SHA256.sum s3://${{ vars.AWS_S3_DOWNLOADS_BUCKET }}/${{ steps.version_path.outputs.result }}/metabase.sha256
- name: Create cloudfront invalidation
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ vars.AWS_CLOUDFRONT_DOWNLOADS_ID }} \
--paths /${{ steps.version_path.outputs.result }}/metabase.jar
--paths "/${{ steps.version_path.outputs.result }}/*"
verify-s3-download:
runs-on: ubuntu-22.04

View File

@@ -111,7 +111,7 @@ jobs:
uses: actions/github-script@v7
id: release_branch
with:
result_encoding: string
result-encoding: string
script: | # js
const { getReleaseBranch } = require('${{ github.workspace }}/release/dist/index.cjs');
const version = '${{ inputs.version }}';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 931 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 42 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: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -165,10 +165,8 @@ Review pull requests with a focus on:
## More Instructions
- Use **tons** of emojis in every comment you write -- the more, the better! 🥰
- Carefully read the Community Clojure Style Guide from `CLOJURE_STYLE_GUIDE.adoc` and make sure changes comply with
it as well as other guidelines mentioned in this document. Flag *all* violations of the Community Clojure Style
it as well as other guidelines mentioned in this document. Flag _all_ violations of the Community Clojure Style
Guide.
- Do not post comments congratulating someone for trivial changes, or for following the style guidelines, or
@@ -186,17 +184,6 @@ Review pull requests with a focus on:
> Test name properly ends with -test as required by the style guide.
- In the Metabase codebase, spelling words ending with `-ck` as `-cc` instead, e.g. `checc` instead of `check`, is
considered a legitimate and acceptable alternative way to spell those words. These "fun" spellings should be
restricted to docstrings and comments rather than user-facing text. Do not flag these as typos or misspellings.
- Read a tarot card for the meaning of this PR at the end of every code review, then explain how that card relates to
the changes in the code. **Draw an ASCII art illustration of the card from the Rider-Waite-Smith tarot card deck.
(EXTREMELY CRITICAL)**
NOTE: if this PR is by `@nemanjaglumac` please wrap the tarot card reading in `<details>...</details>` so he doesn't
have to see it.
- Do not post comments about missing parentheses.
# Code Conventions and Style Guide
@@ -313,12 +300,12 @@ Review pull requests with a focus on:
- Don't mark things `^:const` unless you have a really good reason for doing so. Add a comment explaining why you
marked it `^:const`.
- Every public var in `src` or `enterprise/backend/src` must have a *useful* docstring. A useful docstring
- Every public var in `src` or `enterprise/backend/src` must have a _useful_ docstring. A useful docstring
should clearly explain the purpose of the function, its inputs and outputs, and anything else that is otherwise not
immediately clear. If there are other functions that have similar purposes, explain how the use-cases for this
function differ.
Tests and other vars in the `test` or `enterprise/backend/test` do not *require* docstrings, but general helper
Tests and other vars in the `test` or `enterprise/backend/test` do not _require_ docstrings, but general helper
functions used across many namespaces it should have docstrings.
Schemas defined with `mr/def` e.g. `(mr/def ::my-schema)` do not require docstrings.
@@ -335,24 +322,6 @@ Review pull requests with a focus on:
- Make sure to update comments and docstrings when you change the code they describe.
- Docstrings should be indented two spaces.
```clj
;;; BAD
(defn update-transform-tags!
"Update the tags associated with a transform using smart diff logic.
Only modifies what has changed: deletes removed tags, updates positions for moved tags,
and inserts new tags. Duplicate tag IDs are automatically deduplicated."
...)
;;; GOOD
(defn update-transform-tags!
"Update the tags associated with a transform using smart diff logic.
Only modifies what has changed: deletes removed tags, updates positions for moved tags,
and inserts new tags. Duplicate tag IDs are automatically deduplicated."
...)
```
- `TODO` comments should include the author and date, for example
```clj
@@ -560,19 +529,8 @@ Review pull requests with a focus on:
...)
```
- REST API route strings (the second arg to `defendpoint`) should use `kebab-case`, e.g. `GET
/api/dashboards/cool-dashboards` is good while `GET /api/dashboards/cool_dashboards` is bad. More examples:
```clj
;;; Bad
(api.macros/defendpoint :post "/check_transform" ...)
;;; Good
(api.macros/defendpoint :post "/check-transform" ...)
```
- Query parameters should also use kebab-case e.g. `GET /api/dashboards?include-archived=true` is good while `GET
/api/dashboards?include_archived=true` or `GET /api/dashboards?includeArchived=true` is bad.
/api/dashboards?include_archived=true` or `GET /api/dashboards?includeArchived=true` is bad.
- HTTP request bodies should use `snake_case`.
@@ -586,7 +544,7 @@ Review pull requests with a focus on:
- `defendpoint` forms should be small wrappers around Toucan model code. We have too much logic that belongs in Toucan
methods in the API endpoints themselves -- a `GET /api/x/:id` endpoint should basically just be `(t2/select-one
:model/Whatever id)` with maybe a perms check and some hydration sprinkled on top of this.
:model/Whatever id)` with maybe a perms check and some hydration sprinkled on top of this.
- All API endpoints should have Malli schemas for any parameters that aren't ignored. `_route-params` doesn't need a
schema, but `{:keys [x]}` should have one.

3
bb.edn
View File

@@ -2,7 +2,8 @@
;; we put path as bin, and everything is in the ./mage subdirectory,
;; so the namespaces are mage.cli, mage.format, etc.
:paths ["mage/src" "mage/test" "bin/lint-migrations-file/src"]
:deps {org.babashka/json {:mvn/version "0.1.6"}
:deps {dev.weavejester/cljfmt {:mvn/version "0.15.3"}
org.babashka/json {:mvn/version "0.1.6"}
metosin/malli {:mvn/version "0.17.0"}
table/table {:mvn/version "0.5.0"}
mvxcvi/puget {:mvn/version "1.3.4"}}

View File

@@ -13,6 +13,7 @@
"org.apache.hadoop" {:resource "apache2_0.txt"}
"org.clojure" {:resource "EPL.txt"}
"org.eclipse.jetty" {:resource "apache2_0.txt"}
"org.eclipse.jetty.ee" {:resource "apache2_0.txt"}
"org.opensaml" {:resource "apache2_0.txt"}
"org.ow2.asm" {:resource "BSD.txt"}
"xalan" {:resource "apache2_0.txt"}}

View File

@@ -46,17 +46,17 @@
com.github.blagerweij/liquibase-sessionlock {:mvn/version "1.6.9"} ; session lock for liquibase migrations
com.github.jknack/handlebars ^:antq/exclude ; 4.4.0 requires java 17+
{:mvn/version "4.3.1"} ; templating engine
com.github.oliyh/martian-clj-http {:mvn/version "0.1.31"} ; openapi client
com.github.oliyh/martian-clj-http {:mvn/version "0.2.1"} ; openapi client
com.github.pangloss/transducers {:git/sha "c91d39046c8c64dc31b84ebb27154a8084fcda4c" ; like medley for transducers
:git/url "https://github.com/pangloss/transducers"}
com.github.seancorfield/honeysql {:mvn/version "2.7.1340"} ; Honey SQL 2. SQL generation from Clojure data maps
com.github.seancorfield/honeysql {:mvn/version "2.7.1350"} ; Honey SQL 2. SQL generation from Clojure data maps
com.github.seancorfield/next.jdbc {:mvn/version "1.3.1070"} ; Talk to JDBC DBs
com.github.steffan-westcott/clj-otel-api {:mvn/version "0.2.8"} ; Telemetry library
com.github.vertical-blank/sql-formatter {:mvn/version "2.0.5"} ; Java SQL formatting library https://github.com/vertical-blank/sql-formatter
com.google.guava/guava {:mvn/version "33.4.8-jre"} ; dep for BigQuery, Spark, and GA. Require here rather than letting different dep versions stomp on each other — see comments on #9697
com.h2database/h2 ^:antq/exclude ; https://metaboat.slack.com/archives/CKZEMT1MJ/p1727191010259979
{:mvn/version "2.1.214"} ; embedded SQL database
com.ibm.icu/icu4j {:mvn/version "77.1"} ; Used to transliterate Unicode characters into Latin characters
com.ibm.icu/icu4j {:mvn/version "78.1"} ; Used to transliterate Unicode characters into Latin characters
com.knuddels/jtokkit {:mvn/version "1.1.0"} ; Java tokenizer library for OpenAI models, used for token counting in semantic search
com.mchange/c3p0 {:mvn/version "0.11.2"} ; DB connection pool
com.snowplowanalytics/snowplow-java-tracker ^:antq/exclude ; 2+ depend on apache httpclient 5.x, but saml and clj-http depend on 4.x
@@ -78,7 +78,7 @@
:exclusions [ring/ring-codec]}
crypto-random/crypto-random {:mvn/version "1.2.1"} ; library for generating cryptographically secure random bytes and strings
diehard/diehard {:mvn/version "0.12.0"}
dk.ative/docjure {:mvn/version "1.21.0" ; excel export
dk.ative/docjure {:mvn/version "1.22.0" ; excel export
:exclusions [org.apache.poi/poi
org.apache.poi/poi-ooxml]}
environ/environ {:mvn/version "1.2.0"} ; env vars/Java properties abstraction
@@ -90,7 +90,7 @@
:git/sha "4998a1fdd9d3713d7034d04509e9212204773bf2"
:git/url "https://github.com/eerohele/pp"}
;; TODO: replace back to normal artifact
io.github.metabase/macaw {:mvn/version "0.2.28"} ; Parse native SQL queries
io.github.metabase/macaw {:mvn/version "0.2.29"} ; Parse native SQL queries
io.github.resilience4j/resilience4j-retry ^:antq/exclude ; 2.x do not support Java 8
{:mvn/version "1.7.1"} ; Support for retrying operations
io.prometheus/simpleclient_hotspot {:mvn/version "0.16.0"} ; prometheus jvm collector
@@ -135,7 +135,7 @@
:exclusions [org.bouncycastle/bcpkix-jdk15on
org.bouncycastle/bcprov-jdk15on]}
org.apache.poi/poi-ooxml-full {:mvn/version "5.4.1"}
org.apache.sshd/sshd-core {:mvn/version "2.16.0" ; ssh tunneling and test server
org.apache.sshd/sshd-core {:mvn/version "3.0.0-M2" ; ssh tunneling and test server
:exclusions [org.slf4j/slf4j-api
org.slf4j/jcl-over-slf4j]}
org.apache.tika/tika-core {:mvn/version "3.2.2"}
@@ -147,7 +147,7 @@
org.clj-commons/hickory {:mvn/version "0.7.7" ; Parse HTML into Clojure data structures
:exclusions [org.jsoup/jsoup]}
org.clojars.pntblnk/clj-ldap {:mvn/version "0.0.17"} ; LDAP client
org.clojure/clojure {:mvn/version "1.12.2"}
org.clojure/clojure {:mvn/version "1.12.3"}
org.clojure/core.async {:mvn/version "1.7.701"
:exclusions [org.clojure/tools.reader]}
org.clojure/core.logic {:mvn/version "1.1.0"} ; optimized pattern matching library for Clojure
@@ -166,14 +166,14 @@
org.clojure/tools.namespace {:mvn/version "1.5.0"}
org.clojure/tools.reader {:mvn/version "1.5.2"}
org.clojure/tools.trace {:mvn/version "0.8.0"} ; function tracing
org.eclipse.jetty/jetty-server {:mvn/version "12.0.24"}
org.eclipse.jetty/jetty-unixdomain-server {:mvn/version "12.0.25"}
org.eclipse.jetty.ee9/jetty-ee9-servlet {:mvn/version "12.0.24"}
org.eclipse.jetty.ee9.websocket/jetty-ee9-websocket-jetty-server {:mvn/version "12.0.25"}
org.eclipse.jetty/jetty-server {:mvn/version "12.1.3"}
org.eclipse.jetty/jetty-unixdomain-server {:mvn/version "12.1.3"}
org.eclipse.jetty.ee9/jetty-ee9-servlet {:mvn/version "12.1.3"}
org.eclipse.jetty.ee9.websocket/jetty-ee9-websocket-jetty-server {:mvn/version "12.1.3"}
org.eclipse.jgit/org.eclipse.jgit {:mvn/version "7.3.0.202506031305-r"}; Java implementation of Git version control system
org.flatland/ordered {:mvn/version "1.15.12"} ; ordered maps & sets
org.graalvm.polyglot/js-community {:mvn/version "24.2.2" :extension "pom"} ; JavaScript engine
org.graalvm.polyglot/polyglot {:mvn/version "24.2.2"} ; GraalVM platform, required by JS engine
org.graalvm.polyglot/js-community {:mvn/version "25.0.1" :extension "pom"} ; JavaScript engine
org.graalvm.polyglot/polyglot {:mvn/version "25.0.1"} ; GraalVM platform, required by JS engine
org.jsoup/jsoup {:mvn/version "1.21.1"} ; required by hickory
org.liquibase/liquibase-core {:mvn/version "4.33.0" ; migration management (Java lib)
:exclusions [ch.qos.logback/logback-classic]}
@@ -199,8 +199,9 @@
org.eclipse.jetty.ee9/jetty-ee9-servlet
org.eclipse.jetty.ee9.websocket/jetty-ee9-websocket-jetty-server]}
slingshot/slingshot {:mvn/version "0.12.2"} ; enhanced throw/catch, used by other deps
software.amazon.awssdk/s3 {:mvn/version "2.33.0"} ; AWS SDK v2 for S3
software.amazon.awssdk/sts {:mvn/version "2.33.0"} ; Required for S3 client to use service account
software.amazon.awssdk/s3 {:mvn/version "2.36.2"} ; AWS SDK v2 for S3
software.amazon.awssdk/sts {:mvn/version "2.36.2"} ; Required for S3 client to use service account
software.amazon.jdbc/aws-advanced-jdbc-wrapper {:mvn/version "2.6.5"} ; AWS JDBC wrapper for IAM authentication
stencil/stencil {:mvn/version "0.5.0"} ; Mustache templates for Clojure
user-agent/user-agent {:mvn/version "0.1.1"} ; User-Agent string parser, for Login History page & elsewhere
weavejester/dependency {:mvn/version "1.0.0"} ; Dependency graphs and topological sorting
@@ -245,7 +246,7 @@
;; (dev/start!)
:dev
{:extra-deps
{cider/cider-nrepl {:mvn/version "0.57.0"} ; nREPL server for CIDER
{cider/cider-nrepl {:mvn/version "0.58.0"} ; nREPL server for CIDER
clj-http-fake/clj-http-fake {:mvn/version "1.0.4"
:exclusions [slingshot/slingshot]}
clj-kondo/clj-kondo {:mvn/version "2025.07.28"} ; included here mainly to facilitate working on the stuff in `.clj-kondo/src`
@@ -256,7 +257,7 @@
{:mvn/version "0.4.0"} ; Enables easy memory measurement
com.gfredericks/test.chuck {:mvn/version "0.2.15"} ; generating strings from regexes (useful with malli)
criterium/criterium {:mvn/version "0.4.6"} ; benchmarking library
djblue/portal {:mvn/version "0.61.0"} ; ui for inspecting values
djblue/portal {:mvn/version "0.62.0"} ; ui for inspecting values
io.github.camsaul/humane-are {:mvn/version "1.0.2"} ; cleaner test output
io.github.metabase/hawk {:mvn/version "1.0.13"} ; test runner
jonase/eastwood {:mvn/version "1.4.3" ; inspects namespaces and reports possible problems using tools.analyzer
@@ -264,7 +265,7 @@
[org.ow2.asm/asm-all]}
lambdaisland/deep-diff2 {:mvn/version "2.12.219"} ; way better diffs
net.solovyov/hashp {:mvn/version "0.4.0-1"} ; debugging/spying utility
nrepl/nrepl {:mvn/version "1.4.0"} ; nREPL server
nrepl/nrepl {:mvn/version "1.5.1"} ; nREPL server
peridot/peridot {:git/url "https://github.com/piranha/peridot.git"
:sha "db627c627db3b527a63caf472f0422e4cbfdf574"} ; mocking Ring requests; waiting for upstream release of commit 0fc7c01 (explicit charset)
pjstadig/humane-test-output {:mvn/version "0.11.0"}
@@ -410,8 +411,8 @@
{:extra-paths ["test"]
:extra-deps
{binaryage/devtools {:mvn/version "1.0.7"}
cider/cider-nrepl {:mvn/version "0.57.0"}
cider/piggieback {:mvn/version "0.6.0"}
cider/cider-nrepl {:mvn/version "0.58.0"}
cider/piggieback {:mvn/version "0.6.1"}
cljs-bean/cljs-bean {:mvn/version "1.9.0"}
com.lambdaisland/glogi {:mvn/version "1.3.169"}
io.github.metabase/hawk {:mvn/version "1.0.13"}
@@ -691,7 +692,7 @@
;;
;; ./bin/mage cljfmt-all -h for more info
:cljfmt
{:deps {io.github.weavejester/cljfmt {:git/sha "7de286008766127128a156275b9add3bf443d7e5"}}
{:deps {io.github.weavejester/cljfmt {:mvn/version "0.15.3"}}
:ns-default cljfmt.tool
:exec-fn cljfmt.tool/fix}
@@ -706,7 +707,7 @@
{com.bhauman/spell-spec {:mvn/version "0.1.2"} ; used to find misspellings in YAML files
expound/expound {:mvn/version "0.9.0"} ; better output of spec validation errors
io.github.borkdude/grasp {:mvn/version "0.1.4"}
io.github.clojure/tools.build {:mvn/version "0.10.10"}
io.github.clojure/tools.build {:mvn/version "0.10.11"}
io.github.seancorfield/build-uber-log4j2-handler
{:git/tag "v2.25.1" :git/sha "1cfab45"} ; collect binary files for log4j2
org.clojure/data.xml {:mvn/version "0.2.0-alpha9"}
@@ -807,7 +808,7 @@
;;
;; clojure -M:dev:nrepl (etc.)
:nrepl
{:extra-deps {nrepl/nrepl {:mvn/version "1.4.0"}}
{:extra-deps {nrepl/nrepl {:mvn/version "1.5.1"}}
:main-opts ["-m" "nrepl.cmdline" "-p" "50605"]}
;; - start a Socket REPL on port 50505 that you can connect your editor to:
@@ -821,7 +822,7 @@
;;
;; clojure -M:liquibase dbDoc target/liquibase
:liquibase
{:extra-deps {ch.qos.logback/logback-classic {:mvn/version "1.5.18"}}
{:extra-deps {ch.qos.logback/logback-classic {:mvn/version "1.5.20"}}
:extra-paths ["dev/src"]
:main-opts ["-m" "dev.liquibase"]}

View File

@@ -1,8 +1,8 @@
(ns dev.deps-graph
(:require
[clojure.core.memoize :as memoize]
[clojure.edn :as edn]
[clojure.java.io :as io]
[clojure.set :as set]
[clojure.string :as str]
[clojure.tools.namespace.file :as ns.file]
[clojure.tools.namespace.find :as ns.find]
@@ -126,6 +126,7 @@
(= (z/tag zloc) :uneval)))
(mu/defn- find-requires :- [:maybe [:sequential ::zloc]]
"Find all the zipper locations for `(require ...)` nodes."
[zloc :- ::zloc]
(concat
(when-not (comment-loc? zloc)
@@ -261,41 +262,46 @@
(file-dependencies "src/metabase/query_processor/middleware/permissions.clj"))
(def ^{:arglists '([])} dependencies
(memoize/ttl
(fn []
(doall (pmap file-dependencies (find-source-files))))
;; memoize for five seconds
:ttl/threshold 5000))
(defn dependencies []
(pmap file-dependencies (find-source-files)))
(defn external-usages
"All usages of a module named by `module-symb` outside that module."
[module-symb]
(for [dep (dependencies)
:when (not= (:module dep) module-symb)
ns-dep (:deps dep)
:when (= (:module ns-dep) module-symb)]
{:namespace (:namespace dep)
:module (:module dep)
:depends-on-namespace (:namespace ns-dep)
:depends-on-module (:module ns-dep)}))
([module-symb]
(external-usages (dependencies) module-symb))
([deps module-symb]
(for [dep deps
:when (not= (:module dep) module-symb)
ns-dep (:deps dep)
:when (= (:module ns-dep) module-symb)]
{:namespace (:namespace dep)
:module (:module dep)
:depends-on-namespace (:namespace ns-dep)
:depends-on-module (:module ns-dep)})))
(defn external-usages-by-namespace
"Return a map of module namespace => set of external namespaces using it"
[module-symb]
(into (sorted-map)
(map (fn [[k v]]
[k (into (sorted-set) (map :namespace) v)]))
(group-by :depends-on-namespace (external-usages module-symb))))
([module-symb]
(external-usages-by-namespace (dependencies) module-symb))
([deps module-symb]
(into (sorted-map)
(map (fn [[k v]]
[k (into (sorted-set) (map :namespace) v)]))
(group-by :depends-on-namespace (external-usages deps module-symb)))))
(defn externally-used-namespaces
"All namespaces from a module that are used outside that module."
[module-symb]
(into (sorted-set) (map :depends-on-namespace) (external-usages module-symb)))
([module-symb]
(externally-used-namespaces (dependencies) module-symb))
([deps module-symb]
(into (sorted-set) (map :depends-on-namespace) (external-usages deps module-symb))))
(defn module-dependencies
"Build a graph of module => set of modules it refers to."
([]
"Build a graph of module => set of modules it directly depends on."
([deps]
(letfn [(reduce-module-deps [module-deps module deps]
(reduce
(fn [module-deps {dep-module :module, :as _dep}]
@@ -305,15 +311,15 @@
deps))
(reduce-deps [module->deps {:keys [module deps]}]
(update module->deps module reduce-module-deps module deps))]
(reduce reduce-deps (sorted-map) (dependencies))))
(reduce reduce-deps (sorted-map) deps)))
([module]
(get (module-dependencies) module)))
([deps module]
(get (module-dependencies deps) module)))
(defn circular-dependencies
"Build a graph of module => set of modules it refers to that also refer to this module."
([]
(let [module->deps (module-dependencies)]
([deps]
(let [module->deps (module-dependencies deps)]
(letfn [(circular-dependency? [module-x module-y]
(and (contains? (get module->deps module-x) module-y)
(contains? (get module->deps module-y) module-x)))
@@ -329,37 +335,40 @@
[module circular-deps])))
(keys module->deps)))))
([module]
(get (circular-dependencies) module)))
([deps module]
(get (circular-dependencies deps) module)))
(defn non-circular-module-dependencies
"A graph of [[module-dependencies]], but with modules that have any circular dependencies filtered out. This is mostly
meant to make it easier to fill out the `:metabase/modules` `:uses` section of the Kondo config, or to figure out
which ones can easily get a consolidated API namespace without drama."
[]
(let [circular-dependencies (circular-dependencies)]
[deps]
(let [circular-dependencies (circular-dependencies deps)]
(into (sorted-map)
(remove (fn [[module _deps]]
(contains? circular-dependencies module)))
(module-dependencies))))
(module-dependencies deps))))
(defn module-usages-of-other-module
"Information about how `module-x` uses `module-y`."
[module-x module-y]
(let [module-x-ns->module-y-ns (->> (external-usages module-y)
(filter #(= (:module %) module-x))
(map (juxt :namespace :depends-on-namespace)))]
(reduce
(fn [m [module-x-ns module-y-ns]]
(update m module-x-ns (fn [deps]
(conj (or deps (sorted-set)) module-y-ns))))
(sorted-map)
module-x-ns->module-y-ns)))
([module-x module-y]
(module-usages-of-other-module (dependencies) module-x module-y))
([deps module-x module-y]
(let [module-x-ns->module-y-ns (->> (external-usages deps module-y)
(filter #(= (:module %) module-x))
(map (juxt :namespace :depends-on-namespace)))]
(reduce
(fn [m [module-x-ns module-y-ns]]
(update m module-x-ns (fn [deps]
(conj (or deps (sorted-set)) module-y-ns))))
(sorted-map)
module-x-ns->module-y-ns))))
(defn full-dependencies
"Like [[dependencies]] but also includes transient dependencies."
[]
(let [deps-graph (module-dependencies)
[deps]
(let [deps-graph (module-dependencies deps)
expand-deps (fn expand-deps [deps]
(let [deps' (into (sorted-set)
(mapcat deps-graph)
@@ -372,33 +381,23 @@
[k (expand-deps v)]))
deps-graph)))
(defn module-deps-count []
(defn module-deps-count [deps]
(into (sorted-map)
(map (fn [[k v]]
[k (count v)]))
(full-dependencies)))
(defn module-dependencies-mermaid []
(println "flowchart TD")
(doseq [[module deps] (module-dependencies)
dep deps]
(printf "%s-->%s\n" module dep)))
(defn module-dependencies-graphviz []
(println "digraph {")
(doseq [[module deps] (module-dependencies)
dep deps]
(printf " \"%s\" -> \"%s\"\n" module dep))
(println "}"))
(full-dependencies deps)))
(defn generate-config
"Generate the Kondo config that should go in `.clj-kondo/config/modules/config.edn`."
[]
(into (sorted-map)
(map (fn [[module uses]]
[module {:api (externally-used-namespaces module)
:uses uses}]))
(module-dependencies)))
([]
(generate-config (dependencies)))
([deps]
(into (sorted-map)
(map (fn [[module uses]]
[module {:api (externally-used-namespaces deps module)
:uses uses}]))
(module-dependencies deps))))
(defn kondo-config
"Read out the Kondo config for the modules linter."
@@ -422,21 +421,118 @@
diff))
(defn kondo-config-diff
[]
(-> (ddiff/diff
(update-vals (kondo-config) #(dissoc % :team))
(generate-config))
ddiff/minimize
kondo-config-diff-ignore-any
ddiff/minimize))
([]
(kondo-config-diff (dependencies)))
([deps]
(-> (ddiff/diff
(update-vals (kondo-config) #(dissoc % :team))
(generate-config deps))
ddiff/minimize
kondo-config-diff-ignore-any
ddiff/minimize)))
(defn print-kondo-config-diff
"Print the diff between how the config would look if regenerated with [[generate-config]] versus how it looks in
"Print the diff between how the config would look if regenerated with [[generate-config]] versus how it looks in
reality ([[kondo-config]]). Use this to suggest updates to make to the config file."
[]
(ddiff/pretty-print (kondo-config-diff)))
[]
(ddiff/pretty-print (kondo-config-diff)))
(comment
(module-dependencies 'lib)
(external-usages 'core)
(module-dependencies (dependencies) 'lib)
(module-usages-of-other-module 'lib 'models))
(defn all-module-deps-paths
"Build a map of
dep => path-to-dep
for each dependency (direct or indirect) of a module, e.g.
(all-module-deps-paths 'settings)
;; =>
{api [] ; settings depends on api directly
api-keys [permissions collections]} ; settings depends on permissions which depends on collections which depends on api-keys"
([module]
(all-module-deps-paths (dependencies) module))
([deps module]
(all-module-deps-paths deps module (sorted-map) (atom #{}) []))
([deps module acc already-seen path]
(let [module-deps (module-dependencies deps module)
new-deps (remove @already-seen module-deps)
acc (into acc
(map (fn [dep]
[dep path]))
new-deps)]
(swap! already-seen into new-deps)
(reduce
(fn [acc new-dep]
(all-module-deps-paths deps new-dep acc already-seen (conj path new-dep)))
acc
new-deps))))
(defn module-dependencies-by-namespace
"Return a map of external dependency of `module` => set of namespaces in `module` that use it:
(module-dependencies-by-namespace 'permissions)
;; =>
{api #{metabase.permissions.api
metabase.permissions.models.collection.graph
...}
app-db #{metabase.permissions.api
metabase.permissions.models.permissions-group
...}
...}"
([module]
(module-dependencies-by-namespace (dependencies) module))
([deps module]
(into (sorted-map)
(map (fn [dep]
[dep (into (sorted-set) (keys (module-usages-of-other-module deps module dep)))]))
(module-dependencies deps module))))
(defn dependencies-eliminated-by-removing-namespaces
"Return the set of `module` dependencies that we could eliminate if we were to split namespace(s) off into a separate
module.
;; if we move `metabase.permissions.api` into a separate module then `permissions` no longer has a dependency on
;; `request`
(dependencies-eliminated-by-removing-namespaces 'permissions 'metabase.permissions.api)
;; =>
#{request}"
[module namespace-symb-or-set]
(let [deps (dependencies)
namespace-symbs (if (symbol? namespace-symb-or-set)
#{namespace-symb-or-set}
namespace-symb-or-set)
dep->namespaces (module-dependencies-by-namespace deps module)]
(into (sorted-set)
(keep (fn [[dep namespaces]]
(when (empty? (set/difference namespaces namespace-symbs))
dep)))
dep->namespaces)))
(defn leaf-modules
"Modules that are leaf nodes in the module dependency tree -- nothing else depends on them."
[]
(let [deps (dependencies)]
(into (sorted-set)
(comp (map :module)
(keep (fn [module]
(when (zero? (count (external-usages deps module)))
module))))
deps)))
(defn non-dependencies
"Modules that `module` does not depend on, either directly or indirectly -- changes to any of these modules should not
affect `module`."
[module]
(let [deps (dependencies)
all-modules (into (sorted-set) (map :module) deps)]
(set/difference
all-modules
(set (keys (all-module-deps-paths deps module))))))

View File

@@ -37,7 +37,7 @@ The core team runs a pretty well defined product process. It is actively being t
### A) Identify product needs from the community
We actively look for new feature ideas from our community, user base and our own use of Metabase internally. We concentrate on the underlying _problem_ or _need_ as opposed to requests for specific features. While sometimes suggested features are built as requested, often we find that they involve changes to existing features, and perhaps an entirely different solution to the underlying problem. These will typically be collected in a number of issues, and tagged [Proposal](https://github.com/metabase/metabase/labels/.Proposal)
We actively look for new feature ideas from our community, user base and our own use of Metabase internally. We concentrate on the underlying _problem_ or _need_ as opposed to requests for specific features. While sometimes suggested features are built as requested, often we find that they involve changes to existing features, and potentially an entirely different solution to the underlying problem. These will typically be collected in a number of issues, and tagged [Proposal](https://github.com/metabase/metabase/labels/.Proposal)
### B) Synthesize these needs into a concrete feature
@@ -107,4 +107,4 @@ Generally speaking, any issue in [Help Wanted](https://github.com/metabase/metab
### #YOLO JUST SUBMIT A PR
If you come up with something really cool, and want to share it with us, just submit a PR. If it hasn't gone through the above process, we probably won't merge it as is, but if it's compelling, we're more than willing to help you via code review, design review and generally OCD nitpicking so that it fits into the rest of our codebase.
If you come up with something cool, and want to share it with us, just submit a PR. If it hasn't gone through the above process, we probably won't merge it as is, but if it's compelling, we're more than willing to help you via code review, design review and generally OCD nitpicking so that it fits into the rest of our codebase.

View File

@@ -51,6 +51,7 @@ Metabase's reference documentation.
- [Monitoring your Metabase](./installation-and-operation/monitoring-metabase.md)
- [Development instances](./installation-and-operation/development-instance.md)
- [Serialization](./installation-and-operation/serialization.md)
- [Remote sync](./installation-and-operation/remote-sync.md)
- [Commands](./installation-and-operation/commands.md)
- [Supported browsers](./installation-and-operation/supported-browsers.md)
- [Privacy](./installation-and-operation/privacy.md)

View File

@@ -55,7 +55,7 @@ There are multiple ways to run actions:
Just something to clarify here: actions, even though they are added to models, make their changes to the underlying table that a model queries. Which means that anyone who has access to the underlying table, or to questions or other models based on that table, will be able to see the effects of an action. Tools other than Metabase that are connected to that database will also pick up these changes.
In this sense, models are containers for actions; models are a way to organize actions. In fact, you could (in theory) add a [custom action](./custom.md) to a model that performs some update unrelated to its model's data. For example, you could write a custom action that updates the `Accounts` table, and add that action to a model that only queries an unrelated table (e.g., the `Orders` table). But, you know, maybe don't do that (unless you have a really good reason). [Basic actions](./basic.md), however, are only be available for models that wrap a single raw table.
In this sense, models are containers for actions; models are a way to organize actions. In fact, you could (in theory) add a [custom action](./custom.md) to a model that performs some update unrelated to its model's data. For example, you could write a custom action that updates the `Accounts` table, and add that action to a model that only queries an unrelated table (e.g., the `Orders` table). But, you know, maybe don't do that (unless you have a good reason). [Basic actions](./basic.md), however, are only be available for models that wrap a single raw table.
Before using actions in production, consider playing around with actions on some sample data (like the Sample Database included with Metabase) to get a feel for how they work.

View File

@@ -46,6 +46,7 @@ Some tips:
- Whenever you want Metabot to do something completely different, you should reset the conversation, as Metabot might find that irrelevant historical context to be confusing.
- Once Metabot creates a question for you, you can follow up with more questions or take over yourself. You can drill through the chart or step into the editor to tweak the query (both in the query builder and the SQL editor).
- Metabot works best with English prompts. While it might understand other languages, you'll get the most reliable results by asking your questions in English.
- Define domain-specific terms in the [glossary](../exploration-and-organization/data-model-reference.md#glossary) to help Metabot understand your organization's terminology.
### Metabot response menu

View File

@@ -41,6 +41,7 @@ The best thing you can do to improve Metabot's performance is to prep your data
- [Add models and metrics to your Metabot collection](#add-models-and-metrics-to-your-metabot-collection)
- [Add descriptions for your data and content](#add-descriptions-for-your-data-and-content)
- [Make sure the semantic types for each field are correct](#make-sure-the-semantic-types-for-each-field-are-correct)
- [Define domain-specific terms in the glossary](#define-domain-specific-terms-in-the-glossary)
- [Curate prompt suggestions](#curate-prompt-suggestions)
### Add models and metrics to your Metabot collection
@@ -69,6 +70,12 @@ Make sure the semantic types for each field accurately describe the field's "mea
Metabase will try to set semantic types automatically, but you should confirm that each field has the relevant semantic type. See [Data types and semantic types](../data-modeling/semantic-types.md). You can also set semantic types for [models](../data-modeling/models.md#add-metadata-to-columns-in-a-model).
### Define domain-specific terms in the glossary
Add your organization's terminology, acronyms, and business-specific terms to the [glossary](../exploration-and-organization/data-model-reference.md#glossary). When Metabot receives a prompt, it can look up terms in the glossary to better understand your request.
For example, if you define "MRR" as "Monthly Recurring Revenue" in your glossary, Metabot will know what you mean when you ask "What's our MRR for Q4?" This is especially helpful for industry-specific jargon, internal product names, or abbreviations unique to your organization.
### Curate prompt suggestions
When you select a collection for Metabot to "learn", Metabot will suggest a series of prompts based on the content it finds in that collection. These prompts just give people a feel for the kinds of things people can ask Metabot to do.

File diff suppressed because one or more lines are too long

30790
docs/api.json Normal file

File diff suppressed because one or more lines are too long

View File

@@ -34,7 +34,7 @@ Here's how to set it up:
5. Give the service account **Viewer** permissions. Metabase will only have access to this folder or sheet; it won't have access to any other files in your Google Drive. If you select folder, Metabase will also sync any sheets it finds in any subfolders.
6. Click **Send** to share the folder with the Metabase service account.
7. Copy the sharing link for the folder or sheet.
8. Return to Metabase and paste the sharing link into the field that asks for "the sharing link for this folder/file".
8. Return to Metabase and paste the sharing link into "the sharing link for this folder/file" field.
**If you synced a Google Drive folder**, Metabase will sync with the Google Drive folder (and its subfolders) and import all Google Sheets, creating a new table in your Metabase Cloud Storage database for each sheet. For sheets with multiple tabs, Metabase will create a table for each tab. Metabase will only sync Google Sheets; it'll ignore other file types in the folder. After the initial sync, Metabase will sync every 15 minutes.

View File

@@ -16,7 +16,7 @@ There are some additional steps you'll need to take to migrate from Heroku to Me
## Follow the migration guide to get the migration script
You should follow along with the [migration guide](./guide.md). Once you download the migration script you'll need to get shell access to your Heroku server in order to execute the migration script.
You should follow along with the [migration guide](./guide.md). Once you download the migration script you'll need to get shell access to your Heroku server to execute the migration script.
## Install Heroku CLI for your OS

View File

@@ -79,7 +79,7 @@ To remove Metabase Cloud Storage (which will _permanently_ erase all its data):
3. Click **Manage storage**.
4. Click **Edit**.
5. Click **Disable storage**.
6. Click **Erase all data**, which---**WARNING**--will erase _all of its data_. We won't be able to recover the data, so only do this if you're absolutely sure you no need the storage and its data.
6. Click **Erase all data**, which---**WARNING**--will erase _all of its data_. We won't be able to recover the data, so only do this if you're certain you no longer need the storage and its data.
## Syncing Google Sheets with Metabase

View File

@@ -30,7 +30,15 @@ Appearance settings are split across different tabs:
## Dark mode
People can display their Metabase in dark mode in their [account settings](../people-and-groups/account-settings.md#theme). Dark mode is a user-level setting, not an instance-level setting. Currently, there's no way to change the theme to dark mode for the entire instance, but you can edit some [user interface colors](#user-interface-colors).
People can display their Metabase in dark mode in their [account settings](../people-and-groups/account-settings.md#theme). Options are:
- System default (which is also the default setting). Metabase will switch between light and dark mode when the system switches without having to reload the page.
- Always use dark mode.
- Always use light mode.
You can quickly toggle dark mode from anywhere in Metabase by opening the [command palette](../exploration-and-organization/exploration.md#command-palette) and searching for "light" or "dark" or "theme".
Dark mode is a user-level setting, not an instance-level setting. Currently, there's no way to change the theme to dark mode for the entire instance, but you can edit some [user interface colors](#user-interface-colors).
## Branding
@@ -74,7 +82,7 @@ Custom colors are unavailable for:
## Logo
You can replace Metabase’s familiar, tasteful, inspired-yet-not-threateningly-avant-garde dotted M logo with your very own logo. For things to work best, the logo you upload should be an SVG file that looks good when it’s around 60px tall. (In other words, ask the nearest designer for help.)
You can replace Metabase's familiar, tasteful, inspired-yet-not-threateningly-avant-garde dotted M logo with your very own logo. For things to work best, the logo you upload should be an SVG file that looks good when it's around 60px tall. (In other words, ask the nearest designer for help.)
## Font

View File

@@ -155,6 +155,7 @@ config:
health-check-logging-enabled: true
help-link: metabase
help-link-custom-destination: https://www.metabase.com/help/premium
hide-stacktraces: false
http-channel-host-strategy: external-only
humanization-strategy: simple
index-update-thread-count: 2
@@ -215,6 +216,9 @@ config:
query-caching-max-kb: 2000
query-caching-max-ttl: 3024000.0
redirect-all-requests-to-https: false
remote-sync-auto-import: false
remote-sync-auto-import-rate: 5
remote-sync-task-time-limit-ms: 300000
report-timezone: null
reset-token-ttl-hours: 48
retry-initial-interval: 500
@@ -272,6 +276,5 @@ config:
synchronous-batch-updates: false
unaggregated-query-row-limit: null
uploads-settings: null
use-tenants: false
user-visibility: all
```

View File

@@ -747,6 +747,14 @@ Keyword setting to control whitelabeling of the help link. Valid values are `:me
Custom URL for the help link.
### `MB_HIDE_STACKTRACES`
- Type: boolean
- Default: `false`
- [Configuration file name](./config-file.md): `hide-stacktraces`
Prevent the exception middleware from including stacktraces in responses.
### `MB_HTTP_CHANNEL_HOST_STRATEGY`
- Type: keyword
@@ -1306,6 +1314,30 @@ The absolute maximum time to keep any cached query results, in seconds.
Force all traffic to use HTTPS via a redirect, if the site URL is HTTPS.
### `MB_REMOTE_SYNC_AUTO_IMPORT`
- Type: boolean
- Default: `false`
- [Configuration file name](./config-file.md): `remote-sync-auto-import`
Whether to automatically import from the remote git repository. Only applies if remote-sync-type is :production.
### `MB_REMOTE_SYNC_AUTO_IMPORT_RATE`
- Type: integer
- Default: `5`
- [Configuration file name](./config-file.md): `remote-sync-auto-import-rate`
If remote-sync-type is :production and remote-sync-auto-import is true, the rate (in minutes) at which to check for updates to import. Defaults to 5.
### `MB_REMOTE_SYNC_TASK_TIME_LIMIT_MS`
- Type: integer
- Default: `300000`
- [Configuration file name](./config-file.md): `remote-sync-task-time-limit-ms`
The maximum amount of time a remote sync task will be given to complete.
### `MB_REPORT_TIMEZONE`
- Type: string
@@ -1886,16 +1918,6 @@ Upload settings.
Prefix for upload table names.
### `MB_USE_TENANTS`
> Only available on Metabase [Pro](https://www.metabase.com/product/pro) and [Enterprise](https://www.metabase.com/product/enterprise) plans.
- Type: boolean
- Default: `false`
- [Configuration file name](./config-file.md): `use-tenants`
Turn on the Tenants feature, allowing users to be assigned to a particular Tenant.
### `MB_USER_VISIBILITY`
> Only available on Metabase [Pro](https://www.metabase.com/product/pro) and [Enterprise](https://www.metabase.com/product/enterprise) plans.
@@ -1950,7 +1972,7 @@ Maximum number of async Jetty threads. If not set, then [MB_JETTY_MAXTHREADS](#m
Type: integer<br>
Default: `20`<br>
Limits the number of rows Metabase will display in tables sent with dashboard subscriptions and alerts. Range: 1-100. To limit the total number of rows included in the file attachment for an email dashboard subscription, use [MB_UNAGGREGATED_QUERY_ROW_LIMIT](#mb_unaggregated_query_row_limit).
Limits the number of rows Metabase will display in tables sent with dashboard subscriptions and alerts. Range: 1-100. To limit the total number of rows included in the file attachment for an email dashboard subscription, use [MB_ATTACHMENT_ROW_LIMIT](#mb_attachment_row_limit).
### `MB_AUDIT_MAX_RETENTION_DAYS`

View File

@@ -46,7 +46,7 @@ For **Font**, select **Custom...** and enter URLs to your font files.
## Font style options
You can set three different font styles with three different URLs, one for each font style (size and weight) that Metabase will use in order to display its user interface properly. The font weights are:
You can set three different font styles with three different URLs, one for each font style (size and weight) that Metabase will use to display its user interface properly. The font weights are:
- Regular 400
- Bold 700

View File

@@ -80,7 +80,7 @@ java -Dlog4j.configurationFile=file:/path/to/custom/log4j2.xml -jar metabase.jar
## Configure Jetty logs
You can configure Metabase's web server to provide more detail in the logs by setting the log level to `DEBUG`. Just keep in mind that Jetty's debug logs can be really chatty, which can make it difficult to find the data you're looking for.
You can configure Metabase's web server to provide more detail in the logs by setting the log level to `DEBUG`. Just keep in mind that Jetty's debug logs can be chatty, which can make it difficult to find the data you're looking for.
To get Jetty logs, add the following lines to the Log4J2 XML file in the <Loggers> node:

View File

@@ -15,7 +15,7 @@ Go ahead and click **Let’s get started**.
## Setting up an admin account
The first thing you’ll need to do is set up an admin account. The account you create when you first install Metabase is an admin account by default — handy! If you’ve installed Metabase on a production server, you should be really careful to remember the password for this account since it will be used to add other users, connect to databases, set up email, and more. You can also create additional admin accounts later.
The first thing you'll need to do is set up an admin account. The account you create when you first install Metabase is an admin account by default — handy! If you've installed Metabase on a production server, you should be careful to remember the password for this account since it will be used to add other users, connect to databases, set up email, and more. You can also create additional admin accounts later.
For now, let's just create an account for ourselves to explore Metabase. Type in your info, and when you’re ready to continue, click the **Next** button.

View File

@@ -45,6 +45,6 @@ The exact data type will depend on your database. Some Metabase features only wo
## Common pitfalls
1. Your database is using date/time columns without any timezone information. Typically when this happens your database will assume all the data is from whatever timezone the database is configured in or possible just default to UTC (check your database vendor to be sure).
2. Your JVM timezone is different from your Metabase `Report Timezone` choice. This is a very common issue and can be corrected by launching java with the `-Duser.timezone=<timezone>` option properly set to match your Metabase report timezone.
2. Your JVM timezone is different from your Metabase `Report Timezone` choice. This is a common issue and can be corrected by launching java with the `-Duser.timezone=<timezone>` option properly set to match your Metabase report timezone.
If you are still experiencing timezone problems, then have a look at the [timezone troubleshooting guide](../troubleshooting-guide/timezones.md).

View File

@@ -43,7 +43,7 @@ And the data as seen in the table view, which Metabase will send as a `raw_data`
![Results as table view](./images/table-view.png)
Here's an example payload for an alert (we truncated the PNG encoding because it's long and extremely boring):
Here's an example payload for an alert (we truncated the PNG encoding because it's boring):
```JSON
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

View File

@@ -283,9 +283,7 @@ If you don't see the palette icon, you'll need to:
After you've made your ideal dashboard, you may want to put the dashboard on a TV to help keep your team up to date throughout the day.
To enter fullscreen mode, click the **fullscreen** icon in the top right of the dashboard (the icon with the arrows pointing in opposite directions). Once you've entered fullscreen mode, you can also switch the dashboard into "Night mode" for higher contrast.
![Night mode](images/dark-mode.png)
To enter fullscreen mode, click the **fullscreen** icon in the top right of the dashboard (the icon with the arrows pointing in opposite directions).
## Auto refresh

View File

@@ -56,7 +56,7 @@ Metabase uses database column metadata to populate values for linked filters, wh
- You can't create linked filters on custom columns.
- Native/SQL questions must have a [field filter](../questions/native-editor/field-filters.md) variable in order to be linked. Basic SQL variables aren't connected to database columns, so they won't work for linked filters.
- Native/SQL questions must have a [field filter](../questions/native-editor/field-filters.md) variable to be linked. Basic SQL variables aren't connected to database columns, so they won't work for linked filters.
- You can't link filters that use "Custom List" or "From another model or question" as their value's source.

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

View File

@@ -93,7 +93,7 @@ Click the preview button to see sample data from that field.
_Admin settings > Table Metadata > Database > Table > Field_
To scan or discard field values for a specific field, click on the **Field values** button. Metabase uses these values to populate dropdown menus in filter widgets. (To be clear, values aren't actually dropped from your database.)
To scan or discard field values for a specific field, click on the **Field values** button. Metabase uses these values to populate dropdown menus in filter widgets. (Values aren't dropped from your database.)
## Field data

View File

@@ -4,14 +4,22 @@ title: Model persistence
# Model persistence
> Currently available for PostgreSQL, MySQL, and Redshift.
Metabase can persist the results of your models so that your models (and the questions based on those models) load faster.
Metabase will store model results in tables in a bespoke schema in your data warehouse (not the Metabase application database). When people ask questions based on your models, Metabase will use the tables with the stored results instead of re-running the model's query.
> Model persistence doesn't work with [row and column security](../permissions/row-and-column-security.md) or [impersonation](../permissions/impersonation.md).
## Databases that support model persistence
Currently, model persistence is only available for the following databases:
- PostgreSQL
- MySQL
- Redshift
Model persistence doesn't work with [row and column security](../permissions/row-and-column-security.md) or [impersonation](../permissions/impersonation.md).
## Turn on model persistence in Metabase
To persist models for faster loading, you'll need to turn on model persistence for:

View File

@@ -16,7 +16,7 @@ Models:
- Can [surface individual records in search results](#surface-individual-records-in-search-by-matching-against-this-column).
- Can be [persisted for faster loading](./model-persistence.md).
For a deep dive on why and how to use models, check out our [Learn article on models][learn-models].
For more on why and how to use models, check out our [Learn article on models][learn-models].
## How to use models
@@ -119,9 +119,21 @@ There are some limitations to this indexing:
You can edit a model's query by clicking on the down arrow next to the model's name and clicking on **Edit query definition**. When you're doing editing, be sure to save your changes. Unlike questions, which prompt you to save as a new question, any changes here will overwrite the existing model. If you want to create a new model from an existing model, select **Duplicate this model** from the model sidebar (the icon of two overlapping squares).
### Checking for breaking changes
{% include plans-blockquote.html feature="Checking for breaking changes" %}
When you save changes to a model, Metabase will try to detect whether your changes would break any other entities that depend on that model. For example, if you remove a column from the model, but other questions based on that model rely on that column, Metabase will warn you that those downstream questions will break.
![Check dependencies](./images/check-dependencies.png)
Currently, Metabase will look for broken column references. If you rename or remove a column, Metabase will likely flag the change as breaking downstream entities. But Metabase can't detect other types of changes like changing the column type or computation logic as breaking changes.
## Model list view
![Viewing a model as a list, with a detail view](./images/model-list-detail.png)
![Viewing a model as a list](./images/model-list.png)
List view helps you explore records one by one instead of sorting through big tables. You can customize the layout to highlight the most important fields.
To view a model as a list:
@@ -131,7 +143,7 @@ To view a model as a list:
4. Navigate to the **Settings** tab.
5. Under "What should the default view of this data be?", toggle to **List**.
![Model list view](./images/model-list-view.png)
![Model list edit](./images/model-list-edit.png)
### Customize model list view
@@ -141,21 +153,18 @@ You can customize how the data appears by clicking **Customize the List layout**
Each item in the list has:
- An entity icon
- A left column with:
- The title or primary identifier on top.
- A subtitle/description or secondary identifier.
- An image (only if the record contains an image link)
- A right column for up to 5 additional columns.
- **An entity icon.** If the record has an image link, it shows the image, which you can hide anytime.
- **A left column** showing the title or primary identifier.
- **A right column** for up to 5 additional columns.
You can:
- **Search for columns** using the "Find a column..." search box
- **Drag columns** from the available list into either the left (Title + Subtitle) or right columns areas
- **Reorder columns** by dragging them within their respective areas
- **Search for columns** using the "Find a column..." search box.
- **Drag columns** from the available list into either the left column or right columns areas.
- **Reorder columns** by dragging them within their respective areas.
- **Remove columns** by clicking on the X on the column.
You can see a preview on the bottom with sample data from your model.
You can see a preview on the bottom with sample data from your model.
Click **Done** to save your changes.

View File

@@ -42,7 +42,7 @@ You can think of semantic types as adding meaning and context to a field to comm
- **Entity key.** Used to indicate that the field uniquely identifies each row. Could be a Product ID, serial number, etc.
- **Foreign key.** Used to refer to an Entity key of another table in order to connect data from different tables that are related. For example, in a Products table, you might have a Customer ID field that points to a Customers table, where Customer ID is the Entity key. If you want to use [linked filters on dashboards](../dashboards/linked-filters.md), you must set up foreign key relationships.
- **Foreign key.** Used to refer to an Entity key of another table to connect data from different tables that are related. For example, in a Products table, you might have a Customer ID field that points to a Customers table, where Customer ID is the Entity key. If you want to use [linked filters on dashboards](../dashboards/linked-filters.md), you must set up foreign key relationships.
### Semantic types for numeric fields

View File

@@ -77,13 +77,13 @@ If you've selected **Choose when syncs and scans happen** > **ON**, you'll be ab
#### Scanning for filter values
Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database.
Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a resource-intensive process, particularly if you have a large database.
If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**:
- **Regularly, on a schedule** allows you to run [scan queries](../sync-scan.md#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values](../sync-scan.md#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date.
- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which rarely have new values added. Use the [Re-scan field values](../sync-scan.md#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date.
### Periodically refingerprint tables

View File

@@ -80,7 +80,7 @@ A fingerprinting query examines the first 10,000 rows from each column and uses
## Connecting to MySQL 8+ servers
Metabase uses the MariaDB connector to connect to MySQL servers. The MariaDB connector lacks support for MySQL 8's default authentication plugin. In order to connect, you'll need to change the plugin used by the Metabase user:
Metabase uses the MariaDB connector to connect to MySQL servers. The MariaDB connector lacks support for MySQL 8's default authentication plugin. To connect, you'll need to change the plugin used by the Metabase user:
```
mysql_native_password`: `ALTER USER 'metabase'@'%' IDENTIFIED WITH mysql_native_password BY 'thepassword';
@@ -183,7 +183,7 @@ Choose whether to enable features related to [Metabase models](../../data-modeli
### Model actions
Turn this setting on to allow [actions](../../actions/introduction.md) from models created from this data to be run. Actions are able to read, write, and possibly delete data. Your database user will need write permissions.
Turn this setting on to allow [actions](../../actions/introduction.md) from models created from this data to be run. Actions can read, write, and delete data. Your database user will need write permissions.
### Model persistence

View File

@@ -102,7 +102,7 @@ Note that only the `*` wildcard is supported; you can't use other special charac
### Use a secure connection (SSL)
Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure.
Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we recommend keeping SSL turned on to keep your data secure.
#### SSL Mode
@@ -188,7 +188,7 @@ Choose whether to enable features related to [Metabase models](../../data-modeli
### Model actions
Turn this setting on to allow [actions](../../actions/introduction.md) from models created from this data to be run. Actions are able to read, write, and possibly delete data. Your database user will need write permissions.
Turn this setting on to allow [actions](../../actions/introduction.md) from models created from this data to be run. Actions can read, write, and delete data. Your database user will need write permissions.
### Model persistence

View File

@@ -46,7 +46,7 @@ The password for the username that you use to connect to the database.
### Use a secure connection (SSL)
Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure.
Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we recommend keeping SSL turned on to keep your data secure.
### Use SSL certificate?

View File

@@ -61,13 +61,13 @@ If you've selected **Choose when syncs and scans happen** > **ON**, you'll be ab
#### Scanning for filter values
Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database.
Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a resource-intensive process, particularly if you have a large database.
If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**:
- **Regularly, on a schedule** allows you to run [scan queries](../sync-scan.md#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values now](../sync-scan.md#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date.
- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which rarely have new values added. Use the [Re-scan field values now](../sync-scan.md#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date.
### Periodically refingerprint tables

View File

@@ -48,7 +48,7 @@ The password for the username that you use to connect to the database.
### Use a secure connection (SSL)
Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure.
Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we recommend keeping SSL turned on to keep your data secure.
### Use an SSH tunnel
@@ -77,13 +77,13 @@ If you've selected **Choose when syncs and scans happen** > **ON**, you'll be ab
### Scanning for filter values
Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database.
Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a resource-intensive process, particularly if you have a large database.
If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**:
- **Regularly, on a schedule** allows you to run [scan queries](../sync-scan.md#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values](../sync-scan.md#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date.
- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which rarely have new values added. Use the [Re-scan field values](../sync-scan.md#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date.
### Periodically refingerprint tables

View File

@@ -45,13 +45,13 @@ If you've selected **Choose when syncs and scans happen** > **ON**, you'll be ab
### Scanning for filter values
Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database.
Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a resource-intensive process, particularly if you have a large database.
If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**:
- **Regularly, on a schedule** allows you to run [scan queries](../sync-scan.md#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values](../sync-scan.md#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date.
- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which rarely have new values added. Use the [Re-scan field values](../sync-scan.md#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date.
### Periodically refingerprint tables

View File

@@ -16,7 +16,7 @@ You can download the JDBC driver from [Vertica's JDBC driver downloads page](htt
Head to this page, log in to your account, accept the license agreement, and download `vertica-jdbc-8.0.0-0.jar` (for Vertica DB version 8.0)
or whatever driver version most closely matches the version of Vertica you're running.
It's very important to make sure you use the correct version of the JDBC driver; version
It's important to make sure you use the correct version of the JDBC driver; version
8.0 of the driver won't work with Vertica version 7.2; version 7.2 of the driver won't work with Vertica version 7.1, and so forth. If in doubt,
consult Vertica's documentation to find the correct version of the JDBC driver for your version of Vertica.

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