Compare commits
240 Commits
git-branch
...
document-s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2935aefc64 | ||
|
|
0ecddc9870 | ||
|
|
7ebb0f0000 | ||
|
|
25ce9c5dcf | ||
|
|
14a343de12 | ||
|
|
ec0c2dba8b | ||
|
|
39afe7fff5 | ||
|
|
ab958737a9 | ||
|
|
45a0c85158 | ||
|
|
d2479a5b95 | ||
|
|
6d13f02bf3 | ||
|
|
3b8161ca75 | ||
|
|
93047a3e2f | ||
|
|
2b902a4ce1 | ||
|
|
e03e528f09 | ||
|
|
6f74d26021 | ||
|
|
cb9d5e33e2 | ||
|
|
1ddff04bf6 | ||
|
|
640b530563 | ||
|
|
952a52974c | ||
|
|
915abf29eb | ||
|
|
67eceb653a | ||
|
|
11260e4d72 | ||
|
|
11d3fb22d2 | ||
|
|
2627574bce | ||
|
|
53fcff39ef | ||
|
|
8783c54480 | ||
|
|
9f8331cb63 | ||
|
|
65bbe6429e | ||
|
|
7b367b6c0f | ||
|
|
c328d7f7e0 | ||
|
|
08cec1d1f5 | ||
|
|
5c489b9c95 | ||
|
|
4a079f203a | ||
|
|
1fc9390906 | ||
|
|
3164d5d866 | ||
|
|
71d915b7d0 | ||
|
|
bbe95ee859 | ||
|
|
6542c95758 | ||
|
|
88ef82938d | ||
|
|
9477b72420 | ||
|
|
38bd513835 | ||
|
|
e4c92ff6e2 | ||
|
|
4cbb2297a5 | ||
|
|
54ebe17696 | ||
|
|
41674dd1de | ||
|
|
9595d9493d | ||
|
|
3c3a8dd127 | ||
|
|
4373216910 | ||
|
|
efbfc502f1 | ||
|
|
9bd2243573 | ||
|
|
9c2838341e | ||
|
|
a60e02dd1e | ||
|
|
92e9d6360d | ||
|
|
c6f35e0393 | ||
|
|
89b4bbe920 | ||
|
|
0ab1d4ccb6 | ||
|
|
ea64672746 | ||
|
|
b9a446a933 | ||
|
|
7bd57d1d66 | ||
|
|
dfeafc9489 | ||
|
|
9f0c6d1e2e | ||
|
|
e716d1d253 | ||
|
|
f7c8221468 | ||
|
|
4135955236 | ||
|
|
b2a0c144ba | ||
|
|
9a56a9e96b | ||
|
|
436840eac9 | ||
|
|
ab0bd1b8ff | ||
|
|
c800fb73d0 | ||
|
|
0463d74f76 | ||
|
|
f8924beba5 | ||
|
|
92eb7e62a1 | ||
|
|
6351f1c4ef | ||
|
|
eb8f2d91d0 | ||
|
|
8c5adc5f85 | ||
|
|
a792b1706e | ||
|
|
268352d02b | ||
|
|
acafad1b6a | ||
|
|
4f95b0ebb7 | ||
|
|
92017cfe7c | ||
|
|
9ee59951ae | ||
|
|
403bf4eafd | ||
|
|
010af9dc10 | ||
|
|
8c1e179da7 | ||
|
|
40368f85fb | ||
|
|
978e12c2d6 | ||
|
|
ea4c347006 | ||
|
|
5556654506 | ||
|
|
4ea6c16f19 | ||
|
|
6620040235 | ||
|
|
f809d7747c | ||
|
|
181e8f31d2 | ||
|
|
83bd4ba534 | ||
|
|
f770d21cdf | ||
|
|
f6f6b2d3a9 | ||
|
|
745ab32bde | ||
|
|
6760658aec | ||
|
|
bad6bccac2 | ||
|
|
7448009633 | ||
|
|
7418a137c8 | ||
|
|
40269ca9c0 | ||
|
|
42bee66fba | ||
|
|
76ee0b6f8c | ||
|
|
912aca8811 | ||
|
|
2e9f07ede2 | ||
|
|
9568b9956d | ||
|
|
80867e1335 | ||
|
|
7894f1e45e | ||
|
|
fd4a621603 | ||
|
|
0486d547d3 | ||
|
|
ec7163091a | ||
|
|
287e496a1b | ||
|
|
2ac44861b5 | ||
|
|
47d994182c | ||
|
|
17435642ef | ||
|
|
a917ade608 | ||
|
|
1799892d0b | ||
|
|
4f7c22ed53 | ||
|
|
ba806688b6 | ||
|
|
18898a5fdf | ||
|
|
1ebe336a00 | ||
|
|
36790affcf | ||
|
|
a15154cb84 | ||
|
|
095cae88af | ||
|
|
5314f9f976 | ||
|
|
7189344bfd | ||
|
|
11b74e0e4b | ||
|
|
c5862c278d | ||
|
|
0af4b1c0de | ||
|
|
4cd96fa6a2 | ||
|
|
b47ccb6123 | ||
|
|
5271f4092d | ||
|
|
c06ea7d391 | ||
|
|
e2e2e5fdf3 | ||
|
|
329b903a8b | ||
|
|
82acc79f82 | ||
|
|
240862340a | ||
|
|
7849e0394c | ||
|
|
8fa264cb17 | ||
|
|
ca4744dc08 | ||
|
|
78e9dda8dd | ||
|
|
b36f00cf80 | ||
|
|
3f24ba5687 | ||
|
|
d7dc44feb2 | ||
|
|
0450ba6a67 | ||
|
|
b30ecea5ca | ||
|
|
fc8ca9b602 | ||
|
|
68366d7d37 | ||
|
|
63a94c8788 | ||
|
|
10bd9d68ce | ||
|
|
7221915503 | ||
|
|
4b57f82089 | ||
|
|
b8d2ac9ebc | ||
|
|
00e3499af8 | ||
|
|
d81a470a57 | ||
|
|
c329272406 | ||
|
|
75ec895750 | ||
|
|
60ca78c873 | ||
|
|
45ee83044e | ||
|
|
c43a1c5ca5 | ||
|
|
a7930e7395 | ||
|
|
ad58a25fc6 | ||
|
|
7c5f3f11db | ||
|
|
cff5e706f9 | ||
|
|
f889695914 | ||
|
|
db61438bd8 | ||
|
|
6191275795 | ||
|
|
319cf701dc | ||
|
|
0995bf3526 | ||
|
|
00d8e50082 | ||
|
|
606416ba23 | ||
|
|
86a55c97d9 | ||
|
|
850afa8366 | ||
|
|
0f1eb823d3 | ||
|
|
64448e927d | ||
|
|
f2a3859e32 | ||
|
|
2c85824963 | ||
|
|
27420b5cb9 | ||
|
|
c3e67fd73e | ||
|
|
18ab9af893 | ||
|
|
d3469efb09 | ||
|
|
e00d09cc37 | ||
|
|
ef602ae2d0 | ||
|
|
65c5af5155 | ||
|
|
eb0e823d1e | ||
|
|
c6eeb8e6ba | ||
|
|
af496e167d | ||
|
|
48199ff2f7 | ||
|
|
83ca395ccf | ||
|
|
bd83d0691b | ||
|
|
5b2fa90fdb | ||
|
|
436341ab76 | ||
|
|
aabc1d165f | ||
|
|
a4747ed263 | ||
|
|
cb5f72cad4 | ||
|
|
6c0b2d81ad | ||
|
|
e0f1ecee2d | ||
|
|
6b8124421a | ||
|
|
df462d07d5 | ||
|
|
4f908179ec | ||
|
|
9cbdac4de4 | ||
|
|
0b4b4dfced | ||
|
|
19f4980a7e | ||
|
|
38e9f21dfb | ||
|
|
2775a7e069 | ||
|
|
d92773df06 | ||
|
|
023864e72f | ||
|
|
9c479154a5 | ||
|
|
747781ee29 | ||
|
|
31503487b3 | ||
|
|
9c7f08c2ae | ||
|
|
8693547be1 | ||
|
|
29786d318c | ||
|
|
9307c56d7b | ||
|
|
2583528cb3 | ||
|
|
33edd890a3 | ||
|
|
1e8dbe446b | ||
|
|
ce0e349f21 | ||
|
|
fc5a6469ba | ||
|
|
8523bf0412 | ||
|
|
13d11d33cd | ||
|
|
bb15f10b44 | ||
|
|
f9241dd461 | ||
|
|
a4a135903b | ||
|
|
67d31cea38 | ||
|
|
b7e77ac43c | ||
|
|
89fd0b5c2b | ||
|
|
5339aaa1ca | ||
|
|
809896ee0a | ||
|
|
aae3788116 | ||
|
|
d743daaf20 | ||
|
|
853d9b0cf0 | ||
|
|
4e88f438e9 | ||
|
|
5b6d472c96 | ||
|
|
60373ead57 | ||
|
|
a4a927799d | ||
|
|
8e75cd74f4 | ||
|
|
8252df95f2 | ||
|
|
1cd6a43417 |
@@ -1,7 +1,7 @@
|
||||
;; -*- comment-column: 100; -*-
|
||||
{:config-paths ["macros" "src" "config"]
|
||||
:linters
|
||||
{ ;;
|
||||
{;;
|
||||
;; enabled optional linters (these are disabled by default)
|
||||
;;
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
;; disabled linters
|
||||
;;
|
||||
|
||||
:redundant-ignore {:level :off} ; lots of false positives, see https://github.com/clj-kondo/clj-kondo/issues/2414
|
||||
:redundant-ignore {:level :off} ; lots of false positives, see https://github.com/clj-kondo/clj-kondo/issues/2414
|
||||
:unexpected-recur {:level :off} ; TODO (cam): I think we just need to tell it how to handle MBQL match and we can enable this?
|
||||
|
||||
;;
|
||||
@@ -187,7 +187,7 @@
|
||||
:metabase/disallow-hardcoded-driver-names-in-tests
|
||||
;; don't include `:h2` since that will probably lead to a mountain of tests where we are specifically testing
|
||||
;; middleware or compilation behavior with just H2 since it's the default.
|
||||
{:drivers #{ ;; core drivers
|
||||
{:drivers #{;; core drivers
|
||||
#_:h2
|
||||
:postgres
|
||||
:mysql
|
||||
@@ -215,7 +215,7 @@
|
||||
;; misc config for built-in linters
|
||||
;;
|
||||
|
||||
:invalid-arity {:skip-args [metabase.lib.util.match/match]} ; TODO (cam): can we fix these?
|
||||
:invalid-arity {:skip-args [metabase.lib.util.match/match]} ; TODO (cam): can we fix these?
|
||||
:refer-all {:level :warning, :exclude [clojure.test]}
|
||||
:unused-referred-var {:exclude {compojure.core [GET DELETE POST PUT]}}
|
||||
|
||||
@@ -292,8 +292,6 @@
|
||||
me.flowthing.pp/pprint {:message "Use metabase.util.log instead of me.flowthing.pp/pprint"}
|
||||
medley.core/random-uuid {:message "Use clojure.core/random-uuid instead of medley.core/random-uuid"}
|
||||
metabase.driver/database-supports? {:message "Use metabase.driver.util/supports? instead of metabase.driver/database-supports?"}
|
||||
metabase.lib.convert/->legacy-MBQL {:message "Conversion to legacy MBQL is discouraged, please use Lib to manipulate MBQL queries"}
|
||||
metabase.lib.core/->legacy-MBQL {:message "Conversion to legacy MBQL is discouraged, please use Lib to manipulate MBQL queries"}
|
||||
metabase.lib.equality/find-column-indexes-for-refs {:message "Use lib.equality/closest-matches-in-metadata or lib.equality/find-closest-matches-for-refs instead of lib.equality/find-column-indexes-for-refs"}
|
||||
next.jdbc/active-tx? {:message "Use metabase.app-db.core/in-transaction? to see if we are in a transaction"}
|
||||
toucan2.core/debug {:message "Don't commit code using t2/debug"}
|
||||
@@ -410,15 +408,11 @@
|
||||
clojure.test.check.clojure-test/defspec clojure.test/deftest
|
||||
clojure.test.check.properties/for-all clojure.core/let
|
||||
clojurewerkz.quartzite.jobs/defjob clojure.core/defn
|
||||
com.climate.claypoole/with-shutdown! clojure.core/let
|
||||
instaparse.core/defparser clojure.core/def
|
||||
metabase-enterprise.action-v2.test-util/with-test-tables! clojure.core/let
|
||||
metabase-enterprise.content-translation.routes-test/with-new-secret-key! clojure.core/fn
|
||||
metabase-enterprise.serialization.test-util/with-dbs clojure.core/fn
|
||||
metabase-enterprise.serialization.test-util/with-random-dump-dir clojure.core/let
|
||||
metabase-enterprise.transforms.api-test/with-transform-tags clojure.core/let
|
||||
metabase-enterprise.transforms.api-test/with-worker-runs clojure.core/let
|
||||
metabase-enterprise.transforms.test-util/with-transform-cleanup! clojure.core/let
|
||||
metabase-enterprise.content-translation.routes-test/with-new-secret-key! clojure.core/fn
|
||||
metabase.actions.test-util/with-actions clojure.core/let
|
||||
metabase.api.common/let-404 clojure.core/let
|
||||
metabase.app-db.custom-migrations.util/with-temp-scheduler! clojure.core/fn
|
||||
@@ -518,7 +512,6 @@
|
||||
metabase-enterprise.advanced-permissions.models.permissions.application-permissions-test/with-new-group-and-current-graph hooks.common/with-two-top-level-bindings
|
||||
metabase-enterprise.audit-app.pages-test/with-temp-objects hooks.common/with-one-binding
|
||||
metabase-enterprise.cache.config-test/with-temp-persist-models hooks.common/with-seven-bindings
|
||||
metabase-enterprise.semantic-search.db.connection/with-migrate-tx hooks.common/let-one-with-optional-value
|
||||
metabase-enterprise.serialization.test-util/with-temp-dpc hooks.toucan2.tools.with-temp/with-temp
|
||||
metabase.api.common.internal-test/with-jetty-server hooks.common/with-one-binding
|
||||
metabase.api.macros/defendpoint hooks.metabase.api.macros/defendpoint
|
||||
@@ -650,7 +643,6 @@
|
||||
|
||||
:macroexpand
|
||||
{clojurewerkz.quartzite.jobs/build macros.quartz/build-job
|
||||
clojurewerkz.quartzite.schedule.calendar-interval/build macros.quartz/build-job
|
||||
clojurewerkz.quartzite.schedule.cron/schedule macros.quartz/schedule
|
||||
clojurewerkz.quartzite.schedule.simple/schedule macros.quartz/simple-schedule
|
||||
clojurewerkz.quartzite.triggers/build macros.quartz/build-trigger
|
||||
@@ -725,11 +717,6 @@
|
||||
{:pattern "metabase\\.driver.*$"
|
||||
:name driver-namespaces}
|
||||
;;
|
||||
;; Perf-sensitive namespaces are currently the union of metabase.lib.*, driver namespaces, and QP (without tests).
|
||||
;;
|
||||
{:pattern "^(?!.*-test(?:\\..*)?$)(?!.*test-util)(?!^metabase\\.test.*)^metabase\\.(lib|driver|legacy-mbql|query-processor).*"
|
||||
:name performance-sensitive}
|
||||
;;
|
||||
;; general QP tests are ones that run across multiple drivers. Anything `metabase.query-processor*-test`,
|
||||
;; `metabase.driver.sql*-test` (excluding SQLServer and SQLite), or
|
||||
;; `metabase-enterprise.sandbox.query-processor*-test`
|
||||
@@ -743,13 +730,9 @@
|
||||
{:inline-def {:level :off}
|
||||
:missing-docstring {:level :off}
|
||||
:private-call {:level :off}
|
||||
:discouraged-var {metabase.driver/database-supports? {:level :off}}
|
||||
:metabase/defsetting-must-specify-export {:level :off}
|
||||
:metabase/defsetting-namespace {:level :off}
|
||||
|
||||
:discouraged-var
|
||||
{metabase.driver/database-supports? {:level :off}
|
||||
metabase.lib.convert/->legacy-MBQL {:level :off}
|
||||
metabase.lib.core/->legacy-MBQL {:level :off}}}
|
||||
:metabase/defsetting-namespace {:level :off}}
|
||||
|
||||
:hooks
|
||||
{:analyze-call
|
||||
@@ -762,13 +745,9 @@
|
||||
{:metabase/validate-escaped-single-quotes-in-i18n {:level :warning}
|
||||
:metabase/validate-string-or-str-args-to-i18n {:level :warning}
|
||||
:metabase/discourage-millis-duration {:level :warning}
|
||||
|
||||
:discouraged-var
|
||||
{clojure.core/with-redefs {:message "Don't use with-redefs outside of tests"}
|
||||
clojure.core/eval {:message "Don't use eval outside of tests"}}
|
||||
|
||||
:discouraged-namespace
|
||||
{metabase.query-processor.store {:message "Please do not use the QP Store outside of legacy QP or driver code. Use MBQL 5/Lib or lib.metadata.jvm/applicaton-database-metadata-provider instead."}}}}
|
||||
clojure.core/eval {:message "Don't use eval outside of tests"}}}}
|
||||
|
||||
printable-namespaces
|
||||
{:linters
|
||||
@@ -793,11 +772,9 @@
|
||||
;; eventually we should do this for the whole codebase, but the args are in the opposite order so switching them
|
||||
;; all at once isn't trivial, at least we can stop using it in new code.
|
||||
:discouraged-var
|
||||
{medley.core/map-keys {:message "Use metabase.util.performance/update-keys"}
|
||||
medley.core/map-vals {:message "Use clojure.core/update-vals"}
|
||||
metabase.lib.convert/->legacy-MBQL {:level :off}
|
||||
metabase.lib.core/->legacy-MBQL {:level :off}
|
||||
metabase.test/with-temp {:message "Don't use application database inside Lib code"}}
|
||||
{medley.core/map-keys {:message "Use clojure.core/update-keys"}
|
||||
medley.core/map-vals {:message "Use clojure.core/update-vals"}
|
||||
metabase.test/with-temp {:message "Don't use application database inside MLv2 code"}}
|
||||
|
||||
:discouraged-namespace
|
||||
{metabase.driver {:message "MLv2 code should be independent of driver code/methods"}
|
||||
@@ -819,36 +796,26 @@
|
||||
{:discouraged-var
|
||||
{metabase.driver/database-supports? {:level :off}}}}
|
||||
|
||||
performance-sensitive
|
||||
{:linters
|
||||
{:discouraged-var
|
||||
{clojure.core/update-keys {:message "Use metabase.util.performance/update-keys"}}}}
|
||||
|
||||
qp-and-driver-source-namespaces
|
||||
{:linters
|
||||
{:discouraged-namespace
|
||||
{metabase.query-processor.store {:level :off}
|
||||
metabase.util.malli.schema {:message "Prefer metabase.lib.schema or metabase.legacy-mbql.schema schemas in QP/driver code"}
|
||||
toucan.db {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
|
||||
toucan.models {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
|
||||
toucan.util.test {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
|
||||
toucan2.core {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}}
|
||||
{metabase.util.malli.schema {:message "Prefer metabase.lib.schema or metabase.legacy-mbql.schema schemas in QP/driver code"}
|
||||
toucan.db {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
|
||||
toucan.models {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
|
||||
toucan.util.test {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
|
||||
toucan2.core {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}}
|
||||
|
||||
:discouraged-var
|
||||
{medley.core/map-keys {:message "Use metabase.util.performance/update-keys"}
|
||||
{medley.core/map-keys {:message "Use clojure.core/update-keys"}
|
||||
medley.core/map-vals {:message "Use clojure.core/update-vals"}
|
||||
metabase.app-db.core/query {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
|
||||
metabase.app-db.core/reducible-query {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}
|
||||
metabase.lib.convert/->legacy-MBQL {:level :off}
|
||||
metabase.lib.core/->legacy-MBQL {:level :off}}}}
|
||||
metabase.app-db.core/reducible-query {:message "Don't use application database directly in QP code; use QP Store/metadata provider"}}}}
|
||||
|
||||
general-qp-and-driver-test-namespaces
|
||||
{:linters
|
||||
{:discouraged-var
|
||||
{metabase.test/with-column-remappings {:message "Use lib.tu/remap-metadata-provider instead of with-column-remappings in QP tests"}
|
||||
metabase.test.util/with-column-remappings {:message "Use lib.tu/remap-metadata-provider instead of with-column-remappings in QP tests"}
|
||||
metabase.test/with-temp {:message "Use lib.tu/mock-metadata-provider in QP tests. Exceptions: tests for code that doesn't use MPs or models not supported by MPs"}
|
||||
toucan2.tools.with-temp/with-temp {:message "Use lib.tu/mock-metadata-provider in QP tests. Exceptions: tests for code that doesn't use MPs or models not supported by MPs"}}
|
||||
{metabase.test/with-column-remappings {:message "Use metabase.lib.test-util/remap-metadata-provider instead of with-column-remappings in QP tests"}
|
||||
metabase.test.util/with-column-remappings {:message "Use metabase.lib.test-util/remap-metadata-provider instead of with-column-remappings in QP tests"}}
|
||||
|
||||
:metabase/disallow-hardcoded-driver-names-in-tests
|
||||
{:level :warning}}}}}
|
||||
|
||||
@@ -48,7 +48,6 @@ module.exports = {
|
||||
],
|
||||
curly: [1, "all"],
|
||||
eqeqeq: [1, "smart"],
|
||||
"import/no-duplicates": ["warn", { considerQueryString: true }],
|
||||
"import/no-default-export": 2,
|
||||
"import/no-named-as-default": 0,
|
||||
"import/no-commonjs": 1,
|
||||
@@ -209,7 +208,6 @@ module.exports = {
|
||||
"release/**/*",
|
||||
"rspack.config.js",
|
||||
"rspack.main.config.js",
|
||||
"rspack.embedding-sdk-package.config.js",
|
||||
"rspack.embedding-sdk-bundle.config.js",
|
||||
],
|
||||
rules: {
|
||||
|
||||
48
.github/CODEOWNERS
vendored
@@ -1,9 +1,7 @@
|
||||
# Before changing this file, make sure you have read how we use it:
|
||||
# https://www.notion.so/metabase/Pull-Request-Code-Review-Guide-374f05df889748b69d67af753f9bc9b8?pvs=4#36550c04ceab40b5a8b8bee6264b090c
|
||||
|
||||
enterprise/frontend/src/embedding-sdk-package @metabase/embedding
|
||||
enterprise/frontend/src/embedding-sdk-bundle @metabase/embedding
|
||||
enterprise/frontend/src/embedding-sdk-shared @metabase/embedding
|
||||
enterprise/frontend/src/embedding-sdk @metabase/embedding
|
||||
frontend/src/metabase/embedding-sdk @metabase/embedding
|
||||
frontend/src/metabase/public/containers/PublicOrEmbeddedQuestion @metabase/embedding
|
||||
frontend/src/metabase/public/containers/PublicOrEmbeddedDashboard @metabase/embedding
|
||||
@@ -22,8 +20,8 @@ docs/developers-guide # exclude from tech-writer ownership
|
||||
#
|
||||
|
||||
# modules/drivers @metabase/drivers
|
||||
src/metabase/driver/sql_jdbc/actions.clj @metabase/core-ux-east
|
||||
test/metabase/driver/sql_jdbc/actions_test.clj @metabase/core-ux-east
|
||||
src/metabase/driver/sql_jdbc/actions.clj @metabase/core-workflows
|
||||
test/metabase/driver/sql_jdbc/actions_test.clj @metabase/core-workflows
|
||||
|
||||
# enterprise/backend/src/metabase_enterprise/advanced_config @metabase/core-backend-admin-webapp
|
||||
# enterprise/backend/test/metabase_enterprise/advanced_config @metabase/core-backend-admin-webapp
|
||||
@@ -55,8 +53,8 @@ test/metabase/driver/sql_jdbc/actions_test.clj @metabase/core-ux-east
|
||||
# enterprise/backend/src/metabase_enterprise/core @metabase/devexp
|
||||
# enterprise/backend/test/metabase_enterprise/core @metabase/devexp
|
||||
|
||||
# enterprise/backend/src/metabase_enterprise/dashboard_subscription_filters @metabase/core-ux-east
|
||||
# enterprise/backend/test/metabase_enterprise/dashboard_subscription_filters @metabase/core-ux-east
|
||||
# enterprise/backend/src/metabase_enterprise/dashboard_subscription_filters @metabase/core-workflows
|
||||
# enterprise/backend/test/metabase_enterprise/dashboard_subscription_filters @metabase/core-workflows
|
||||
|
||||
# enterprise/backend/src/metabase_enterprise/enhancements @metabase/core-backend-admin-webapp
|
||||
# enterprise/backend/test/metabase_enterprise/enhancements @metabase/core-backend-admin-webapp
|
||||
@@ -73,11 +71,11 @@ test/metabase/driver/sql_jdbc/actions_test.clj @metabase/core-ux-east
|
||||
# enterprise/backend/src/metabase_enterprise/scim @metabase/core-backend-admin-webapp
|
||||
# enterprise/backend/test/metabase_enterprise/scim @metabase/core-backend-admin-webapp
|
||||
|
||||
# enterprise/backend/src/metabase_enterprise/search ...
|
||||
# enterprise/backend/test/metabase_enterprise/search ...
|
||||
# enterprise/backend/src/metabase_enterprise/search @metabase/core-workflows
|
||||
# enterprise/backend/test/metabase_enterprise/search @metabase/core-workflows
|
||||
|
||||
# enterprise/backend/src/metabase_enterprise/serialization @metabase/core-ux-east
|
||||
# enterprise/backend/test/metabase_enterprise/serialization @metabase/core-ux-east
|
||||
# enterprise/backend/src/metabase_enterprise/serialization @metabase/core-workflows
|
||||
# enterprise/backend/test/metabase_enterprise/serialization @metabase/core-workflows
|
||||
|
||||
# enterprise/backend/src/metabase_enterprise/snippet_collections @metabase/core-backend-admin-webapp
|
||||
# enterprise/backend/test/metabase_enterprise/snippet_collections @metabase/core-backend-admin-webapp
|
||||
@@ -97,8 +95,8 @@ test/metabase/driver/sql_jdbc/actions_test.clj @metabase/core-ux-east
|
||||
# enterprise/backend/src/metabase_enterprise/upload_management @metabase/core-backend-admin-webapp
|
||||
# enterprise/backend/test/metabase_enterprise/upload_management @metabase/core-backend-admin-webapp
|
||||
|
||||
src/metabase/actions @metabase/core-ux-east
|
||||
test/metabase/actions @metabase/core-ux-east
|
||||
src/metabase/actions @metabase/core-backend-ux-west
|
||||
test/metabase/actions @metabase/core-backend-ux-west
|
||||
|
||||
# src/metabase/activity_feed @metabase/core-backend-admin-webapp
|
||||
# test/metabase/activity_feed @metabase/core-backend-admin-webapp
|
||||
@@ -124,11 +122,11 @@ test/metabase/actions @metabase/core-ux-east
|
||||
# src/metabase/cmd @metabase/devexp
|
||||
# test/metabase/cmd @metabase/devexp
|
||||
|
||||
# src/metabase/channel @metabase/core-ux-east
|
||||
# test/metabase/channel @metabase/core-ux-east
|
||||
# src/metabase/channel @metabase/core-workflows
|
||||
# test/metabase/channel @metabase/core-workflows
|
||||
|
||||
# src/metabase/cloud_migration ...
|
||||
# test/metabase/cloud_migration ...
|
||||
# src/metabase/cloud_migration @metabase/core-workflows
|
||||
# test/metabase/cloud_migration @metabase/core-workflows
|
||||
|
||||
# src/metabase/cmd @metabase/devexp
|
||||
# test/metabase/cmd @metabase/devexp
|
||||
@@ -160,8 +158,8 @@ test/metabase/actions @metabase/core-ux-east
|
||||
# src/metabase/indexed_entities @metabase/core-backend-querying
|
||||
# test/metabase/indexed_entities @metabase/core-backend-querying
|
||||
|
||||
# src/metabase/integrations ...
|
||||
# test/metabase/integrations ...
|
||||
# src/metabase/integrations @metabase/core-workflows
|
||||
# test/metabase/integrations @metabase/core-workflows
|
||||
|
||||
# src/metabase/legacy_mbql @metabase/core-backend-querying
|
||||
# test/metabase/legacy_mbql @metabase/core-backend-querying
|
||||
@@ -184,8 +182,8 @@ test/metabase/actions @metabase/core-ux-east
|
||||
# src/metabase/moderation @metabase/core-backend-admin-webapp
|
||||
# test/metabase/moderation @metabase/core-backend-admin-webapp
|
||||
|
||||
# src/metabase/notification @metabase/core-ux-east
|
||||
# test/metabase/notification @metabase/core-ux-east
|
||||
# src/metabase/notification @metabase/core-workflows
|
||||
# test/metabase/notification @metabase/core-workflows
|
||||
|
||||
# src/metabase/permissions @metabase/core-backend-admin-webapp
|
||||
# test/metabase/permissions @metabase/core-backend-admin-webapp
|
||||
@@ -202,8 +200,8 @@ test/metabase/actions @metabase/core-ux-east
|
||||
# src/metabase/public_sharing @metabase/core-backend-admin-webapp
|
||||
# test/metabase/public_sharing @metabase/core-backend-admin-webapp
|
||||
|
||||
# src/metabase/pulse @metabase/core-ux-east
|
||||
# test/metabase/pulse @metabase/core-ux-east
|
||||
# src/metabase/pulse @metabase/core-workflows
|
||||
# test/metabase/pulse @metabase/core-workflows
|
||||
|
||||
# src/metabase/query_analysis @metabase/core-backend-querying
|
||||
# test/metabase/query_analysis @metabase/core-backend-querying
|
||||
@@ -220,8 +218,8 @@ test/metabase/actions @metabase/core-ux-east
|
||||
# src/metabase/sample_data @metabase/core-backend-admin-webapp
|
||||
# test/metabase/sample_data @metabase/core-backend-admin-webapp
|
||||
|
||||
# src/metabase/search ...
|
||||
# test/metabase/search ...
|
||||
# src/metabase/search @metabase/core-workflows
|
||||
# test/metabase/search @metabase/core-workflows
|
||||
|
||||
# src/metabase/segments @metabase/core-backend-querying
|
||||
# test/metabase/segments @metabase/core-backend-querying
|
||||
|
||||
68
.github/actions/fetch-artifact/action.yml
vendored
@@ -5,14 +5,6 @@ inputs:
|
||||
name:
|
||||
description: The name of the artifact to fetch
|
||||
required: true
|
||||
output-name:
|
||||
description: Optional custom name for the output jar file (defaults to metabase.jar)
|
||||
required: false
|
||||
default: "metabase.jar"
|
||||
extract-path:
|
||||
description: Directory path where the jar should be extracted (defaults to current directory)
|
||||
required: false
|
||||
default: "."
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
@@ -33,7 +25,7 @@ runs:
|
||||
});
|
||||
|
||||
if (!artifacts.data?.artifacts?.[0]?.id) {
|
||||
throw new Error(`No artifacts found for ${{ inputs.name }}`);
|
||||
throw new Error(`No artifacts found for ${{ inputs.commit }}`);
|
||||
}
|
||||
|
||||
const artifact_id = artifacts.data.artifacts[0].id;
|
||||
@@ -47,59 +39,25 @@ runs:
|
||||
|
||||
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/mb.zip`, Buffer.from(download.data));
|
||||
|
||||
- name: Extract and rename JAR
|
||||
- name: unzip uberjar artifact
|
||||
shell: bash
|
||||
run: unzip mb.zip
|
||||
- name: Move the Uberjar
|
||||
shell: bash
|
||||
run: | # bash
|
||||
OUTPUT_NAME="${{ inputs.output-name }}"
|
||||
EXTRACT_PATH="${{ inputs.extract-path }}"
|
||||
|
||||
# Create a temporary directory for extraction to avoid conflicts
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
|
||||
# Extract to temporary directory
|
||||
unzip mb.zip -d "$TEMP_DIR"
|
||||
|
||||
# Create target directory
|
||||
mkdir -p "$EXTRACT_PATH"
|
||||
|
||||
# Find the jar and move all files from its directory
|
||||
if [ -e "$TEMP_DIR/metabase.jar" ]; then
|
||||
# Move all files to extract path
|
||||
mv "$TEMP_DIR"/* "$EXTRACT_PATH/" 2>/dev/null || true
|
||||
# Rename the jar to custom name if different
|
||||
if [ "$OUTPUT_NAME" != "metabase.jar" ]; then
|
||||
mv "$EXTRACT_PATH/metabase.jar" "$EXTRACT_PATH/$OUTPUT_NAME"
|
||||
fi
|
||||
elif [ -e "$TEMP_DIR/target/uberjar/metabase.jar" ]; then
|
||||
# Move all files from uberjar directory to extract path
|
||||
mv "$TEMP_DIR/target/uberjar"/* "$EXTRACT_PATH/" 2>/dev/null || true
|
||||
# Rename the jar to custom name if different
|
||||
if [ "$OUTPUT_NAME" != "metabase.jar" ]; then
|
||||
mv "$EXTRACT_PATH/metabase.jar" "$EXTRACT_PATH/$OUTPUT_NAME"
|
||||
fi
|
||||
if [ -e "metabase.jar" ]; then
|
||||
echo "metabase.jar is already in the right place"
|
||||
elif [ -e "target/uberjar/metabase.jar" ]; then
|
||||
echo "moving metabase.jar to current directory"
|
||||
mv target/uberjar/metabase.jar metabase.jar
|
||||
else
|
||||
echo "Could not find metabase.jar in extracted files"
|
||||
echo "Could not find the metabase.jar file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up temporary directory
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
# Set the JAR_PATH environment variable
|
||||
if [ "$EXTRACT_PATH" == "." ]; then
|
||||
echo "JAR_PATH=$OUTPUT_NAME" >> $GITHUB_ENV
|
||||
else
|
||||
echo "JAR_PATH=$EXTRACT_PATH/$OUTPUT_NAME" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Verify that this is a valid JAR file
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Verifying JAR at: $JAR_PATH"
|
||||
file --mime-type "$JAR_PATH"
|
||||
|
||||
run: file --mime-type ./metabase.jar
|
||||
- name: Reveal its version.properties
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Extracting version.properties from: $JAR_PATH"
|
||||
jar xf "$JAR_PATH" version.properties && cat version.properties
|
||||
run: jar xf metabase.jar version.properties && cat version.properties
|
||||
|
||||
74
.github/actions/get-docker-info/action.yml
vendored
@@ -1,74 +0,0 @@
|
||||
name: Get Docker Info
|
||||
description: Determines Docker repository and tag based on branch and edition
|
||||
|
||||
inputs:
|
||||
branch:
|
||||
description: Branch name (defaults to current branch)
|
||||
required: false
|
||||
default: ${{ github.head_ref || github.ref_name }}
|
||||
edition:
|
||||
description: Edition (ee or oss)
|
||||
required: false
|
||||
default: ee
|
||||
owner:
|
||||
description: Repository owner (defaults to current repo owner)
|
||||
required: false
|
||||
default: ${{ github.repository_owner }}
|
||||
|
||||
outputs:
|
||||
repo:
|
||||
description: Docker repository name
|
||||
value: ${{ steps.docker-info.outputs.repo }}
|
||||
tag:
|
||||
description: Docker tag
|
||||
value: ${{ steps.docker-info.outputs.tag }}
|
||||
full_image:
|
||||
description: Full Docker image name (repo:tag)
|
||||
value: ${{ steps.docker-info.outputs.full_image }}
|
||||
editions:
|
||||
description: JSON array of editions to build
|
||||
value: ${{ steps.docker-info.outputs.editions }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Determine Docker info
|
||||
id: docker-info
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: | # js
|
||||
const branch = '${{ inputs.branch }}';
|
||||
const edition = '${{ inputs.edition }}';
|
||||
const owner = '${{ inputs.owner }}';
|
||||
|
||||
console.log(`Determining Docker info for branch: ${branch}, edition: ${edition}`);
|
||||
|
||||
let repo, tag, editions;
|
||||
|
||||
if (branch === 'master') {
|
||||
// Master builds both editions with specific repos
|
||||
editions = ['ee', 'oss'];
|
||||
tag = 'latest';
|
||||
|
||||
if (edition === 'ee') {
|
||||
repo = `${owner}/metabase-enterprise-head`;
|
||||
} else {
|
||||
repo = `${owner}/metabase-head`;
|
||||
}
|
||||
} else {
|
||||
// All other branches only build EE to metabase-dev
|
||||
editions = ['ee'];
|
||||
tag = branch.replaceAll('/', '-'); // slashes make docker sad
|
||||
repo = `${owner}/metabase-dev`;
|
||||
}
|
||||
|
||||
const fullImage = `${repo}:${tag}`;
|
||||
|
||||
// Set outputs
|
||||
core.setOutput('repo', repo);
|
||||
core.setOutput('tag', tag);
|
||||
core.setOutput('full_image', fullImage);
|
||||
core.setOutput('editions', JSON.stringify(editions));
|
||||
|
||||
console.log(`Docker image: ${fullImage}`);
|
||||
console.log(`Editions: ${JSON.stringify(editions)}`);
|
||||
10
.github/file-paths.yaml
vendored
@@ -30,7 +30,6 @@ frontend_configs: &frontend_configs
|
||||
- "postcss.config.js"
|
||||
- "rspack.config.js"
|
||||
- "rspack.main.config.js"
|
||||
- "rspack.embedding-sdk-package.config.js"
|
||||
- "rspack.embedding-sdk-bundle.config.js"
|
||||
- "rspack.static-viz.config.js"
|
||||
- ".nvmrc"
|
||||
@@ -138,17 +137,16 @@ e2e_embedding_sdk_compatibility:
|
||||
- "e2e/runner/embedding-sdk/**"
|
||||
- "e2e/test-host-app/**/*.cy.*.{js,ts}"
|
||||
|
||||
snowplow: &snowplow
|
||||
- ".github/workflows/snowplow.yml"
|
||||
- "snowplow/**"
|
||||
|
||||
e2e_all:
|
||||
- *default
|
||||
- *e2e_ci
|
||||
- *sources
|
||||
- *e2e_specs
|
||||
- "e2e/**"
|
||||
- *snowplow
|
||||
|
||||
snowplow:
|
||||
- ".github/workflows/snowplow.yml"
|
||||
- "snowplow/**"
|
||||
|
||||
documentation:
|
||||
- "docs/**"
|
||||
|
||||
387
.github/workflows/claude-code-bug-fix.yml
vendored
@@ -1,387 +0,0 @@
|
||||
name: "Claude Code Bug Fix"
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- labeled
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
issue_number:
|
||||
description: "Issue number to fix"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
check-employee-and-issue:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
permissions:
|
||||
contents: read
|
||||
issues: read
|
||||
if: |
|
||||
(github.event_name == 'issues' && github.event.label.name == 'Claude Bug Fix' && github.event.issue.state == 'open') ||
|
||||
(github.event_name == 'workflow_dispatch')
|
||||
outputs:
|
||||
is_employee: ${{ steps.check_employee.outputs.is_employee }}
|
||||
issue_number: ${{ steps.get_issue.outputs.issue_number }}
|
||||
issue_data: ${{ steps.get_issue.outputs.issue_data }}
|
||||
steps:
|
||||
- name: Generate GitHub App Token
|
||||
uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ secrets.METABASE_BOT_APP_ID }}
|
||||
private-key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Get issue data
|
||||
id: get_issue
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
let issueNumber, issueData;
|
||||
|
||||
if (context.eventName === 'issues') {
|
||||
// Original issue label event
|
||||
issueNumber = context.payload.issue.number;
|
||||
issueData = context.payload.issue;
|
||||
} else if (context.eventName === 'workflow_dispatch') {
|
||||
// Manual trigger with issue number input
|
||||
issueNumber = parseInt('${{ github.event.inputs.issue_number }}');
|
||||
const { data } = await github.rest.issues.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issueNumber
|
||||
});
|
||||
issueData = data;
|
||||
}
|
||||
|
||||
core.setOutput('issue_number', issueNumber);
|
||||
core.setOutput('issue_data', JSON.stringify(issueData));
|
||||
|
||||
console.log(`Issue #${issueNumber}: ${issueData.title}`);
|
||||
console.log(`Issue author: ${issueData.user.login}`);
|
||||
|
||||
- name: Check if issue creator is a Metabase employee
|
||||
id: check_employee
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
ISSUE_DATA: ${{ steps.get_issue.outputs.issue_data }}
|
||||
with:
|
||||
github-token: ${{ steps.app-token.outputs.token }}
|
||||
script: |
|
||||
const issueData = JSON.parse(process.env.ISSUE_DATA);
|
||||
const issueAuthor = issueData.user.login;
|
||||
|
||||
try {
|
||||
// Check if user is a member of the metabase organization (including private members)
|
||||
const { data: membership } = await github.rest.orgs.getMembershipForUser({
|
||||
org: 'metabase',
|
||||
username: issueAuthor
|
||||
});
|
||||
|
||||
if (membership.state === 'active') {
|
||||
console.log(`User ${issueAuthor} is an active member of the Metabase organization. Proceeding with bug fix automation.`);
|
||||
core.setOutput('is_employee', 'true');
|
||||
} else {
|
||||
console.log(`User ${issueAuthor} is not an active member of the Metabase organization. Skipping bug fix automation.`);
|
||||
core.setOutput('is_employee', 'false');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
console.log(`User ${issueAuthor} is not a member of the Metabase organization. Skipping bug fix automation.`);
|
||||
} else {
|
||||
console.error('Error checking organization membership:', error);
|
||||
}
|
||||
core.setOutput('is_employee', 'false');
|
||||
}
|
||||
|
||||
auto-fix-bug:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
needs: check-employee-and-issue
|
||||
if: needs.check-employee-and-issue.outputs.is_employee == 'true'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up git configuration
|
||||
run: |
|
||||
git config --global user.name "Claude Code[bot]"
|
||||
git config --global user.email "noreply@anthropic.com"
|
||||
|
||||
- name: Prepare dynamic issue info
|
||||
id: prepare_issue_info
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
ISSUE_DATA: ${{ needs.check-employee-and-issue.outputs.issue_data }}
|
||||
with:
|
||||
script: |
|
||||
const issueData = JSON.parse(process.env.ISSUE_DATA);
|
||||
const issueNumber = '${{ needs.check-employee-and-issue.outputs.issue_number }}';
|
||||
|
||||
// Convert issue title to kebab case
|
||||
const issueTitle = issueData.title || 'untitled';
|
||||
const kebabTitle = issueTitle
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '')
|
||||
.replace(/-+/g, '-')
|
||||
.substring(0, 50); // Limit length
|
||||
|
||||
// Create base branch name
|
||||
const baseBranchName = `claude-fix/issue-${issueNumber}-${kebabTitle}`;
|
||||
core.exportVariable('BASE_BRANCH_NAME', baseBranchName);
|
||||
|
||||
// Export issue info for the prompt
|
||||
core.exportVariable('ISSUE_NUMBER', issueNumber);
|
||||
core.exportVariable('ISSUE_TITLE', issueData.title);
|
||||
core.exportVariable('ISSUE_AUTHOR', issueData.user.login);
|
||||
core.exportVariable('ISSUE_CREATED', issueData.created_at);
|
||||
core.exportVariable('ISSUE_BODY', issueData.body || 'No description provided');
|
||||
|
||||
- name: Determine branch strategy
|
||||
run: |
|
||||
# Use the base branch name (no counters)
|
||||
BRANCH_NAME="${{ env.BASE_BRANCH_NAME }}"
|
||||
|
||||
# Check if this exact branch already exists
|
||||
if git branch -r --list "origin/${BRANCH_NAME}" | grep -q .; then
|
||||
echo "Branch already exists: $BRANCH_NAME"
|
||||
echo "Will push to existing branch and skip PR creation"
|
||||
echo "BRANCH_EXISTS=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Creating new branch: $BRANCH_NAME"
|
||||
echo "Will create new PR"
|
||||
echo "BRANCH_EXISTS=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
# Export the branch name
|
||||
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
|
||||
|
||||
- name: Prepare bug fix prompt
|
||||
id: prepare_prompt
|
||||
run: |
|
||||
# Prepare the prompt for Claude
|
||||
cat << 'EOF' >> $GITHUB_ENV
|
||||
BUG_FIX_PROMPT<<PROMPT_END
|
||||
You are helping to automatically fix a bug reported in GitHub issue #${{ env.ISSUE_NUMBER }}.
|
||||
|
||||
## Bug Report Details
|
||||
**Title:** ${{ env.ISSUE_TITLE }}
|
||||
**Reporter:** ${{ env.ISSUE_AUTHOR }}
|
||||
**Created:** ${{ env.ISSUE_CREATED }}
|
||||
|
||||
**Description:**
|
||||
${{ env.ISSUE_BODY }}
|
||||
|
||||
## Instructions
|
||||
1. **Analyze the bug report** - Understand what the issue is describing
|
||||
2. **Search the codebase** - Use Grep and Glob tools to find relevant files
|
||||
3. **Implement a fix** - Follow existing code patterns and conventions
|
||||
4. **Test the fix** - Run appropriate tests using the commands in CLAUDE.md:
|
||||
- JavaScript/TypeScript: `yarn test-unit path/to/file.unit.spec.js`
|
||||
- Clojure: `clojure -X:dev:test :only namespace/test-name`
|
||||
- Lint: `yarn lint-eslint-pure` for JS/TS, `./bin/mage kondo <file>` for Clojure
|
||||
5. **Verify the fix** - Ensure tests pass and code follows conventions
|
||||
|
||||
## Important Guidelines
|
||||
- Follow the development patterns in CLAUDE.md
|
||||
- Write failing tests first, then fix them
|
||||
- Work in small, testable increments
|
||||
- Don't commit changes - leave that for the workflow
|
||||
- IMPORTANT: Focus only on fixing the reported bug, don't make unrelated changes
|
||||
|
||||
## Scratchpad Directory
|
||||
A `.claude-scratchpad/` directory has been created for your temporary files:
|
||||
- Use this directory for ALL temporary verification files. However, prefer using production test files rather than adhoc ones.
|
||||
- Only modify actual production code in the main repository directories
|
||||
- The scratchpad will be cleaned up automatically - nothing from it will be committed
|
||||
|
||||
## If You Cannot Fix The Bug
|
||||
If you determine that you cannot create a definitive fix, create a file called `FAILED_FIX_ANALYSIS.md` with:
|
||||
1. **Why No Fix** - Specific reason why you couldn't implement a fix
|
||||
2. **Tool Limitations** - If you needed additional tools/access that weren't available
|
||||
|
||||
Start by understanding the bug and then systematically work toward a solution.
|
||||
PROMPT_END
|
||||
EOF
|
||||
|
||||
- name: Create scratchpad directory for Claude
|
||||
run: |
|
||||
# Create a scratchpad directory for Claude to use for temporary files
|
||||
mkdir -p .claude-scratchpad
|
||||
echo "Scratchpad directory created for Claude's temporary verification files"
|
||||
|
||||
- name: Generate GitHub App Token for Claude
|
||||
uses: actions/create-github-app-token@v1
|
||||
id: claude-app-token
|
||||
with:
|
||||
app-id: ${{ secrets.METABASE_BOT_APP_ID }}
|
||||
private-key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Generate Bug Fix with Claude Code
|
||||
uses: anthropics/claude-code-action@beta
|
||||
with:
|
||||
mode: agent
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
github_token: ${{ steps.claude-app-token.outputs.token }}
|
||||
direct_prompt: ${{ env.BUG_FIX_PROMPT }}
|
||||
timeout_minutes: "25"
|
||||
allowed_tools: "Bash(yarn test-unit*),Bash(yarn lint-eslint-pure),Bash(./bin/mage*),Bash(clojure*),Bash(find*),Bash(ls*),Bash(grep*),Write,Read,Glob,Grep,Edit,MultiEdit"
|
||||
disallowed_tools: "Bash(git commit*),Bash(git push*),Bash(gh*)"
|
||||
|
||||
- name: Clean up scratchpad directory
|
||||
run: |
|
||||
# Remove the scratchpad directory so its contents don't get committed
|
||||
rm -rf .claude-scratchpad/
|
||||
# Remove output file generated by Claude Code action
|
||||
rm -f output.txt
|
||||
echo "Scratchpad directory and action output files cleaned up"
|
||||
|
||||
- name: Check for changes and analysis
|
||||
id: check_changes
|
||||
run: |
|
||||
# Check if Claude created an analysis file first and store its content
|
||||
if [ -f "FAILED_FIX_ANALYSIS.md" ]; then
|
||||
echo "has_analysis=true" >> $GITHUB_OUTPUT
|
||||
echo "Analysis file found"
|
||||
# Store analysis content in a GitHub output (base64 encoded to handle multiline)
|
||||
ANALYSIS_CONTENT=$(base64 -w 0 FAILED_FIX_ANALYSIS.md)
|
||||
echo "analysis_content=$ANALYSIS_CONTENT" >> $GITHUB_OUTPUT
|
||||
# Remove analysis file so it doesn't count as a code change
|
||||
rm -f FAILED_FIX_ANALYSIS.md
|
||||
else
|
||||
echo "has_analysis=false" >> $GITHUB_OUTPUT
|
||||
echo "No analysis file found"
|
||||
fi
|
||||
|
||||
# Now check for actual code changes (excluding analysis file)
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||
echo "Changes detected:"
|
||||
git status --short
|
||||
else
|
||||
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||||
echo "No changes made by Claude."
|
||||
fi
|
||||
|
||||
- name: Get issue team labels and prepare reviewers
|
||||
if: steps.check_changes.outputs.has_changes == 'true'
|
||||
id: prepare_reviewers
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
ISSUE_DATA: ${{ needs.check-employee-and-issue.outputs.issue_data }}
|
||||
with:
|
||||
script: |
|
||||
// Get existing team labels from the issue
|
||||
const issueData = JSON.parse(process.env.ISSUE_DATA);
|
||||
const issueLabels = issueData.labels.map(label => label.name);
|
||||
const teamLabels = issueLabels.filter(label => label.startsWith('.Team/'));
|
||||
|
||||
console.log('Issue labels:', issueLabels);
|
||||
console.log('Team labels found:', teamLabels);
|
||||
|
||||
// Add issue creator as reviewer
|
||||
const issueCreator = issueData.user.login;
|
||||
|
||||
core.setOutput('team_labels', teamLabels.join(','));
|
||||
core.setOutput('reviewers', issueCreator);
|
||||
|
||||
console.log('Reviewer:', issueCreator);
|
||||
|
||||
- name: Create Pull Request
|
||||
if: steps.check_changes.outputs.has_changes == 'true'
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ env.BRANCH_NAME }}
|
||||
base: master
|
||||
commit-message: |
|
||||
Fix: ${{ env.ISSUE_TITLE }}
|
||||
|
||||
Fixes #${{ env.ISSUE_NUMBER }}
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.ai/code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
committer: "Claude Code[bot] <noreply@anthropic.com>"
|
||||
author: "Claude Code[bot] <noreply@anthropic.com>"
|
||||
title: "Fix: ${{ env.ISSUE_TITLE }}"
|
||||
body: |
|
||||
This PR automatically fixes the bug reported in #${{ env.ISSUE_NUMBER }}.
|
||||
|
||||
## Bug Report
|
||||
**Original Issue:** #${{ env.ISSUE_NUMBER }}
|
||||
**Reporter:** @${{ env.ISSUE_AUTHOR }}
|
||||
**Issue Title:** ${{ env.ISSUE_TITLE }}
|
||||
|
||||
## Automated Fix
|
||||
🤖 This fix was generated automatically by Claude Code based on the issue description.
|
||||
|
||||
**Please review carefully:**
|
||||
- [ ] The fix addresses the reported issue
|
||||
- [ ] Tests pass and code follows conventions
|
||||
- [ ] No unrelated changes were introduced
|
||||
- [ ] The solution is appropriate and maintainable
|
||||
|
||||
## Next Steps
|
||||
- Review the changes and test thoroughly
|
||||
- If the fix looks good, approve and merge
|
||||
- If issues are found, either fix them or close this PR
|
||||
|
||||
---
|
||||
Closes #${{ env.ISSUE_NUMBER }}
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.ai/code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
labels: |
|
||||
${{ steps.prepare_reviewers.outputs.team_labels }}
|
||||
automated-fix
|
||||
ci skip
|
||||
reviewers: ${{ steps.prepare_reviewers.outputs.reviewers }}
|
||||
|
||||
- name: Log existing branch update
|
||||
if: steps.check_changes.outputs.has_changes == 'true' && env.BRANCH_EXISTS == 'true'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
console.log('🔄 Updated existing branch: ${{ env.BRANCH_NAME }}');
|
||||
console.log('The changes have been pushed to the existing PR for this issue.');
|
||||
|
||||
- name: Log analysis for no changes
|
||||
if: steps.check_changes.outputs.has_changes == 'false'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
console.log('🤖 No code changes were made by Claude.');
|
||||
|
||||
// Check if Claude provided a detailed analysis
|
||||
if ('${{ steps.check_changes.outputs.has_analysis }}' === 'true') {
|
||||
try {
|
||||
// Decode the base64-encoded analysis content
|
||||
const analysisBase64 = '${{ steps.check_changes.outputs.analysis_content }}';
|
||||
const analysisContent = Buffer.from(analysisBase64, 'base64').toString('utf8');
|
||||
console.log('📋 Claude provided detailed analysis:');
|
||||
console.log('='.repeat(50));
|
||||
console.log(analysisContent);
|
||||
console.log('='.repeat(50));
|
||||
} catch (error) {
|
||||
console.log('❌ Could not decode analysis content:', error);
|
||||
}
|
||||
} else {
|
||||
console.log('ℹ️ No detailed analysis file was created by Claude.');
|
||||
console.log('This could be because:');
|
||||
console.log('- The issue requires more context or clarification');
|
||||
console.log('- The fix is complex and requires human judgment');
|
||||
console.log('- The issue is not a straightforward code bug');
|
||||
console.log('- Claude couldn\'t locate the relevant code to modify');
|
||||
}
|
||||
126
.github/workflows/containerize-uberjar.yml
vendored
@@ -1,126 +0,0 @@
|
||||
name: Containerize Uberjar
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
get-container-info:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
name: Get container info
|
||||
outputs:
|
||||
editions: ${{ steps.ee-info.outputs.editions }}
|
||||
ee: ${{ toJson(fromJson(steps.build-matrix.outputs.result).ee) }}
|
||||
oss: ${{ toJson(fromJson(steps.build-matrix.outputs.result).oss) }}
|
||||
steps:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v4
|
||||
- name: Get EE Docker info
|
||||
id: ee-info
|
||||
uses: ./.github/actions/get-docker-info
|
||||
with:
|
||||
edition: ee
|
||||
- name: Get OSS Docker info
|
||||
id: oss-info
|
||||
uses: ./.github/actions/get-docker-info
|
||||
with:
|
||||
edition: oss
|
||||
- name: Build matrix info
|
||||
id: build-matrix
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: | # js
|
||||
const editions = JSON.parse('${{ steps.ee-info.outputs.editions }}');
|
||||
const result = {
|
||||
editions: editions,
|
||||
ee: {
|
||||
repo: '${{ steps.ee-info.outputs.repo }}',
|
||||
tag: '${{ steps.ee-info.outputs.tag }}'
|
||||
},
|
||||
oss: {
|
||||
repo: '${{ steps.oss-info.outputs.repo }}',
|
||||
tag: '${{ steps.oss-info.outputs.tag }}'
|
||||
}
|
||||
};
|
||||
console.log('Build matrix:', result);
|
||||
return result;
|
||||
|
||||
containerize:
|
||||
needs: [get-container-info]
|
||||
if: needs.get-container-info.result == 'success'
|
||||
strategy:
|
||||
matrix:
|
||||
edition: ${{ fromJson(needs.get-container-info.outputs.editions) }}
|
||||
uses: ./.github/workflows/containerize-jar.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
artifact-name: metabase-${{ matrix.edition }}-${{ github.event.inputs.commit || github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
commit: ${{ github.event.inputs.commit || github.sha }}
|
||||
repo: ${{ fromJson(needs.get-container-info.outputs[matrix.edition]).repo }}
|
||||
tag: ${{ fromJson(needs.get-container-info.outputs[matrix.edition]).tag }}
|
||||
release: "false"
|
||||
build-args: |
|
||||
GIT_COMMIT_SHA=${{ github.event.inputs.commit || github.sha }}
|
||||
|
||||
run-trivy:
|
||||
needs: [get-container-info, containerize]
|
||||
strategy:
|
||||
matrix:
|
||||
edition: ${{ fromJson(needs.get-container-info.outputs.editions) }}
|
||||
runs-on: ubuntu-22.04
|
||||
name: Run Trivy vulnerability scanner
|
||||
steps:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit || github.sha }}
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@0.29.0
|
||||
env:
|
||||
TRIVY_OFFLINE_SCAN: true
|
||||
repo: ${{ fromJson(needs.get-container-info.outputs[matrix.edition]).repo }}
|
||||
tag: ${{ fromJson(needs.get-container-info.outputs[matrix.edition]).tag }}
|
||||
with:
|
||||
image-ref: docker.io/${{ env.repo }}:${{ env.tag }}
|
||||
format: sarif
|
||||
output: trivy-results.sarif
|
||||
version: "v0.57.1"
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: "trivy-results.sarif"
|
||||
|
||||
post-comment:
|
||||
needs: [get-container-info, containerize]
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-22.04
|
||||
name: Post PR comment
|
||||
steps:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v4
|
||||
- name: Get Docker info for comment
|
||||
id: docker-info
|
||||
uses: ./.github/actions/get-docker-info
|
||||
with:
|
||||
branch: ${{ github.head_ref || github.ref_name }}
|
||||
edition: ee
|
||||
|
||||
- name: Post PR comment
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
header: docker-build-status
|
||||
message: |
|
||||
✅ Docker build completed for commit ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
The uberjar has been built and containerized successfully.
|
||||
|
||||
**Branch:** `${{ github.head_ref || github.ref_name }}`
|
||||
**Docker Image:** `${{ steps.docker-info.outputs.full_image }}`
|
||||
**Docker Hub:** [View on Docker Hub](https://hub.docker.com/r/${{ steps.docker-info.outputs.repo }}/tags?name=${{ steps.docker-info.outputs.tag }})
|
||||
**Triggered by:** @${{ github.actor }}
|
||||
|
||||
Pull the image:
|
||||
```bash
|
||||
docker pull ${{ steps.docker-info.outputs.full_image }}
|
||||
```
|
||||
@@ -5,7 +5,7 @@ on:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- enterprise/frontend/src/embedding-sdk-bundle/**
|
||||
- enterprise/frontend/src/embedding-sdk/**
|
||||
|
||||
jobs:
|
||||
pr-title-reminder:
|
||||
|
||||
182
.github/workflows/docs-generate-base.yml
vendored
@@ -1,182 +0,0 @@
|
||||
# .github/workflows/reusable-doc-update.yml
|
||||
name: Reusable - Update Documentation
|
||||
|
||||
# This workflow is designed to be called by other workflows.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
target_branch:
|
||||
description: "The branch to check out and create a PR against"
|
||||
required: true
|
||||
type: string
|
||||
m2_cache_key_suffix:
|
||||
description: "A unique suffix for the Maven cache key"
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
automation_token:
|
||||
description: "A token with permissions to create branches and PRs"
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update-docs:
|
||||
name: Update documentation for ${{ inputs.target_branch }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.automation_token }}
|
||||
ref: ${{ inputs.target_branch }}
|
||||
|
||||
- name: Prepare backend environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: "auto-update-docs-${{ inputs.m2_cache_key_suffix }}"
|
||||
|
||||
- name: Generate environment variables documentation
|
||||
id: generate_env_docs
|
||||
run: |
|
||||
set -e # Exit on any error
|
||||
# Ensure we're on the target branch for documentation generation
|
||||
git checkout ${{ inputs.target_branch }}
|
||||
echo "Generating environment variables documentation from branch: ${{ inputs.target_branch }}"
|
||||
clojure -M:ee:doc environment-variables-documentation
|
||||
continue-on-error: false
|
||||
|
||||
- name: Generate config template documentation
|
||||
id: generate_config_docs
|
||||
run: |
|
||||
set -e # Exit on any error
|
||||
echo "Generating config template documentation..."
|
||||
clojure -M:ee:doc config-template
|
||||
continue-on-error: false
|
||||
|
||||
- name: Generate API documentation
|
||||
id: generate_api_docs
|
||||
run: |
|
||||
set -e # Exit on any error
|
||||
echo "Generating API documentation..."
|
||||
clojure -M:ee:doc api-documentation
|
||||
continue-on-error: false
|
||||
|
||||
- name: Check for changes
|
||||
id: check_changes
|
||||
run: |
|
||||
if git diff --quiet docs/; then
|
||||
echo "changes=false" >> $GITHUB_OUTPUT
|
||||
echo "No changes detected in docs directory"
|
||||
else
|
||||
echo "changes=true" >> $GITHUB_OUTPUT
|
||||
echo "Changes detected in docs directory"
|
||||
fi
|
||||
|
||||
- name: Create branch and commit changes
|
||||
id: commit_and_push
|
||||
if: steps.check_changes.outputs.changes == 'true'
|
||||
run: |
|
||||
git config user.name github-actions
|
||||
git config user.email github-actions@github.com
|
||||
|
||||
BRANCH_NAME="docs/auto-update-${{ inputs.target_branch }}-$(date +%Y-%m-%d-%H%M%S)"
|
||||
echo "Creating branch: $BRANCH_NAME"
|
||||
|
||||
# Create and switch to new branch from current target branch
|
||||
git checkout -b "$BRANCH_NAME"
|
||||
|
||||
# Stage and commit changes
|
||||
git add docs/
|
||||
if git diff --cached --quiet; then
|
||||
echo "No changes to commit"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git commit -m "Update generated docs (${{ inputs.target_branch }})" --no-verify
|
||||
git push -u origin "$BRANCH_NAME"
|
||||
|
||||
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
|
||||
echo "Successfully created and pushed branch"
|
||||
|
||||
- name: Create pull request
|
||||
id: create_pr
|
||||
if: steps.check_changes.outputs.changes == 'true'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.automation_token }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
run: |
|
||||
CHANGES_SUMMARY=$(git diff --name-only HEAD~1 docs/ 2>/dev/null | head -10 | sed 's/^/- /' || echo "- No specific files detected")
|
||||
TOTAL_CHANGES=$(git diff --name-only HEAD~1 docs/ 2>/dev/null | wc -l || echo "0")
|
||||
BRANCH_NAME="${{ steps.commit_and_push.outputs.branch_name }}"
|
||||
|
||||
echo "Creating PR with branch: $BRANCH_NAME"
|
||||
echo "Changes detected: $TOTAL_CHANGES files"
|
||||
|
||||
for i in {1..3}; do
|
||||
echo "Attempt $i of 3..."
|
||||
if gh pr create \
|
||||
--base "${{ inputs.target_branch }}" \
|
||||
--head "$BRANCH_NAME" \
|
||||
--title "Auto-update documentation for ${{ inputs.target_branch }}" \
|
||||
--body "This PR contains automatically generated documentation updates.
|
||||
|
||||
## Changes detected
|
||||
The following documentation files were updated:
|
||||
$CHANGES_SUMMARY
|
||||
$([ "$TOTAL_CHANGES" -gt 10 ] && echo "- ... and $((TOTAL_CHANGES - 10)) more files")
|
||||
|
||||
## Generation commands
|
||||
Documentation was generated using:
|
||||
- \`clojure -M:ee:doc environment-variables-documentation\`
|
||||
- \`clojure -M:ee:doc config-template\`
|
||||
- \`clojure -M:ee:doc api-documentation\`
|
||||
|
||||
Please review the changes and merge if they look correct." \
|
||||
--label "Type:Documentation" \
|
||||
--label "no-backport" \
|
||||
--reviewer "metabase/tech-writers"; then
|
||||
echo "PR created successfully on attempt $i"
|
||||
break
|
||||
else
|
||||
echo "PR creation failed on attempt $i"
|
||||
if [ $i -eq 3 ]; then
|
||||
echo "All attempts failed. Exiting with error."
|
||||
exit 1
|
||||
fi
|
||||
echo "Waiting 10 seconds before retry..."
|
||||
sleep 10
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Skip PR creation
|
||||
if: steps.check_changes.outputs.changes == 'false'
|
||||
run: |
|
||||
echo "No documentation changes detected, skipping PR creation"
|
||||
|
||||
- name: Workflow summary
|
||||
if: always()
|
||||
run: |
|
||||
if [ "${{ steps.check_changes.outputs.changes }}" == "true" ]; then
|
||||
if [ "${{ steps.commit_and_push.outcome }}" == "success" ]; then
|
||||
if [ "${{ steps.create_pr.outcome }}" == "success" ]; then
|
||||
echo "## ✅ Documentation Updated Successfully" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Branch: \`${{ steps.commit_and_push.outputs.branch_name }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- PR created targeting **${{ inputs.target_branch }}**" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "## ⚠️ Branch Created but PR Failed" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Branch: \`${{ steps.commit_and_push.outputs.branch_name }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Manual PR creation required" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
else
|
||||
echo "## ❌ Failed to Create Branch" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Check workflow logs for details" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
else
|
||||
echo "## ℹ️ No Changes Detected" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Documentation is up to date on **${{ inputs.target_branch }}**" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
16
.github/workflows/docs-master-generate.yml
vendored
@@ -1,16 +0,0 @@
|
||||
name: Auto-update documentation (master)
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 1 * * 1-5" # Every Monday through Friday at 1 AM UTC
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update-master-docs:
|
||||
name: Call documentation update for master
|
||||
uses: ./.github/workflows/docs-generate-base.yml
|
||||
with:
|
||||
target_branch: "master"
|
||||
m2_cache_key_suffix: "master"
|
||||
secrets:
|
||||
automation_token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
|
||||
16
.github/workflows/docs-release-generate.yml
vendored
@@ -1,16 +0,0 @@
|
||||
name: Auto-update documentation (release)
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 2 * * 1-5" # Every Monday through Friday at 2 AM UTC
|
||||
workflow_dispatch:
|
||||
|
||||
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"
|
||||
m2_cache_key_suffix: "release"
|
||||
secrets:
|
||||
automation_token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
|
||||
43
.github/workflows/drivers-stress-test.yml
vendored
@@ -689,25 +689,24 @@ jobs:
|
||||
junit-name: 'be-tests-starburst-ee'
|
||||
test-args: ":only ${{ inputs.test }} :times ${{ inputs.times }}"
|
||||
|
||||
# TODO(rileythomp, 2025-08-20): Re-enable vertica tests once the docker image is updated
|
||||
# be-tests-vertica-ee:
|
||||
# if: ${{ false && inputs.driver == 'Vertica' }}
|
||||
# runs-on: ubuntu-22.04
|
||||
# timeout-minutes: 90
|
||||
# env:
|
||||
# CI: 'true'
|
||||
# DRIVERS: vertica
|
||||
# services:
|
||||
# vertica:
|
||||
# image: vertica/vertica-ce:12.0.2-0
|
||||
# ports:
|
||||
# - "5433:5433"
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
# - name: Make plugins directory
|
||||
# run: mkdir plugins
|
||||
# - name: Test Vertica driver
|
||||
# uses: ./.github/actions/test-driver
|
||||
# with:
|
||||
# junit-name: 'be-tests-vertica-ee'
|
||||
# test-args: ":only ${{ inputs.test }} :times ${{ inputs.times }}"
|
||||
be-tests-vertica-ee:
|
||||
if: inputs.driver == 'Vertica'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
CI: 'true'
|
||||
DRIVERS: vertica
|
||||
services:
|
||||
vertica:
|
||||
image: vertica/vertica-ce:12.0.2-0
|
||||
ports:
|
||||
- "5433:5433"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Make plugins directory
|
||||
run: mkdir plugins
|
||||
- name: Test Vertica driver
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
junit-name: 'be-tests-vertica-ee'
|
||||
test-args: ":only ${{ inputs.test }} :times ${{ inputs.times }}"
|
||||
|
||||
78
.github/workflows/drivers.yml
vendored
@@ -48,7 +48,7 @@ jobs:
|
||||
|
||||
# Initialize an empty array to store folders with changes
|
||||
CHANGED_FOLDERS=()
|
||||
for folder in "src/metabase/lib" "src/metabase/query_processor" "modules/drivers" "src/metabase/driver"; do
|
||||
for folder in "src/metabase/lib" "src/metabase/query_processor" "modules/drivers"; do
|
||||
if echo "$CHANGED_FILES" | grep -q "$folder"; then
|
||||
CHANGED_FOLDERS+=("$folder")
|
||||
fi
|
||||
@@ -1078,42 +1078,41 @@ jobs:
|
||||
aws-region: ${{ vars.AWS_REGION }}
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
# TODO(rileythomp, 2025-08-20): Re-enable vertica tests once the docker image is updated
|
||||
# be-tests-vertica-ee:
|
||||
# needs: determine-driver-skips
|
||||
# if: ${{ false && !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
# runs-on: ubuntu-22.04
|
||||
# timeout-minutes: 60
|
||||
# env:
|
||||
# CI: 'true'
|
||||
# DRIVERS: vertica
|
||||
# services:
|
||||
# vertica:
|
||||
# image: vertica/vertica-ce:12.0.2-0
|
||||
# ports:
|
||||
# - "5433:5433"
|
||||
# name: Vertica
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
# - name: Make plugins directory
|
||||
# run: mkdir plugins
|
||||
# - name: Test Vertica driver
|
||||
# uses: ./.github/actions/test-driver
|
||||
# with:
|
||||
# junit-name: 'be-tests-vertica-ee'
|
||||
# test-args: >-
|
||||
# :only-tags [:mb/driver-tests]
|
||||
# - name: Upload Test Results
|
||||
# uses: ./.github/actions/upload-test-results
|
||||
# if: always()
|
||||
# with:
|
||||
# input-path: ./target/junit/
|
||||
# output-name: ${{ github.job }}
|
||||
# bucket: ${{ vars.AWS_S3_TEST_RESULTS_BUCKET }}
|
||||
# aws-access-key-id: ${{ secrets.AWS_TEST_RESULTS_ACCESS_KEY_ID }}
|
||||
# aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
|
||||
# aws-region: ${{ vars.AWS_REGION }}
|
||||
# trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
be-tests-vertica-ee:
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
CI: 'true'
|
||||
DRIVERS: vertica
|
||||
services:
|
||||
vertica:
|
||||
image: vertica/vertica-ce:12.0.2-0
|
||||
ports:
|
||||
- "5433:5433"
|
||||
name: Vertica
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Make plugins directory
|
||||
run: mkdir plugins
|
||||
- name: Test Vertica driver
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
junit-name: 'be-tests-vertica-ee'
|
||||
test-args: >-
|
||||
:only-tags [:mb/driver-tests]
|
||||
- name: Upload Test Results
|
||||
uses: ./.github/actions/upload-test-results
|
||||
if: always()
|
||||
with:
|
||||
input-path: ./target/junit/
|
||||
output-name: ${{ github.job }}
|
||||
bucket: ${{ vars.AWS_S3_TEST_RESULTS_BUCKET }}
|
||||
aws-access-key-id: ${{ secrets.AWS_TEST_RESULTS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ vars.AWS_REGION }}
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
drivers-tests-result:
|
||||
needs:
|
||||
@@ -1137,8 +1136,7 @@ jobs:
|
||||
- be-tests-sqlite-ee
|
||||
- be-tests-sqlserver
|
||||
- be-tests-starburst-ee
|
||||
# TODO(rileythomp, 2025-08-20): Re-enable vertica tests once the docker image is updated
|
||||
# - be-tests-vertica-ee
|
||||
- be-tests-vertica-ee
|
||||
- be-tests-clickhouse-ee
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
@@ -1160,7 +1158,7 @@ jobs:
|
||||
}));
|
||||
|
||||
// are all jobs skipped or successful?
|
||||
if (jobs.every(job => (job.result === 'skipped' || job.result === 'success' || job.name == 'be-tests-starburst-ee'))) {
|
||||
if (jobs.every(job => (job.result === 'skipped' || job.result === 'success'))) {
|
||||
console.log("");
|
||||
console.log(" _------. ");
|
||||
console.log(" / , \_ ");
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
# Thi 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
|
||||
name: E2E Cross-version Component Tests for Embedding SDK
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
cached-embedding-sdk-dist-artifact-name:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
files-changed:
|
||||
name: "SDK backward-compatibility E2E > Check which files changed"
|
||||
name: "SDK cross-version E2E > Check which files changed"
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 3
|
||||
outputs:
|
||||
e2e_embedding_sdk: ${{ steps.changes.outputs.e2e_embedding_sdk }}
|
||||
e2e_all: ${{ steps.changes.outputs.e2e_all }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test which files changed
|
||||
@@ -26,31 +19,11 @@ jobs:
|
||||
token: ${{ github.token }}
|
||||
filters: .github/file-paths.yaml
|
||||
|
||||
decide-target-ref:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
target-ref: ${{ steps.get-target-ref.outputs.value }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Decide ref to checkout
|
||||
id: get-target-ref
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
echo "value=${{ github.base_ref }}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "value=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
# if this is a test on a release branch, we need to check the build requirements
|
||||
get-build-requirements:
|
||||
name: "SDK backward-compatibility E2E > [Backport only] Get build requirements"
|
||||
needs: [decide-target-ref]
|
||||
name: "SDK cross-version E2E > [Backport only] Get build requirements"
|
||||
if: |
|
||||
!cancelled() &&
|
||||
contains(github.base_ref || github.ref, 'release-x')
|
||||
!cancelled()
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 10
|
||||
outputs:
|
||||
@@ -59,7 +32,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.decide-target-ref.outputs.target-ref }}
|
||||
sparse-checkout: release
|
||||
- name: Prepare build scripts
|
||||
run: cd ${{ github.workspace }}/release && yarn && yarn build
|
||||
@@ -82,12 +54,76 @@ jobs:
|
||||
node_version: requirements.node,
|
||||
};
|
||||
|
||||
e2e-tests:
|
||||
name: "SDK backward-compatibility E2E > Run e2e tests"
|
||||
needs: [files-changed, decide-target-ref, get-build-requirements]
|
||||
build:
|
||||
name: "SDK cross-version E2E > Build uberjar"
|
||||
needs: [files-changed, get-build-requirements]
|
||||
if: |
|
||||
!cancelled() &&
|
||||
needs.files-changed.outputs.e2e_embedding_sdk == 'true'
|
||||
!cancelled()
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 25
|
||||
env:
|
||||
MB_EDITION: ee
|
||||
INTERACTIVE: false
|
||||
# make sure that builds on release branches get licenses, because we use them for releases
|
||||
SKIP_LICENSES: ${{ github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
with:
|
||||
node-version: "${{ needs.get-build-requirements.outputs.node_version }}"
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: uberjar
|
||||
java-version: "${{ needs.get-build-requirements.outputs.java_version || 11 }}"
|
||||
|
||||
- name: Build uberjar with ./bin/build.sh
|
||||
run: ./bin/build.sh
|
||||
|
||||
- name: Prepare uberjar artifact
|
||||
uses: ./.github/actions/prepare-uberjar-artifact
|
||||
with:
|
||||
name: metabase-ee-${{ github.event.pull_request.head.sha || github.sha }}-uberjar-cross-version
|
||||
|
||||
resolve-sdk-version:
|
||||
name: "SDK cross-version E2E > Resolve SDK version"
|
||||
if: |
|
||||
!cancelled()
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 10
|
||||
outputs:
|
||||
sdk_version: ${{ fromJson(steps.dependencies.outputs.result).sdk_version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: release
|
||||
- name: Prepare build scripts
|
||||
run: cd ${{ github.workspace }}/release && yarn && yarn build
|
||||
- name: Get latest SDK release for this branch
|
||||
uses: actions/github-script@v7
|
||||
id: dependencies
|
||||
with:
|
||||
script: | # js
|
||||
const { getSdkVersionFromReleaseBranchName } = require('${{ github.workspace }}/release/dist/index.cjs');
|
||||
const branchName = '${{ github.base_ref || github.ref }}';
|
||||
|
||||
const sdk_version = await getSdkVersionFromReleaseBranchName({
|
||||
github,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
branchName,
|
||||
});
|
||||
|
||||
return {
|
||||
sdk_version,
|
||||
};
|
||||
|
||||
e2e-tests:
|
||||
name: "SDK cross-version E2E > Run e2e tests"
|
||||
needs: [get-build-requirements, build, resolve-sdk-version]
|
||||
if: |
|
||||
!cancelled() && needs.build.result == 'success'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 45
|
||||
env:
|
||||
@@ -106,33 +142,45 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.decide-target-ref.outputs.target-ref }}
|
||||
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
# Needed to omit newly added tests for functionality that is not yet released
|
||||
- name: Sparse checkout tests from SDK release commit
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
m2-cache-key: uberjar
|
||||
java-version: "${{ needs.get-build-requirements.outputs.java_version || 21 }}"
|
||||
ref: embedding-sdk-${{ needs.resolve-sdk-version.outputs.sdk_version }}
|
||||
path: sdk-release-e2e
|
||||
sparse-checkout: e2e
|
||||
|
||||
- name: Move tests from the release commit into the repo
|
||||
run: |
|
||||
rm -rf ./e2e/support/*
|
||||
mv ./sdk-release-e2e/e2e/support/* ./e2e/support
|
||||
|
||||
rm -rf ./e2e/test-component/*
|
||||
mv ./sdk-release-e2e/e2e/test-component/* ./e2e/test-component
|
||||
shell: bash
|
||||
|
||||
- name: Retrieve uberjar artifact for ee
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-ee-${{ github.event.pull_request.head.sha || github.sha }}-uberjar-cross-version
|
||||
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
with:
|
||||
node-version: "${{ needs.get-build-requirements.outputs.node_version }}"
|
||||
|
||||
- name: Build uberjar with ./bin/build.sh
|
||||
run: ./bin/build.sh
|
||||
|
||||
- name: Retrieve Embedding SDK dist artifact
|
||||
uses: actions/download-artifact@v4
|
||||
- name: Prepare JDK ${{ needs.get-build-requirements.outputs.java_version || 11 }}
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
name: ${{ inputs.cached-embedding-sdk-dist-artifact-name }}
|
||||
path: ${{ github.workspace }}/resources/embedding-sdk
|
||||
java-version: ${{ needs.get-build-requirements.outputs.java_version || 11 }}
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Prepare Cypress environment
|
||||
id: cypress-prep
|
||||
uses: ./.github/actions/prepare-cypress
|
||||
|
||||
- name: Install Embedding SDK package v${{ needs.resolve-sdk-version.outputs.sdk_version }}
|
||||
run: yarn add @metabase/embedding-sdk-react@${{ needs.resolve-sdk-version.outputs.sdk_version }}
|
||||
|
||||
- name: Run Metabase
|
||||
run: node e2e/runner/run_cypress_ci.js start
|
||||
|
||||
162
.github/workflows/e2e-cross-version-for-breaking-changes.yml
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
name: E2E cross-version for breaking changes
|
||||
|
||||
# See `bin/backward-compatibility-test.js` for the documentation of this workflow.
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
fe-ref:
|
||||
description: "Frontend git ref to use"
|
||||
type: string
|
||||
required: true
|
||||
default: "master"
|
||||
be-ref:
|
||||
description: "Backend git ref to use"
|
||||
type: string
|
||||
required: true
|
||||
default: "master"
|
||||
total-shards:
|
||||
description: "Total number of parallel test shards"
|
||||
type: number
|
||||
required: false
|
||||
default: 4
|
||||
workflow_call:
|
||||
inputs:
|
||||
fe-ref:
|
||||
description: "Frontend git ref to use"
|
||||
type: string
|
||||
required: true
|
||||
be-ref:
|
||||
description: "Backend git ref to use"
|
||||
type: string
|
||||
required: true
|
||||
total-shards:
|
||||
description: "Total number of parallel test shards"
|
||||
type: number
|
||||
required: false
|
||||
default: 4
|
||||
|
||||
jobs:
|
||||
generate-matrix:
|
||||
name: "Breaking changes E2E > Generate matrix"
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix_json: ${{ steps.set_matrix.outputs.matrix_json }}
|
||||
shards_total: ${{ steps.set_matrix.outputs.shards_total }}
|
||||
steps:
|
||||
- name: Set up shard matrix
|
||||
id: set_matrix
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
# generate an output like `{"matrixJson": "{\"shard\": [1, 2, 3, 4]}", "shardsTotal": 4}` to be used in the other jobs
|
||||
script: |
|
||||
const totalShards = parseInt(process.env.TOTAL_SHARDS_INPUT, 10);
|
||||
|
||||
const matrix = { shard: Array.from({ length: totalShards }, (_, i) => i + 1) };
|
||||
|
||||
console.log("Generated matrix JSON", matrix);
|
||||
console.log(`Total shards: ${totalShards}`);
|
||||
|
||||
core.setOutput('matrix_json', JSON.stringify(matrix));
|
||||
core.setOutput('shards_total', totalShards);
|
||||
env:
|
||||
TOTAL_SHARDS_INPUT: ${{ inputs.total-shards }}
|
||||
|
||||
build-jar:
|
||||
name: "Breaking changes E2E > Build jar"
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 45
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare Node.js
|
||||
# We're not using `actions/prepare-frontend` because we don't want to install deps from the root repo
|
||||
# nor we want to touch the cache as we'll be potentially be installing different versions of packages
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: cross-version-uberjar
|
||||
|
||||
- name: Build jar with different frontend and backend version
|
||||
env:
|
||||
MB_EDITION: ee
|
||||
CYPRESS_CI: true
|
||||
run: |
|
||||
node bin/backward-compatibility-test.js \
|
||||
${{ inputs.fe-ref }} ${{ inputs.be-ref }} \
|
||||
build
|
||||
|
||||
- name: Upload Uberjar
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: metabase-jar-cross-version
|
||||
path: .tmp/metabase-be/target/uberjar/metabase.jar
|
||||
if-no-files-found: error
|
||||
|
||||
run-breaking-changes-tests:
|
||||
name: "Breaking changes E2E > Run breaking changes tests"
|
||||
needs: [build-jar, generate-matrix]
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 45
|
||||
env:
|
||||
TOTAL_SHARDS: ${{ needs.generate-matrix.outputs.shards_total }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix_json) }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: cross-version-uberjar
|
||||
|
||||
- name: Download Uberjar
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-jar-cross-version
|
||||
path: .tmp/metabase-be/target/uberjar/
|
||||
|
||||
- name: Download FE repo
|
||||
run: |
|
||||
git clone --depth 1 -b ${{ inputs.fe-ref }} https://github.com/metabase/metabase.git .tmp/metabase-fe
|
||||
|
||||
- name: Install FE dependencies
|
||||
working-directory: .tmp/metabase-fe
|
||||
run: |
|
||||
yarn install
|
||||
|
||||
- name: Prepare Cypress environment
|
||||
id: cypress-prep
|
||||
uses: ./.github/actions/prepare-cypress
|
||||
with:
|
||||
working-directory: .tmp/metabase-fe
|
||||
|
||||
- name: Run the tests
|
||||
env:
|
||||
MB_EDITION: ee
|
||||
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_CI: true
|
||||
run: |
|
||||
node bin/backward-compatibility-test.js \
|
||||
${{ inputs.fe-ref }} ${{ inputs.be-ref }} \
|
||||
start > /dev/null & \
|
||||
node bin/backward-compatibility-test.js \
|
||||
${{ inputs.fe-ref }} ${{ inputs.be-ref }} \
|
||||
test ${{ matrix.shard}}/${{ env.TOTAL_SHARDS }}
|
||||
@@ -178,8 +178,12 @@ jobs:
|
||||
with:
|
||||
name: metabase-ee-${{ github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
|
||||
- name: Compile CLJS
|
||||
run: yarn build-pure:cljs
|
||||
shell: bash
|
||||
|
||||
- name: Build Embedding SDK package
|
||||
run: yarn build-embedding-sdk-package
|
||||
run: yarn build-embedding-sdk
|
||||
|
||||
- name: Prepare Embedding SDK artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -192,7 +196,7 @@ jobs:
|
||||
# - starts it
|
||||
# - runs its Cypress tests against the local metabase.jar and local @metabase/embedding-sdk-react package.
|
||||
# The job is not required, though if it's failing better to be sure that it's not caused by a breaking change.
|
||||
# For more details see `Sample Apps compatibility with Embedding SDK tests` in `enterprise/frontend/src/embedding-sdk-package/dev.md`
|
||||
# For more details see `Sample Apps compatibility with Embedding SDK tests` in `enterprise/frontend/src/embedding-sdk/dev.md`
|
||||
e2e-sample-apps-tests:
|
||||
needs: [get-build-requirements, get-sample-apps-data, build]
|
||||
strategy:
|
||||
@@ -316,7 +320,7 @@ jobs:
|
||||
# - starts an app
|
||||
# - runs its Cypress tests against the e2e test metabase instance and local @metabase/embedding-sdk-react package.
|
||||
# The job is not required, though if it's failing better to be sure that it's not caused by a breaking change.
|
||||
# For more details see `Embedding SDK integration tests with Host Apps` in `enterprise/frontend/src/embedding-sdk-package/dev.md`
|
||||
# For more details see `Embedding SDK integration tests with Host Apps` in `enterprise/frontend/src/embedding-sdk/dev.md`
|
||||
e2e-host-apps-tests:
|
||||
needs: [get-build-requirements, build]
|
||||
strategy:
|
||||
|
||||
8
.github/workflows/e2e-test.yml
vendored
@@ -79,11 +79,9 @@ jobs:
|
||||
uses: ./.github/actions/run-embedding-sdk-storybook
|
||||
|
||||
- name: Retrieve uberjar artifact for ${{ inputs.edition }}
|
||||
uses: ./.github/actions/fetch-artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-${{ inputs.edition }}-${{ github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
extract-path: "target/uberjar"
|
||||
output-name: "metabase.jar"
|
||||
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
@@ -131,7 +129,7 @@ jobs:
|
||||
run: |
|
||||
echo "Running tests with specs: $SPEC_PATH"
|
||||
node e2e/runner/run_cypress_ci.js e2e \
|
||||
--env grepTags="-@mongo+-@flaky+-@OSS+-@skip",grepOmitFiltered=true \
|
||||
--env grepTags="-@mongo+-@flaky+-@OSS --@quarantine",grepOmitFiltered=true \
|
||||
--spec "$SPEC_PATH" \
|
||||
--browser ${{ steps.cypress-prep.outputs.chrome-path }}
|
||||
|
||||
@@ -143,7 +141,7 @@ jobs:
|
||||
run: |
|
||||
echo "Running tests with specs: $SPEC_PATH"
|
||||
node e2e/runner/run_cypress_ci.js e2e \
|
||||
--env grepTags="${{inputs.tags}}+-@skip",grepOmitFiltered=true \
|
||||
--env grepTags="${{inputs.tags}} --@quarantine",grepOmitFiltered=true \
|
||||
--spec "$SPEC_PATH" \
|
||||
--browser ${{ steps.cypress-prep.outputs.chrome-path }}
|
||||
|
||||
|
||||
29
.github/workflows/embedding-sdk.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
with:
|
||||
m2-cache-key: "cljs"
|
||||
- name: Build Embedding SDK package
|
||||
run: yarn build-embedding-sdk-package
|
||||
run: yarn build-embedding-sdk
|
||||
- name: Prepare Embedding SDK artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -137,7 +137,7 @@ jobs:
|
||||
if: ${{ steps.docs-generation.outcome == 'failure' }}
|
||||
run: exit 1
|
||||
|
||||
# See `Component e2e tests` in `enterprise/frontend/src/embedding-sdk-package/dev.md`
|
||||
# See `Component e2e tests` in `enterprise/frontend/src/embedding-sdk/dev.md`
|
||||
sdk-e2e-tests:
|
||||
name: "SDK e2e tests"
|
||||
uses: ./.github/workflows/e2e-component-tests-embedding-sdk.yml
|
||||
@@ -146,13 +146,24 @@ jobs:
|
||||
with:
|
||||
cached-embedding-sdk-dist-artifact-name: embedding-sdk-${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
e2e-component-tests-embedding-sdk-backward-compatibility:
|
||||
name: "SDK e2e backward compatibility tests"
|
||||
uses: ./.github/workflows/e2e-component-tests-embedding-sdk-backward-compatibility.yml
|
||||
needs: [build]
|
||||
e2e-component-tests-embedding-sdk-cross-version:
|
||||
name: "[Backport only] SDK e2e cross version tests"
|
||||
# run on: every push on release branches, and every pr that targets a release branch
|
||||
if: ${{ startsWith(github.ref, 'refs/heads/release-x.') || (github.event_name == 'pull_request' && startsWith(github.base_ref, 'release-x.')) }}
|
||||
uses: ./.github/workflows/e2e-component-tests-embedding-sdk-cross-version.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
cached-embedding-sdk-dist-artifact-name: embedding-sdk-${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
# Temporarily skipped because the cypress runner crashes
|
||||
# See `bin/backward-compatibility-test.js` for the documentation of this workflow.
|
||||
# cross-version-for-breaking-changes:
|
||||
# name: "[NOT REQUIRED - Experimental - Backport only] detect breaking changes with cross versions tests"
|
||||
# # run on: every pr that targets a release branch, it does NOT run for pr targeting master
|
||||
# if: ${{ github.event_name == 'pull_request' && startsWith(github.base_ref, 'release-x.') }}
|
||||
# uses: ./.github/workflows/e2e-cross-version-for-breaking-changes.yml
|
||||
# secrets: inherit
|
||||
# with:
|
||||
# fe-ref: ${{ github.base_ref }}
|
||||
# be-ref: ${{ github.head_ref }}
|
||||
|
||||
embedding-sdk-tests-result:
|
||||
needs:
|
||||
@@ -160,7 +171,7 @@ jobs:
|
||||
- embedding-sdk-docs-snippets-type-check
|
||||
- embedding-sdk-api-documentation-generation-validation
|
||||
- sdk-e2e-tests
|
||||
- e2e-component-tests-embedding-sdk-backward-compatibility
|
||||
- e2e-component-tests-embedding-sdk-cross-version
|
||||
if: always() && !cancelled()
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
6
.github/workflows/perf-test.yml
vendored
@@ -89,11 +89,11 @@ jobs:
|
||||
done
|
||||
echo "run_id=$(jq -r '.workflow_runs[0].id' e2e-tests.json)" >> $GITHUB_OUTPUT
|
||||
- name: Retrieve uberjar artifact for ee
|
||||
uses: ./.github/actions/fetch-artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-ee-${{ github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
extract-path: "target/uberjar"
|
||||
output-name: "metabase.jar"
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ inputs.wait_for_uberjar && steps.wait_for_uberjar.outputs.run_id || github.run_id }}
|
||||
- name: Move uberjar to bin/docker
|
||||
run: |
|
||||
jar xf target/uberjar/metabase.jar
|
||||
|
||||
4
.github/workflows/pr-env.yml
vendored
@@ -27,11 +27,9 @@ jobs:
|
||||
with:
|
||||
registries: "${{ secrets.PR_ENV_AWS_ACCOUNT_ID }}"
|
||||
- name: Retrieve uberjar artifact for ee
|
||||
uses: ./.github/actions/fetch-artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-ee-${{ github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
extract-path: "target/uberjar"
|
||||
output-name: "metabase.jar"
|
||||
- name: Move uberjar to bin/docker
|
||||
run: |
|
||||
jar xf target/uberjar/metabase.jar
|
||||
|
||||
10
.github/workflows/release-embedding-sdk.yml
vendored
@@ -187,7 +187,7 @@ jobs:
|
||||
- name: Get current SDK version
|
||||
id: current-sdk-version
|
||||
run: |
|
||||
VERSION=$(jq -r .version ./enterprise/frontend/src/embedding-sdk-package/package.template.json)
|
||||
VERSION=$(jq -r .version ./enterprise/frontend/src/embedding-sdk/package.template.json)
|
||||
echo "sdk_current_version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get next SDK patch version
|
||||
@@ -298,8 +298,8 @@ jobs:
|
||||
run: |
|
||||
yarn embedding-sdk:generate-changelog -o changelog-diff
|
||||
|
||||
- name: Build SDK package
|
||||
run: yarn run build-embedding-sdk-package
|
||||
- name: Build SDK bundle
|
||||
run: yarn run build-embedding-sdk
|
||||
|
||||
- name: Generate SDK package.json in the build directory
|
||||
run: yarn run embedding-sdk:generate-package
|
||||
@@ -350,8 +350,8 @@ jobs:
|
||||
|
||||
- name: Update changelog
|
||||
run: |
|
||||
cat changelog-diff enterprise/frontend/src/embedding-sdk-bundle/CHANGELOG.md > new-changelog
|
||||
mv new-changelog enterprise/frontend/src/embedding-sdk-bundle/CHANGELOG.md
|
||||
cat changelog-diff enterprise/frontend/src/embedding-sdk/CHANGELOG.md > new-changelog
|
||||
mv new-changelog enterprise/frontend/src/embedding-sdk/CHANGELOG.md
|
||||
|
||||
- name: Create a PR updating readme + published version, and changelog (using GitHub Metabase Automation account)
|
||||
run: |
|
||||
|
||||
21
.github/workflows/run-tests.yml
vendored
@@ -72,6 +72,8 @@ jobs:
|
||||
if: ${{ !cancelled() && !(needs.files-changed.outputs.documentation == 'true' && needs.files-changed.outputs.backend_all == 'false' && needs.files-changed.outputs.frontend_all == 'false' && needs.files-changed.outputs.e2e_all == 'false') }}
|
||||
uses: ./.github/workflows/uberjar.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
source_changed: ${{ needs.files-changed.outputs.backend_all == 'true' || needs.files-changed.outputs.frontend_all == 'true' || needs.static-viz-files-changed.outputs.static_viz == 'true' }}
|
||||
|
||||
backend-tests:
|
||||
if: ${{ !cancelled() }}
|
||||
@@ -81,13 +83,6 @@ jobs:
|
||||
with:
|
||||
skip: ${{ needs.files-changed.outputs.backend_all != 'true' && needs.static-viz-files-changed.outputs.static_viz != 'true' }}
|
||||
|
||||
semantic-search-tests:
|
||||
needs: files-changed
|
||||
uses: ./.github/workflows/semantic-search.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
skip: ${{ needs.files-changed.outputs.backend_all != 'true' }}
|
||||
|
||||
app-db-tests:
|
||||
needs: files-changed
|
||||
uses: ./.github/workflows/app-db.yml
|
||||
@@ -135,15 +130,3 @@ jobs:
|
||||
contains(github.event.pull_request.labels.*.name, 'PR-Env')
|
||||
uses: ./.github/workflows/pr-env.yml
|
||||
secrets: inherit
|
||||
|
||||
containerize:
|
||||
needs: [uberjar]
|
||||
if: |
|
||||
!cancelled() &&
|
||||
needs.uberjar.result == 'success' &&
|
||||
(
|
||||
(github.event_name == 'push' && contains(fromJson('["master", "metabot-v3-main", "internal-tools"]'), github.ref_name)) ||
|
||||
(github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'build-docker-uberjar'))
|
||||
)
|
||||
uses: ./.github/workflows/containerize-uberjar.yml
|
||||
secrets: inherit
|
||||
|
||||
145
.github/workflows/semantic-search.yml
vendored
@@ -1,145 +0,0 @@
|
||||
name: Semantic Search Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
skip:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}-semantic-search
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
semantic-search-tests-pgvector:
|
||||
if: ${{ !inputs.skip }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version:
|
||||
- name: pgvector pg16
|
||||
junit-name: semantic-search-tests-pgvector-16
|
||||
image: pgvector/pgvector:pg16
|
||||
env:
|
||||
enable-ssl-tests: 'false'
|
||||
job:
|
||||
- name: Semantic Search Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only '"enterprise/backend/test/metabase_enterprise/semantic_search"'
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
|
||||
services:
|
||||
pgvector:
|
||||
image: ${{ matrix.version.image }}
|
||||
ports:
|
||||
- "5432:5432"
|
||||
env:
|
||||
POSTGRES_DB: mb_semantic_search
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
env:
|
||||
# Only run old migrations tests on pushes to master or release branches. All other branches should skip tests
|
||||
# with the tag `mb/old-migrations-test`. `__ADDITIONAL_EXCLUDED_TAG__` is not used anywhere outside of splicing
|
||||
# it in to the command below.
|
||||
__ADDITIONAL_EXCLUDED_TAG__: >-
|
||||
${{
|
||||
(
|
||||
github.event_name == 'push' &&
|
||||
(
|
||||
github.ref == 'master' ||
|
||||
startsWith(github.ref, 'release-')
|
||||
) &&
|
||||
''
|
||||
) ||
|
||||
':mb/old-migrations-test'
|
||||
}}
|
||||
MB_PGVECTOR_DB_URL: 'jdbc:postgres://localhost:5432/mb_semantic_search?user=postgres&password=postgres'
|
||||
CI: 'true'
|
||||
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test ${{ matrix.version.name }}
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
build-static-viz: ${{ matrix.job.build-static-viz }}
|
||||
junit-name: ${{ matrix.version.junit-name }}
|
||||
test-args: >-
|
||||
${{ matrix.job.test-args }}
|
||||
:exclude-tags '[ ${{ matrix.job.exclude-tag }} ${{ env.__ADDITIONAL_EXCLUDED_TAG__ }}]'
|
||||
- name: Upload Test Results
|
||||
uses: ./.github/actions/upload-test-results
|
||||
if: always()
|
||||
with:
|
||||
input-path: ./target/junit/
|
||||
output-name: ${{ github.job }}
|
||||
bucket: ${{ vars.AWS_S3_TEST_RESULTS_BUCKET }}
|
||||
aws-access-key-id: ${{ secrets.AWS_TEST_RESULTS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ vars.AWS_REGION }}
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
semantic-search-tests-result:
|
||||
needs:
|
||||
- semantic-search-tests-pgvector
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
name: semantic-search-tests-result
|
||||
if: always() && !cancelled()
|
||||
steps:
|
||||
- name: Check job status
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
needs: ${{ toJson(needs) }}
|
||||
with:
|
||||
script: | # js
|
||||
const needs = JSON.parse(process.env.needs);
|
||||
|
||||
const jobs = Object.entries(needs).map(
|
||||
([jobName, jobValues]) => ({
|
||||
name: jobName,
|
||||
result: jobValues.result
|
||||
}));
|
||||
|
||||
// are all jobs skipped or successful?
|
||||
if (jobs.every(job => (job.result === 'skipped' || job.result === 'success'))) {
|
||||
console.log("");
|
||||
console.log(" _------. ");
|
||||
console.log(" / , \_ ");
|
||||
console.log(" / / /{}\ |o\_ ");
|
||||
console.log(" / \ `--' /-' \ ");
|
||||
console.log(" | \ \ | ");
|
||||
console.log(" | |`-, | ");
|
||||
console.log(" / /__/)/ ");
|
||||
console.log(" | | ");
|
||||
console.log("");
|
||||
console.log("All semantic search tests have passed (or have been skipped). Cam is very proud of you.");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// otherwise, something failed
|
||||
console.log("");
|
||||
console.log(" .::::::::::. .::::::::::. ");
|
||||
console.log(" .::::''''''::::. .::::''''''::::. ");
|
||||
console.log(" .:::' `::::.... ....::::' `:::. ");
|
||||
console.log(" .::' `:::::::| |:::::::' `::. ");
|
||||
console.log(" .::| |::::::|_ ___ __|::::::| |::. ");
|
||||
console.log(" `--' |::::::|_()__()_|::::::| `--' ");
|
||||
console.log(" ::: |::-o::| |::o-::| ::: ");
|
||||
console.log(" `::. .|::::::| |::::::|. .::' ");
|
||||
console.log(" `:::. .::\-----' `-----/::. .:::' ");
|
||||
console.log(" `::::......::::' `::::......::::' ");
|
||||
console.log(" `::::::::::' `::::::::::' ");
|
||||
console.log("");
|
||||
console.log("Semantic search tests have failed. You have been sentenced to MetaJail.");
|
||||
|
||||
jobs.forEach((job) => {
|
||||
if (job.result !== 'success') {
|
||||
console.log(`${job.name} - ${job.result}`);
|
||||
}
|
||||
});
|
||||
|
||||
process.exit(1);
|
||||
@@ -1,21 +0,0 @@
|
||||
name: Uberjar Containerize labeled
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ labeled ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
uberjar:
|
||||
if: ${{ github.event.label.name == 'build-docker-uberjar' }}
|
||||
uses: ./.github/workflows/uberjar.yml
|
||||
secrets: inherit
|
||||
|
||||
containerize:
|
||||
needs: [uberjar]
|
||||
if: ${{ github.event.label.name == 'build-docker-uberjar' }}
|
||||
uses: ./.github/workflows/containerize-uberjar.yml
|
||||
secrets: inherit
|
||||
140
.github/workflows/uberjar.yml
vendored
@@ -1,16 +1,17 @@
|
||||
name: Build Uberjar
|
||||
name: Build + Docker Uberjar
|
||||
|
||||
# This workflow builds an uberjar and pushes it to dockerhub for any branch, either on-demand,
|
||||
# or automatically for the listed branches
|
||||
|
||||
concurrency:
|
||||
group: uberjar-${{ github.event.inputs.commit || github.event.pull_request.head.sha || github.sha }}
|
||||
group: uberjar-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- metabot-v3-main
|
||||
- internal-tools
|
||||
paths-ignore:
|
||||
# config files
|
||||
@@ -27,6 +28,11 @@ on:
|
||||
commit:
|
||||
description: "Optional full-length commit SHA-1 hash"
|
||||
workflow_call:
|
||||
inputs:
|
||||
source_changed:
|
||||
description: "Whether source code has changed"
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
check-existing-artifacts:
|
||||
@@ -37,41 +43,38 @@ jobs:
|
||||
oss_exists: ${{ steps.check-oss.outcome == 'success' }}
|
||||
should_build: ${{ steps.decide.outputs.should_build }}
|
||||
steps:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v4
|
||||
- name: Try to fetch existing EE artifact
|
||||
- name: Try to download existing EE artifact
|
||||
id: check-ee
|
||||
continue-on-error: true
|
||||
uses: ./.github/actions/fetch-artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-ee-${{ github.event.inputs.commit || github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
output-name: metabase-ee.jar
|
||||
|
||||
- name: Try to fetch existing OSS artifact
|
||||
- name: Try to download existing OSS artifact
|
||||
id: check-oss
|
||||
continue-on-error: true
|
||||
uses: ./.github/actions/fetch-artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-oss-${{ github.event.inputs.commit || github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
output-name: metabase-oss.jar
|
||||
|
||||
- name: Decide if build is needed
|
||||
id: decide
|
||||
run: |
|
||||
SOURCE_CHANGED="${{ inputs.source_changed == true }}"
|
||||
EE_EXISTS="${{ steps.check-ee.outcome == 'success' }}"
|
||||
OSS_EXISTS="${{ steps.check-oss.outcome == 'success' }}"
|
||||
|
||||
echo "Source changed: $SOURCE_CHANGED"
|
||||
echo "EE exists: $EE_EXISTS"
|
||||
echo "OSS exists: $OSS_EXISTS"
|
||||
|
||||
# Build only if artifacts don't exist for this commit hash
|
||||
# Since we build by hash, if artifacts exist for this hash, we don't need to rebuild
|
||||
if [[ "$EE_EXISTS" == "false" ]] || [[ "$OSS_EXISTS" == "false" ]]; then
|
||||
# Build if source changed OR artifacts don't exist
|
||||
if [[ "$SOURCE_CHANGED" == "true" ]] || [[ "$EE_EXISTS" == "false" ]] || [[ "$OSS_EXISTS" == "false" ]]; then
|
||||
SHOULD_BUILD="true"
|
||||
echo "Will build: ee_exists=$EE_EXISTS, oss_exists=$OSS_EXISTS"
|
||||
echo "Will build: source_changed=$SOURCE_CHANGED, ee_exists=$EE_EXISTS, oss_exists=$OSS_EXISTS"
|
||||
else
|
||||
SHOULD_BUILD="false"
|
||||
echo "Skipping build: artifacts exist for this commit hash"
|
||||
echo "Skipping build: artifacts exist and no source changes"
|
||||
fi
|
||||
|
||||
echo "should_build=$SHOULD_BUILD" >> $GITHUB_OUTPUT
|
||||
@@ -107,17 +110,63 @@ jobs:
|
||||
node_version: requirements.node,
|
||||
};
|
||||
|
||||
get-container-info:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
name: Get container info
|
||||
# Skip if this is a PR without the build-docker-uberjar label
|
||||
if: github.ref_name == 'master' || contains(github.event.pull_request.labels.*.name, 'build-docker-uberjar')
|
||||
outputs:
|
||||
editions: ${{ toJson(fromJson(steps.info.outputs.result).editions) }}
|
||||
ee: ${{ toJson(fromJson(steps.info.outputs.result).ee) }}
|
||||
oss: ${{ toJson(fromJson(steps.info.outputs.result).oss) }}
|
||||
steps:
|
||||
- name: Get docker repo and tag
|
||||
id: info
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: | # js
|
||||
const branch = '${{ github.head_ref || github.ref_name }}';
|
||||
const owner = '${{ github.repository_owner }}';
|
||||
|
||||
console.log(`Branch: ${branch}`);
|
||||
|
||||
if (branch === "master") {
|
||||
return {
|
||||
editions: ["ee", "oss"],
|
||||
ee: {
|
||||
repo: `${owner}/metabase-enterprise-head`,
|
||||
tag: "latest"
|
||||
},
|
||||
oss: {
|
||||
repo: `${owner}/metabase-head`,
|
||||
tag: "latest"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
editions: ["ee"],
|
||||
ee: {
|
||||
repo: `${owner}/metabase-dev`,
|
||||
tag: branch.replaceAll("/", "-"), // slashes make docker sad
|
||||
},
|
||||
};
|
||||
|
||||
- name: Print output
|
||||
run: |
|
||||
echo "${{ steps.info.outputs.result }}"
|
||||
|
||||
build:
|
||||
needs:
|
||||
[check-existing-artifacts, get-build-requirements]
|
||||
[check-existing-artifacts, get-build-requirements, get-container-info]
|
||||
if: always() && !cancelled() && needs.check-existing-artifacts.outputs.should_build == 'true' && (needs.get-build-requirements.result == 'success' || needs.get-build-requirements.result == 'skipped')
|
||||
name: Build MB ${{ matrix.edition }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
matrix:
|
||||
edition: ["ee", "oss"]
|
||||
edition: ${{ needs.get-container-info.result == 'success' && fromJson(needs.get-container-info.outputs.editions) || fromJson('["ee", "oss"]') }}
|
||||
env:
|
||||
MB_EDITION: ${{ matrix.edition }}
|
||||
INTERACTIVE: false
|
||||
@@ -146,16 +195,14 @@ jobs:
|
||||
check-jar-health:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Is ${{ matrix.edition }} (java ${{ matrix.java-version }}) healthy?
|
||||
needs: [build, check-existing-artifacts]
|
||||
needs: [build, check-existing-artifacts, get-container-info]
|
||||
if: always() && !cancelled() && (needs.build.result == 'success' || (needs.check-existing-artifacts.outputs.should_build == 'false' && needs.check-existing-artifacts.outputs.ee_exists == 'true' && needs.check-existing-artifacts.outputs.oss_exists == 'true'))
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
edition: ["ee", "oss"]
|
||||
edition: ${{ needs.get-container-info.result == 'success' && fromJson(needs.get-container-info.outputs.editions) || fromJson('["ee", "oss"]') }}
|
||||
java-version: [21]
|
||||
steps:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v4
|
||||
- name: Prepare JRE (Java Run-time Environment)
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
@@ -163,12 +210,57 @@ jobs:
|
||||
java-version: ${{ matrix.java-version }}
|
||||
distribution: "temurin"
|
||||
- run: java -version
|
||||
- name: Retrieve uberjar artifact
|
||||
uses: ./.github/actions/fetch-artifact
|
||||
- uses: actions/download-artifact@v4
|
||||
name: Retrieve uberjar artifact
|
||||
with:
|
||||
name: metabase-${{ matrix.edition }}-${{ github.event.inputs.commit || github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
- name: Launch uberjar
|
||||
run: >-
|
||||
java --add-opens java.base/java.nio=ALL-UNNAMED -jar ./metabase.jar &
|
||||
java --add-opens java.base/java.nio=ALL-UNNAMED -jar ./target/uberjar/metabase.jar &
|
||||
- name: Wait for Metabase to start
|
||||
run: while ! curl 'http://localhost:3000/api/health' | grep '{"status":"ok"}'; do sleep 1; done
|
||||
|
||||
containerize:
|
||||
needs: [check-jar-health, get-container-info, build]
|
||||
if: needs.get-container-info.result == 'success' && needs.build.result == 'success'
|
||||
strategy:
|
||||
matrix:
|
||||
edition: ${{ fromJson(needs.get-container-info.outputs.editions) }}
|
||||
uses: ./.github/workflows/containerize-jar.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
artifact-name: metabase-${{ matrix.edition }}-${{ github.event.inputs.commit || github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
commit: ${{ github.event.inputs.commit || github.sha }}
|
||||
repo: ${{ fromJson(needs.get-container-info.outputs[matrix.edition]).repo }}
|
||||
tag: ${{ fromJson(needs.get-container-info.outputs[matrix.edition]).tag }}
|
||||
release: "false"
|
||||
build-args: |
|
||||
GIT_COMMIT_SHA=${{ github.event.inputs.commit || github.sha }}
|
||||
|
||||
run-trivy:
|
||||
needs: [get-container-info, containerize]
|
||||
strategy:
|
||||
matrix:
|
||||
edition: ${{ fromJson(needs.get-container-info.outputs.editions) }}
|
||||
runs-on: ubuntu-22.04
|
||||
name: Run Trivy vulnerability scanner
|
||||
steps:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.commit || github.sha }}
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@0.29.0
|
||||
env:
|
||||
TRIVY_OFFLINE_SCAN: true
|
||||
repo: ${{ fromJson(needs.get-container-info.outputs[matrix.edition]).repo }}
|
||||
tag: ${{ fromJson(needs.get-container-info.outputs[matrix.edition]).tag }}
|
||||
with:
|
||||
image-ref: docker.io/${{ env.repo }}:${{ env.tag }}
|
||||
format: sarif
|
||||
output: trivy-results.sarif
|
||||
version: "v0.57.1"
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: "trivy-results.sarif"
|
||||
|
||||
4
.gitignore
vendored
@@ -61,9 +61,7 @@ cypress.env.json
|
||||
/resources/frontend_client/app/dist/
|
||||
/resources/frontend_client/app/locales
|
||||
/resources/frontend_client/app/embed.js
|
||||
/resources/frontend_client/app/embedding-sdk.js
|
||||
/resources/frontend_client/app/embedding-sdk.js.map
|
||||
/resources/frontend_client/tmp-*/
|
||||
/resources/frontend_client/tmp-embed-js/
|
||||
/resources/frontend_client/embed.html
|
||||
/resources/frontend_client/embed-sdk.html
|
||||
/resources/frontend_client/index.html
|
||||
|
||||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 66 KiB |