Compare commits
309 Commits
single-dev
...
transforms
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9b011b506 | ||
|
|
b6ff2c819a | ||
|
|
4573893d1a | ||
|
|
d3b2229822 | ||
|
|
71e663c2ba | ||
|
|
6404cbc1b0 | ||
|
|
cf0f22670c | ||
|
|
3edf7f4338 | ||
|
|
7858cc5310 | ||
|
|
c92b06ee68 | ||
|
|
9939bfef78 | ||
|
|
5dda365309 | ||
|
|
fb9385fb9b | ||
|
|
6a90c2274e | ||
|
|
26c5149303 | ||
|
|
eae98e6ebc | ||
|
|
bdbee6a222 | ||
|
|
9f8fb84037 | ||
|
|
20192d3c9e | ||
|
|
74764ff8a8 | ||
|
|
665fd8146d | ||
|
|
0acc749fc0 | ||
|
|
6f26702527 | ||
|
|
921f826288 | ||
|
|
385d600330 | ||
|
|
2928a3c1b9 | ||
|
|
66415b0ba6 | ||
|
|
7b1ac77db0 | ||
|
|
af7deb4b9c | ||
|
|
78f83e6c3c | ||
|
|
fdfe821815 | ||
|
|
2fa6ea0c52 | ||
|
|
2de2f8d732 | ||
|
|
8599574936 | ||
|
|
a97d2d1c0d | ||
|
|
5f8b4e95eb | ||
|
|
6d7524138a | ||
|
|
a793753415 | ||
|
|
20fb8601f6 | ||
|
|
790d221d1f | ||
|
|
ae79ee4e32 | ||
|
|
b484fc93ed | ||
|
|
a5880551f8 | ||
|
|
0614a03ea2 | ||
|
|
dccd4f970e | ||
|
|
b5c789acf0 | ||
|
|
e587fa357d | ||
|
|
bdeca87a47 | ||
|
|
efef12dbb0 | ||
|
|
02da4ebccc | ||
|
|
0ef0f93644 | ||
|
|
76fd1bfb52 | ||
|
|
52fd7f457c | ||
|
|
b1401f1a5a | ||
|
|
de37711918 | ||
|
|
5e40b0d589 | ||
|
|
07267954f1 | ||
|
|
4cd5ac3743 | ||
|
|
bf06c662eb | ||
|
|
9ab71b7283 | ||
|
|
6acc4b0e86 | ||
|
|
c8e9ccae66 | ||
|
|
89dd4a6db2 | ||
|
|
98e2dcc7c8 | ||
|
|
148bd23161 | ||
|
|
68549e8664 | ||
|
|
8adc64a632 | ||
|
|
1ea95981bf | ||
|
|
00a24143f0 | ||
|
|
5feeb16ab7 | ||
|
|
34965e0fcb | ||
|
|
7c39ff2fbe | ||
|
|
7f724d65b0 | ||
|
|
4c6ebf7d58 | ||
|
|
63466c8a41 | ||
|
|
997806cad5 | ||
|
|
a5c3bec1fa | ||
|
|
ababaeaa40 | ||
|
|
9e2c462c09 | ||
|
|
d80b0f7cb5 | ||
|
|
03a090e3fa | ||
|
|
1aecbe45ea | ||
|
|
dd8d9aaee6 | ||
|
|
0ff434acce | ||
|
|
c0da9fe3a1 | ||
|
|
42aa1cc95f | ||
|
|
5a07192176 | ||
|
|
5477bf1a8c | ||
|
|
91fc911887 | ||
|
|
1e4efe0fb8 | ||
|
|
5372f7a813 | ||
|
|
7b7a81ec37 | ||
|
|
f0bffec1ef | ||
|
|
dae160df0b | ||
|
|
f79a5a3b68 | ||
|
|
51b6f7e41c | ||
|
|
9e75dcffa6 | ||
|
|
93c0afb069 | ||
|
|
6646c46d90 | ||
|
|
4b39657797 | ||
|
|
d9eec6d01f | ||
|
|
131c127eb9 | ||
|
|
4b527d16cb | ||
|
|
50ba7910a0 | ||
|
|
1de9f60d69 | ||
|
|
427c8df3e3 | ||
|
|
8321dcb44d | ||
|
|
feb1037758 | ||
|
|
b7a556a2b7 | ||
|
|
cc7564e1f8 | ||
|
|
4dad9fd40e | ||
|
|
9a3a5e8d52 | ||
|
|
96e51b83b1 | ||
|
|
835792147a | ||
|
|
cc112327ab | ||
|
|
3204acc748 | ||
|
|
3f2f202b28 | ||
|
|
1324a86e65 | ||
|
|
e59956db6a | ||
|
|
ad8f5d6944 | ||
|
|
59cd8376fe | ||
|
|
3584d9410d | ||
|
|
ab17acf66b | ||
|
|
5d969b8913 | ||
|
|
1ba3a2259e | ||
|
|
68c03d37c9 | ||
|
|
1169f3f043 | ||
|
|
2ab98edd41 | ||
|
|
ebcf446ad9 | ||
|
|
dd02ac1df1 | ||
|
|
4504595645 | ||
|
|
fbf6038a83 | ||
|
|
11cfa6679a | ||
|
|
e3688062aa | ||
|
|
ecbb96c04d | ||
|
|
e121e258ed | ||
|
|
7c25b5d622 | ||
|
|
542998e964 | ||
|
|
70c565cc2a | ||
|
|
fcb5200ad9 | ||
|
|
f854fa1b6c | ||
|
|
a15838f7af | ||
|
|
7405037f12 | ||
|
|
4299f31087 | ||
|
|
2a1665066e | ||
|
|
2da2dc3a03 | ||
|
|
4406c4464d | ||
|
|
838ae27f16 | ||
|
|
01ef763723 | ||
|
|
974684b58d | ||
|
|
7ed7423614 | ||
|
|
97d1a1e82a | ||
|
|
e872767998 | ||
|
|
b89726a15d | ||
|
|
bcf6e46585 | ||
|
|
a3aed2ab66 | ||
|
|
57fcb1a6d1 | ||
|
|
19b4b29ce7 | ||
|
|
547028bafd | ||
|
|
343dd2c518 | ||
|
|
d834221200 | ||
|
|
0fb5606341 | ||
|
|
0452a7403b | ||
|
|
90bf2749d3 | ||
|
|
3219571e48 | ||
|
|
b39dfa529a | ||
|
|
2fd83dba03 | ||
|
|
223e79b9c2 | ||
|
|
7faeda11f2 | ||
|
|
702230d6f4 | ||
|
|
3d9ec072e4 | ||
|
|
08cfa3d14b | ||
|
|
ab57a144aa | ||
|
|
22a045996c | ||
|
|
5c468e8170 | ||
|
|
3aed5bfd73 | ||
|
|
50554f3001 | ||
|
|
8464213a96 | ||
|
|
67397aeadf | ||
|
|
88bdcfe6ae | ||
|
|
8ca1361d47 | ||
|
|
af55313e5d | ||
|
|
a41e383e0e | ||
|
|
37f6d88370 | ||
|
|
e4003975d0 | ||
|
|
a36337cb42 | ||
|
|
90f2f3b309 | ||
|
|
7aba2a5695 | ||
|
|
271459ead8 | ||
|
|
b7c40b13a4 | ||
|
|
a024d632f4 | ||
|
|
14cd563b6e | ||
|
|
01bf8c50fa | ||
|
|
6da4c6ebe8 | ||
|
|
2d4d1dfc47 | ||
|
|
6c0cd33105 | ||
|
|
4371c14114 | ||
|
|
2cd7b7abcd | ||
|
|
cc84b518f2 | ||
|
|
92f2dc76e9 | ||
|
|
d8e8b17d23 | ||
|
|
60fe4437ba | ||
|
|
d149e62a5c | ||
|
|
3f85969803 | ||
|
|
6ccd85ae4a | ||
|
|
ef109213a2 | ||
|
|
7bd58dd39b | ||
|
|
f23bca761c | ||
|
|
b7e62695f1 | ||
|
|
af696da68c | ||
|
|
a23753148e | ||
|
|
4dcc7e5e1e | ||
|
|
f5aa70d869 | ||
|
|
b039849b2b | ||
|
|
fb2691764f | ||
|
|
5b3f0b8ada | ||
|
|
93d44f7c4d | ||
|
|
723ca9e4a8 | ||
|
|
f96d0a7e53 | ||
|
|
625145686a | ||
|
|
343445301b | ||
|
|
363af94d50 | ||
|
|
e7900c56c0 | ||
|
|
99eddd4aa4 | ||
|
|
60830ca5fb | ||
|
|
4ae6739cab | ||
|
|
df8f88c0d9 | ||
|
|
a1ec32c4c1 | ||
|
|
db76991217 | ||
|
|
1aef88e1a0 | ||
|
|
cfa1cac67a | ||
|
|
991a536af1 | ||
|
|
02cd081cf3 | ||
|
|
027dcf9071 | ||
|
|
f234621449 | ||
|
|
b04b0baa1c | ||
|
|
7a2a99379e | ||
|
|
7c676d4f30 | ||
|
|
756ba5c593 | ||
|
|
ca79b062e7 | ||
|
|
bd45dd3ceb | ||
|
|
70c663d859 | ||
|
|
a489f8cf49 | ||
|
|
e8056cd996 | ||
|
|
dd46aa0686 | ||
|
|
64d36c81b0 | ||
|
|
7d860ce9d0 | ||
|
|
d4ddb685b5 | ||
|
|
acd034425a | ||
|
|
c3c2469f6a | ||
|
|
14a0913f13 | ||
|
|
e4f959e109 | ||
|
|
3bf9bff940 | ||
|
|
2943d49d22 | ||
|
|
7ff73d789a | ||
|
|
2eb3558399 | ||
|
|
00b07b20f6 | ||
|
|
b56244edde | ||
|
|
31cd80ece1 | ||
|
|
da97a51e95 | ||
|
|
efcc142db0 | ||
|
|
f7e83b35b1 | ||
|
|
9e5b064bc0 | ||
|
|
2b82fc5785 | ||
|
|
e6da8a0bf0 | ||
|
|
a158877776 | ||
|
|
519a7fef26 | ||
|
|
dc657da1cb | ||
|
|
1825d9ea72 | ||
|
|
6126a40361 | ||
|
|
24f8cefc56 | ||
|
|
9213639b44 | ||
|
|
0fa32c79f1 | ||
|
|
44265e9d25 | ||
|
|
f475c78129 | ||
|
|
46588a1ef6 | ||
|
|
e32252fea4 | ||
|
|
ccf1f976ca | ||
|
|
0b5707fc97 | ||
|
|
d1d137319a | ||
|
|
0831ff0d70 | ||
|
|
8081a68505 | ||
|
|
ff08209ceb | ||
|
|
f43e43f8ad | ||
|
|
e00ef81d03 | ||
|
|
2a55b86213 | ||
|
|
29f9071f99 | ||
|
|
4bf5f38a96 | ||
|
|
4cb8315580 | ||
|
|
cb9ac33d3b | ||
|
|
478cd9f933 | ||
|
|
7bf69d33e0 | ||
|
|
e89dc0b721 | ||
|
|
c1badf210c | ||
|
|
0e7a277d82 | ||
|
|
7f43a53cf0 | ||
|
|
fb1c041353 | ||
|
|
030684868f | ||
|
|
38715c57cc | ||
|
|
c43bcc46d1 | ||
|
|
83f7cf0fd9 | ||
|
|
677473f773 | ||
|
|
a3fb318575 | ||
|
|
e71dba060f | ||
|
|
411f2ac8ea | ||
|
|
58b2ac5b0d | ||
|
|
9e7943aeb5 | ||
|
|
f8c015777c | ||
|
|
2b1efe414a |
@@ -76,8 +76,13 @@
|
||||
;;
|
||||
;; TODO -- these should all be made thread safe if possible or renamed so they end in `!`. Then we can remove them
|
||||
;; from this list because by default anything ending in `!` is considered to be thread-unsafe
|
||||
;;
|
||||
;; TODO (Cam 6/19/25) -- move this into the `test-helpers/config.edn` file so they can live with their friends.
|
||||
:parallel/unsafe
|
||||
#{clojure.core/alter-var-root
|
||||
#{java.util.Locale/setDefault
|
||||
java.lang.System/setProperty
|
||||
java.lang.System/setProperties
|
||||
clojure.core/alter-var-root
|
||||
clojure.core/with-redefs
|
||||
clojure.core/with-redefs-fn
|
||||
metabase.actions.test-util/with-actions
|
||||
@@ -96,7 +101,6 @@
|
||||
metabase.test.util/with-all-users-permission
|
||||
metabase.test.util/with-discarded-collections-perms-changes
|
||||
metabase.test.util/with-env-keys-renamed-by
|
||||
metabase.test.util/with-locale
|
||||
metabase.test.util/with-model-cleanup
|
||||
metabase.test.util/with-non-admin-groups-no-root-collection-for-namespace-perms
|
||||
metabase.test.util/with-non-admin-groups-no-root-collection-perms
|
||||
@@ -119,7 +123,6 @@
|
||||
metabase.test/with-fake-inbox
|
||||
metabase.test/with-group
|
||||
metabase.test/with-group-for-user
|
||||
metabase.test/with-locale
|
||||
metabase.test/with-log-level
|
||||
metabase.test/with-model-cleanup
|
||||
metabase.test/with-non-admin-groups-no-root-collection-for-namespace-perms
|
||||
@@ -232,6 +235,8 @@
|
||||
(metabase.driver.druid.query-processor-test/druid-query-returning-rows)
|
||||
(metabase.lib.util.match/match)
|
||||
(metabase.lib.util.match/match-one)
|
||||
(metabase.lib.util.match/match-lite)
|
||||
(metabase.lib.util.match/match-lite-recursive)
|
||||
(metabase.lib.util.match/replace)
|
||||
(metabase.lib.util.match/replace-in)
|
||||
(metabase.driver-api.core/match)
|
||||
@@ -287,7 +292,9 @@
|
||||
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.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"}}
|
||||
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"}
|
||||
toucan2.tools.debug/debug {:message "Don't commit code using t2/debug"}}
|
||||
|
||||
:discouraged-namespace
|
||||
{camel-snake-kebab.core {:message "CSK is not Turkish-safe, use the versions in metabase.util instead."}
|
||||
@@ -690,6 +697,8 @@ metabase-enterprise.content-translation.routes-test/with-new-secret-key!
|
||||
:name printable-namespaces}
|
||||
{:pattern "^metabase\\.(?:(?:lib)|(?:legacy-mbql))\\..*"
|
||||
:name metabase-lib}
|
||||
{:pattern "^metabase\\.lib\\..*"
|
||||
:name metabase-lib-excluding-legacy-mbql}
|
||||
;;
|
||||
;; QP source namespaces: `metabase.query-processor.*`, `metabase-enterprise.sandbox.query-processor.*`, and
|
||||
;; `metabase.driver.*`, excluding `-test` namespaces.
|
||||
@@ -770,6 +779,11 @@ metabase-enterprise.content-translation.routes-test/with-new-secret-key!
|
||||
toucan.util.test {:message "Don't use application database inside MLv2 code"}
|
||||
toucan2.core {:message "Don't use application database inside MLv2 code"}}}}
|
||||
|
||||
metabase-lib-excluding-legacy-mbql
|
||||
{:linters
|
||||
{:discouraged-var
|
||||
{metabase.legacy-mbql.util/unique-name-generator {:message "Use metabase.lib.util/unique-name-generator or non-truncating-unique-name-generator"}}}}
|
||||
|
||||
driver-namespaces
|
||||
{:linters
|
||||
{:discouraged-var
|
||||
|
||||
@@ -326,6 +326,7 @@
|
||||
driver
|
||||
events
|
||||
legacy-mbql
|
||||
lib-be
|
||||
models
|
||||
notification
|
||||
permissions
|
||||
@@ -573,15 +574,16 @@
|
||||
metabase.lib.core
|
||||
metabase.lib.equality
|
||||
metabase.lib.field
|
||||
metabase.lib.field.resolution
|
||||
metabase.lib.filter
|
||||
metabase.lib.ident
|
||||
metabase.lib.init
|
||||
metabase.lib.join.util
|
||||
metabase.lib.metadata
|
||||
metabase.lib.metadata.cached-provider
|
||||
metabase.lib.metadata.calculation
|
||||
metabase.lib.metadata.invocation-tracker
|
||||
metabase.lib.metadata.protocols
|
||||
metabase.lib.metadata.result-metadata
|
||||
metabase.lib.normalize
|
||||
metabase.lib.options
|
||||
metabase.lib.query
|
||||
@@ -594,6 +596,7 @@
|
||||
metabase.lib.schema.expression.window
|
||||
metabase.lib.schema.id
|
||||
metabase.lib.schema.info
|
||||
metabase.lib.schema.join
|
||||
metabase.lib.schema.literal
|
||||
metabase.lib.schema.metadata
|
||||
metabase.lib.schema.parameter
|
||||
@@ -755,17 +758,7 @@
|
||||
{:team "Admin Webapp"
|
||||
:api #{metabase.permissions.api
|
||||
metabase.permissions.core
|
||||
metabase.permissions.init
|
||||
;; TODO -- move these into the API namespace.
|
||||
metabase.permissions.models.application-permissions-revision
|
||||
metabase.permissions.models.collection-permission-graph-revision
|
||||
metabase.permissions.models.collection.graph
|
||||
metabase.permissions.models.data-permissions
|
||||
metabase.permissions.models.permissions
|
||||
metabase.permissions.models.permissions-group
|
||||
metabase.permissions.path
|
||||
metabase.permissions.util
|
||||
metabase.permissions.validation}
|
||||
metabase.permissions.init}
|
||||
:uses #{api
|
||||
app-db
|
||||
audit-app
|
||||
@@ -1252,6 +1245,14 @@
|
||||
models
|
||||
util}}
|
||||
|
||||
transform
|
||||
{:team "Semantic Layer"
|
||||
:api #{}
|
||||
:uses #{api
|
||||
lib
|
||||
models
|
||||
util}}
|
||||
|
||||
types
|
||||
{:team "Semantic Layer"
|
||||
:api #{metabase.types.core
|
||||
@@ -1355,6 +1356,7 @@
|
||||
metabase.warehouse-schema.metadata-from-qp
|
||||
metabase.warehouse-schema.metadata-queries
|
||||
metabase.warehouse-schema.models.field
|
||||
metabase.warehouse-schema.models.field-user-settings
|
||||
metabase.warehouse-schema.models.field-values
|
||||
metabase.warehouse-schema.models.table
|
||||
metabase.warehouse-schema.table}
|
||||
@@ -1593,6 +1595,7 @@
|
||||
:uses #{api
|
||||
config
|
||||
database-routing
|
||||
driver
|
||||
events
|
||||
lib
|
||||
models
|
||||
@@ -1663,6 +1666,7 @@
|
||||
app-db
|
||||
collections
|
||||
config
|
||||
driver
|
||||
legacy-mbql
|
||||
lib
|
||||
lib-be
|
||||
@@ -1672,12 +1676,23 @@
|
||||
pulse
|
||||
query-processor
|
||||
request
|
||||
server
|
||||
settings
|
||||
system
|
||||
users
|
||||
util
|
||||
warehouse-schema}}
|
||||
|
||||
enterprise/permission-debug
|
||||
{:team "Admin Webapp"
|
||||
:api #{metabase-enterprise.permission-debug.api}
|
||||
:uses #{api
|
||||
lib
|
||||
models
|
||||
permissions
|
||||
query-processor
|
||||
util}}
|
||||
|
||||
enterprise/premium-features
|
||||
{:team "Admin Webapp"
|
||||
:api #{}
|
||||
|
||||
@@ -120,6 +120,10 @@
|
||||
metabase.collections.models.collection-test/with-personal-and-impersonal-collections [[:block 1]]
|
||||
metabase.config/build-type-case [[:block 0]]
|
||||
metabase.dashboards.models.dashboard-test/with-dash-in-collection [[:inner 0]]
|
||||
metabase.driver-api.core/match [[:inner 0]]
|
||||
metabase.driver-api.core/match-one [[:inner 0]]
|
||||
metabase.driver-api.core/replace [[:inner 0]]
|
||||
metabase.driver-api.core/replace-in [[:inner 0]]
|
||||
metabase.driver.bigquery-cloud-sdk.query-processor/with-temporal-type [[:default]]
|
||||
metabase.driver.druid.client/DELETE [[:default]]
|
||||
metabase.driver.druid.client/GET [[:default]]
|
||||
@@ -151,6 +155,8 @@
|
||||
metabase.lib.test-util.macros/mbql-query [[:inner 0]]
|
||||
metabase.lib.util.match/match [[:inner 0]]
|
||||
metabase.lib.util.match/match-one [[:inner 0]]
|
||||
metabase.lib.util.match/match-lite [[:inner 0]]
|
||||
metabase.lib.util.match/match-lite-recursive [[:inner 0]]
|
||||
metabase.lib.util.match/replace [[:inner 0]]
|
||||
metabase.lib.util.match/replace-in [[:inner 0]]
|
||||
metabase.models.interface/define-batched-hydration-method [[:inner 0]]
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
name: Cross-branch migration test
|
||||
|
||||
inputs:
|
||||
base-ref:
|
||||
base-ref: ## Base branch PR came from
|
||||
required: true
|
||||
head-ref: ## Source branch of the pull request
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
## First we deploy the base branch
|
||||
- name: Check out base branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -39,10 +42,11 @@ runs:
|
||||
run: kill $(cat metabase_pid)
|
||||
shell: bash
|
||||
|
||||
## Then we deploy the PR branch to ensure it migrates up successfully
|
||||
- name: Check out pull request branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
ref: ${{ inputs.head-ref }}
|
||||
|
||||
- name: Run backend on pull request branch
|
||||
run: |
|
||||
@@ -65,3 +69,38 @@ runs:
|
||||
- name: Stop Metabase on pull request branch
|
||||
run: kill $(cat metabase_pid)
|
||||
shell: bash
|
||||
|
||||
## Testing that originally deploying this PR allows you to roll back to a previous release
|
||||
## Reset the checksums so when we go back to the base branch, it's as if the PR branch was what was originally deployed
|
||||
- name: Reset the checksums as if the PR branch was what was originally deployed
|
||||
run: |
|
||||
clojure -M:dev:ee:migrate reset-checksums
|
||||
shell: bash
|
||||
|
||||
- name: Rollback the last deployment
|
||||
run: |
|
||||
clojure -M:dev:ee:migrate rollback last-deployment
|
||||
shell: bash
|
||||
|
||||
- name: Re-check out base branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.base-ref }}
|
||||
|
||||
- name: Re-run backend on base branch
|
||||
run: |
|
||||
clojure -M:run:ee > metabase.log 2>&1 & echo $! > metabase_pid
|
||||
tail -F metabase.log &
|
||||
shell: bash
|
||||
|
||||
- name: Wait for Metabase to start
|
||||
run: |
|
||||
while ! curl -s 'http://localhost:3000/api/health' | grep '{"status":"ok"}' > /dev/null; do
|
||||
if ! kill -0 $(cat metabase_pid) 2>/dev/null; then
|
||||
cat metabase.log
|
||||
echo "Metabase process has exited."
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
shell: bash
|
||||
|
||||
@@ -31,6 +31,10 @@ inputs:
|
||||
description: Webhook tester container
|
||||
required: false
|
||||
default: false
|
||||
snowplow:
|
||||
description: Snowplow micro container
|
||||
required: false
|
||||
default: false
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
@@ -42,56 +46,62 @@ runs:
|
||||
password: ${{ inputs.password }}
|
||||
|
||||
- name: Start Containers
|
||||
run: |
|
||||
shell: bash
|
||||
run: | # bash
|
||||
Y='\033[33m'
|
||||
G='\033[1;32m'
|
||||
|
||||
cd e2e/test/scenarios/
|
||||
|
||||
docker compose up \
|
||||
$([ ${{ inputs.postgres }} = true ] && echo "postgres-sample") \
|
||||
$([ ${{ inputs.mysql }} = true ] && echo "mysql-sample") \
|
||||
$([ ${{ inputs.mongo }} = true ] && echo "mongo-sample") \
|
||||
$([ ${{ inputs.maildev }} = true ] && echo "maildev") \
|
||||
$([ ${{ inputs.openldap }} = true ] && echo "ldap") \
|
||||
$([ ${{ inputs.webhook }} = true ] && echo "webhook-tester") \
|
||||
$([ ${{ inputs.snowplow }} = true ] && echo "snowplow-micro") \
|
||||
-d
|
||||
|
||||
if ${{ inputs.maildev }}; then
|
||||
echo -e "${Y}Starting maildev container..." &&
|
||||
docker run -d -p 1080:1080 -p 1025:1025 maildev/maildev:2.0.5 &&
|
||||
echo -e "${Y}checking maildev container..." &&
|
||||
while ! nc -z localhost 1080; do sleep 1; done &&
|
||||
while ! nc -z localhost 1025; do sleep 1; done &&
|
||||
echo -e "${G}Maildev is up and running!"
|
||||
fi
|
||||
|
||||
if ${{ inputs.openldap }}; then
|
||||
echo -e "${Y}Starting openldap container..." &&
|
||||
docker run -d -p 389:389 \
|
||||
--env LDAP_ADMIN_PASSWORD=adminpass \
|
||||
--env LDAP_USERS=user01@example.org,user02@example.org \
|
||||
--env LDAP_PASSWORDS=123456,123465 \
|
||||
--env LDAP_ROOT=dc=example,dc=org \
|
||||
--env LDAP_PORT_NUMBER=389 \
|
||||
bitnami/openldap:2.6.4 &&
|
||||
echo -e "${Y}checking openldap container..." &&
|
||||
while ! nc -z localhost 389; do sleep 1; done &&
|
||||
echo -e "${G}Openldap is up and running!"
|
||||
fi
|
||||
|
||||
if ${{ inputs.postgres }}; then
|
||||
echo -e "${Y}Starting postgres container..." &&
|
||||
docker run -d -p 5404:5432 -e TZ='US/Pacific' metabase/qa-databases:postgres-sample-12 &&
|
||||
echo -e "${Y}checking postgres container..." &&
|
||||
while ! nc -z localhost 5404; do sleep 1; done &&
|
||||
echo -e "${G}Postgres is up and running!"
|
||||
fi
|
||||
|
||||
if ${{ inputs.mysql }}; then
|
||||
echo -e "${Y}Starting mysql container..." &&
|
||||
docker run -d -p 3304:3306 -e TZ='US/Pacific' metabase/qa-databases:mysql-sample-8 &&
|
||||
echo -e "${Y}checking mysql container..." &&
|
||||
while ! nc -z localhost 3304; do sleep 1; done &&
|
||||
echo -e "${G}MySQL is up and running!"
|
||||
fi
|
||||
|
||||
if ${{ inputs.mongo }}; then
|
||||
echo -e "${Y}Starting mongo container..." &&
|
||||
docker run -d -p 27004:27017 metabase/qa-databases:mongo-sample-4.4 &&
|
||||
echo -e "${Y}checking mongo container..." &&
|
||||
while ! nc -z localhost 27004; do sleep 1; done &&
|
||||
echo -e "${G}Mongo is up and running!"
|
||||
fi
|
||||
|
||||
if ${{ inputs.webhook }}; then
|
||||
echo -e "${Y}Starting webhook test container..." &&
|
||||
docker run -d -p 9080:8080/tcp tarampampam/webhook-tester:1.1.0 serve --create-session 00000000-0000-0000-0000-000000000000 &&
|
||||
echo -e "${Y}checking webhook test container..." &&
|
||||
while ! nc -z localhost 9080; do sleep 1; done &&
|
||||
echo -e "${G}Webhook tester is up and running!"
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
if ${{ inputs.snowplow }}; then
|
||||
echo -e "${Y}checking snowplow micro container..." &&
|
||||
while ! nc -z localhost 9090; do sleep 1; done &&
|
||||
echo -e "${G}Snowplow micro is up and running!"
|
||||
fi
|
||||
|
||||
13
.github/actions/run-snowplow-micro/action.yml
vendored
@@ -1,13 +0,0 @@
|
||||
name: Run Snowplow micro
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Download Snowplow micro JAR
|
||||
run: curl -L -o snowplow-micro.jar https://github.com/snowplow-incubator/snowplow-micro/releases/download/micro-1.2.1/snowplow-micro-1.2.1.jar
|
||||
shell: bash
|
||||
- name: Launch Snowplow micro
|
||||
run: java -cp snowplow-micro.jar:snowplow com.snowplowanalytics.snowplow.micro.Main --collector-config snowplow/micro.conf --iglu snowplow/iglu.json &
|
||||
shell: bash
|
||||
- name: Wait until Snowplow micro is ready
|
||||
run: while ! curl -s 'http://localhost:9090' | grep '404'; do sleep 1; done
|
||||
shell: bash
|
||||
38
.github/file-paths.yaml
vendored
@@ -16,10 +16,12 @@ frontend_ci: &frontend_ci
|
||||
- ".github/actions/prepare-backend/**"
|
||||
- ".github/workflows/frontend.yml"
|
||||
|
||||
frontend_sources: &frontend_sources
|
||||
- *shared_sources
|
||||
- "enterprise/frontend/!(test)**/**/{!(*.spec),}.{js,jsx,ts,tsx,css}"
|
||||
- "frontend/!(test)**/**/{!(*.spec),}.{js,jsx,ts,tsx,css}"
|
||||
frontend_embedding_sdk_ci: &frontend_embedding_sdk_ci
|
||||
- ".github/actions/prepare-frontend/**"
|
||||
- ".github/actions/prepare-backend/**"
|
||||
- ".github/workflows/*embedding-sdk*.yml"
|
||||
|
||||
frontend_configs: &frontend_configs
|
||||
- "yarn.lock"
|
||||
- "**/tsconfig*.json"
|
||||
- "package.json"
|
||||
@@ -32,8 +34,15 @@ frontend_sources: &frontend_sources
|
||||
- "webpack.static-viz.config.js"
|
||||
- ".nvmrc"
|
||||
|
||||
frontend_sources: &frontend_sources
|
||||
- *shared_sources
|
||||
- *frontend_configs
|
||||
- "enterprise/frontend/!(test)**/**/{!(*.spec),}.{js,jsx,ts,tsx,css}"
|
||||
- "frontend/!(test)**/**/{!(*.spec),}.{js,jsx,ts,tsx,css}"
|
||||
|
||||
frontend_embedding_sdk_sources:
|
||||
- *frontend_sources
|
||||
- *frontend_configs
|
||||
- "enterprise/frontend/!(test)**/**/{!(*.spec),}.{js,jsx,ts,tsx,css}"
|
||||
|
||||
frontend_specs: &frontend_specs
|
||||
- *shared_specs
|
||||
@@ -105,25 +114,27 @@ e2e_ci: &e2e_ci
|
||||
- ".github/actions/prepare-uberjar-artifact/**"
|
||||
- ".github/actions/e2e-prepare-containers/**"
|
||||
- ".github/actions/prepare-cypress/**"
|
||||
- ".github/actions/run-snowplow-micro/**"
|
||||
- ".github/workflows/e2e-*"
|
||||
|
||||
e2e_specs: &e2e_specs
|
||||
- "**/*.cy.*.js"
|
||||
- "**/*.cy.*.ts"
|
||||
- e2e/!(test-host-app)**/*.cy.*.{js,ts}
|
||||
|
||||
e2e_cross_version: &e2e_cross_version
|
||||
- ".github/workflows/e2e-cross-version.yml"
|
||||
- "e2e/test/scenarios/cross-version/**"
|
||||
|
||||
e2e_embedding_sdk:
|
||||
- *frontend_embedding_sdk_ci
|
||||
- *sources
|
||||
- "e2e/component/**/*.cy.*.{js,ts}"
|
||||
|
||||
e2e_embedding_sdk_compatibility:
|
||||
- *default
|
||||
- *e2e_ci
|
||||
- *frontend_embedding_sdk_ci
|
||||
- *frontend_sources
|
||||
- "e2e/embedding-sdk-host-apps/**"
|
||||
- "e2e/runner/embedding-sdk/**"
|
||||
- "e2e/runner/test-host-app/**/*.cy.*.js"
|
||||
- "e2e/runner/test-host-app/**/*.cy.*.ts"
|
||||
- "e2e/test-host-app/**/*.cy.*.{js,ts}"
|
||||
|
||||
e2e_all:
|
||||
- *default
|
||||
@@ -137,10 +148,13 @@ snowplow:
|
||||
- "snowplow/**"
|
||||
|
||||
documentation:
|
||||
- ".typedoc/**"
|
||||
- "docs/**"
|
||||
- "**/*.md"
|
||||
|
||||
embedding_documentation:
|
||||
- ".typedoc/**"
|
||||
- "docs/embedding/**"
|
||||
|
||||
yaml:
|
||||
- "**/*.yml"
|
||||
- "**/*.yaml"
|
||||
|
||||
405
.github/workflows/app-db.yml
vendored
Normal file
@@ -0,0 +1,405 @@
|
||||
name: App DB Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
skip:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}-app-db
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
be-tests-mariadb:
|
||||
if: ${{ !inputs.skip }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version:
|
||||
- name: MariaDB 10.2
|
||||
junit-name: be-tests-mariadb-10-2-ee
|
||||
image: circleci/mariadb:10.2.23
|
||||
env:
|
||||
enable-ssl-tests: 'false'
|
||||
- name: MariaDB Latest
|
||||
junit-name: be-tests-mariadb-latest-ee
|
||||
image: circleci/mariadb:latest
|
||||
env:
|
||||
enable-ssl-tests: 'false'
|
||||
job:
|
||||
- name: Enterprise Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only '"enterprise/backend/test"'
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 1)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:partition/total 2
|
||||
:partition/index 0
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 2)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:partition/total 2
|
||||
:partition/index 1
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: ${{ matrix.version.image }}
|
||||
ports:
|
||||
- "3306:3306"
|
||||
env:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: true
|
||||
MYSQL_DATABASE: circle_test
|
||||
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'
|
||||
}}
|
||||
# actual serious env vars below
|
||||
CI: 'true'
|
||||
DRIVERS: mysql
|
||||
MB_DB_TYPE: mysql
|
||||
MB_DB_HOST: localhost
|
||||
MB_DB_PORT: 3306
|
||||
MB_DB_DBNAME: circle_test
|
||||
MB_DB_USER: root
|
||||
MB_MYSQL_TEST_USER: root
|
||||
#
|
||||
# SSL config: only for mysql latest tests.
|
||||
#
|
||||
# set up env vars for something named "MYSQL_SSL" to run MySQL SSL tests verifying connectivity with PEM cert
|
||||
# they are deliberately given a different name to prevent them from affecting the regular test run against
|
||||
# the configured MySQL instance, but there is one particular test (mysql-connect-with-ssl-and-pem-cert-test)
|
||||
# that overrides the MB_MYSQL_TEST_* values with them
|
||||
# the MYSQL_RDS_SSL_INSTANCE vars are defined as secrets and can be altered
|
||||
MB_MYSQL_SSL_TEST_SSL: ${{ matrix.version.env.enable-ssl-tests }}
|
||||
MB_MYSQL_SSL_TEST_HOST: ${{ secrets.MYSQL_RDS_SSL_INSTANCE_HOST }}
|
||||
MB_MYSQL_SSL_TEST_ADDITIONAL_OPTIONS: 'verifyServerCertificate=true'
|
||||
# the contents of the ./resources/certificates/rds-combined-ca-bundle.pem file
|
||||
MB_MYSQL_SSL_TEST_SSL_CERT: ${{ secrets.MB_MYSQL_SSL_TEST_SSL_CERT }}
|
||||
MB_MYSQL_SSL_TEST_USER: metabase
|
||||
MB_MYSQL_SSL_TEST_PASSWORD: ${{ secrets.MYSQL_RDS_SSL_INSTANCE_PASSWORD }}
|
||||
# for historic reasons (I don't want to mess around with required jobs) the job name should be something like
|
||||
# "be-tests-mariadb-10-2-ee (0)"
|
||||
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
|
||||
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 }}
|
||||
|
||||
be-tests-mysql:
|
||||
if: ${{ !inputs.skip }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version:
|
||||
- name: MySQL 8.0
|
||||
junit-name: be-tests-mysql-8-0-ee
|
||||
image: cimg/mysql:8.0
|
||||
env:
|
||||
enable-ssl-tests: 'false'
|
||||
- name: MySQL Latest
|
||||
junit-name: be-tests-mysql-latest-ee
|
||||
image: mysql:latest
|
||||
env:
|
||||
enable-ssl-tests: 'true'
|
||||
job:
|
||||
- name: Enterprise Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only '"enterprise/backend/test"'
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 1)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:partition/total 2
|
||||
:partition/index 0
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 2)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:partition/total 2
|
||||
:partition/index 1
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: ${{ matrix.version.image }}
|
||||
ports:
|
||||
- "3306:3306"
|
||||
env:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: true
|
||||
MYSQL_DATABASE: circle_test
|
||||
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'
|
||||
}}
|
||||
# actual serious env vars below
|
||||
CI: 'true'
|
||||
DRIVERS: mysql
|
||||
MB_DB_TYPE: mysql
|
||||
MB_DB_HOST: localhost
|
||||
MB_DB_PORT: 3306
|
||||
MB_DB_DBNAME: circle_test
|
||||
MB_DB_USER: root
|
||||
MB_MYSQL_TEST_USER: root
|
||||
#
|
||||
# SSL config: only for mysql latest tests.
|
||||
#
|
||||
# set up env vars for something named "MYSQL_SSL" to run MySQL SSL tests verifying connectivity with PEM cert
|
||||
# they are deliberately given a different name to prevent them from affecting the regular test run against
|
||||
# the configured MySQL instance, but there is one particular test (mysql-connect-with-ssl-and-pem-cert-test)
|
||||
# that overrides the MB_MYSQL_TEST_* values with them
|
||||
# the MYSQL_RDS_SSL_INSTANCE vars are defined as secrets and can be altered
|
||||
MB_MYSQL_SSL_TEST_SSL: ${{ matrix.version.env.enable-ssl-tests }}
|
||||
MB_MYSQL_SSL_TEST_HOST: ${{ secrets.MYSQL_RDS_SSL_INSTANCE_HOST }}
|
||||
MB_MYSQL_SSL_TEST_ADDITIONAL_OPTIONS: 'verifyServerCertificate=true'
|
||||
# the contents of the ./resources/certificates/rds-combined-ca-bundle.pem file
|
||||
MB_MYSQL_SSL_TEST_SSL_CERT: ${{ secrets.MB_MYSQL_SSL_TEST_SSL_CERT }}
|
||||
MB_MYSQL_SSL_TEST_USER: metabase
|
||||
MB_MYSQL_SSL_TEST_PASSWORD: ${{ secrets.MYSQL_RDS_SSL_INSTANCE_PASSWORD }}
|
||||
# for historic reasons (I don't want to mess around with required jobs) the job name should be something like
|
||||
# "be-tests-mariadb-10-2-ee (0)"
|
||||
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
|
||||
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 }}
|
||||
|
||||
be-tests-postgres:
|
||||
if: ${{ !inputs.skip }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version:
|
||||
- name: Postgres 12.x
|
||||
junit-name: postgres-ee
|
||||
docker-image: postgres:12-alpine
|
||||
env:
|
||||
enable-ssl-tests: 'false'
|
||||
- name: Postgres Latest
|
||||
junit-name: postgres-latest-ee
|
||||
docker-image: postgres:latest
|
||||
env:
|
||||
enable-ssl-tests: 'true'
|
||||
job:
|
||||
- name: Driver Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only-tags [:mb/driver-tests]
|
||||
- name: Enterprise Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only '"enterprise/backend/test"'
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 1)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:exclude-tags [:mb/driver-tests]
|
||||
:partition/total 2
|
||||
:partition/index 0
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 2)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:partition/total 2
|
||||
:partition/index 1
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
|
||||
env:
|
||||
# Only run old migrations tests on pushes to master or release branches. All other branches should skip tests
|
||||
# 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'
|
||||
}}
|
||||
# actual serious env vars below
|
||||
CI: 'true'
|
||||
DRIVERS: postgres
|
||||
MB_DB_TYPE: postgres
|
||||
MB_DB_PORT: 5432
|
||||
MB_DB_HOST: localhost
|
||||
MB_DB_DBNAME: mb_test
|
||||
MB_DB_USER: mb_test
|
||||
MB_POSTGRESQL_TEST_USER: mb_test
|
||||
# SSL tests are only enabled for the postgres-latest job.
|
||||
MB_POSTGRES_SSL_TEST_SSL: ${{ matrix.version.env.enable-ssl-tests }}
|
||||
MB_POSTGRES_SSL_TEST_SSL_MODE: verify-full
|
||||
MB_POSTGRES_SSL_TEST_SSL_ROOT_CERT_PATH: 'test-resources/certificates/us-east-2-bundle.pem'
|
||||
services:
|
||||
postgres:
|
||||
image: ${{ matrix.version.docker-image }}
|
||||
ports:
|
||||
- "5432:5432"
|
||||
env:
|
||||
POSTGRES_USER: mb_test
|
||||
POSTGRES_DB: mb_test
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test ${{ matrix.version.name }} (${{ matrix.job.name }})
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
build-static-viz: ${{ matrix.job.build-static-viz }}
|
||||
junit-name: 'be-tests-${{ 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 }}
|
||||
|
||||
app-db-tests-result:
|
||||
needs:
|
||||
- be-tests-mariadb
|
||||
- be-tests-mysql
|
||||
- be-tests-postgres
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
name: app-db-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 app db 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("App db 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);
|
||||
49
.github/workflows/cross-branch-migrations.yml
vendored
@@ -5,6 +5,19 @@ on:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
paths:
|
||||
- "resources/migrations/**"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
base-ref:
|
||||
description: 'Base reference for the migration test'
|
||||
required: true
|
||||
type: string
|
||||
head-ref:
|
||||
description: 'Head reference for the migration test'
|
||||
required: true
|
||||
type: string
|
||||
env:
|
||||
BASE_REF: ${{ inputs.base-ref || github.base_ref }}
|
||||
HEAD_REF: ${{ inputs.head-ref || github.head_ref }}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}
|
||||
@@ -13,19 +26,21 @@ concurrency:
|
||||
jobs:
|
||||
migrations-h2-ee:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CI: 'true'
|
||||
MB_DB_TYPE: h2
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/cross-branch-migration-test
|
||||
with:
|
||||
base-ref: ${{ github.base_ref }}
|
||||
base-ref: ${{ env.BASE_REF }}
|
||||
head-ref: ${{ env.HEAD_REF }}
|
||||
|
||||
migrations-postgres-12-ee:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CI: 'true'
|
||||
MB_DB_TYPE: postgres
|
||||
@@ -46,11 +61,12 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/cross-branch-migration-test
|
||||
with:
|
||||
base-ref: ${{ github.base_ref }}
|
||||
base-ref: ${{ env.BASE_REF }}
|
||||
head-ref: ${{ env.HEAD_REF }}
|
||||
|
||||
migrations-postgres-latest-ee:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CI: 'true'
|
||||
MB_DB_TYPE: postgres
|
||||
@@ -71,11 +87,12 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/cross-branch-migration-test
|
||||
with:
|
||||
base-ref: ${{ github.base_ref }}
|
||||
base-ref: ${{ env.BASE_REF }}
|
||||
head-ref: ${{ env.HEAD_REF }}
|
||||
|
||||
migrations-mysql-8-0-ee:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CI: 'true'
|
||||
MB_DB_TYPE: mysql
|
||||
@@ -92,11 +109,12 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/cross-branch-migration-test
|
||||
with:
|
||||
base-ref: ${{ github.base_ref }}
|
||||
base-ref: ${{ env.BASE_REF }}
|
||||
head-ref: ${{ env.HEAD_REF }}
|
||||
|
||||
migrations-mysql-latest-ee:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CI: 'true'
|
||||
MB_DB_TYPE: mysql
|
||||
@@ -117,11 +135,12 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/cross-branch-migration-test
|
||||
with:
|
||||
base-ref: ${{ github.base_ref }}
|
||||
base-ref: ${{ env.BASE_REF }}
|
||||
head-ref: ${{ env.HEAD_REF }}
|
||||
|
||||
migrations-mariadb-10-2-ee:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CI: 'true'
|
||||
MB_DB_TYPE: mysql
|
||||
@@ -138,11 +157,12 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/cross-branch-migration-test
|
||||
with:
|
||||
base-ref: ${{ github.base_ref }}
|
||||
base-ref: ${{ env.BASE_REF }}
|
||||
head-ref: ${{ env.HEAD_REF }}
|
||||
|
||||
migrations-mariadb-latest-ee:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CI: 'true'
|
||||
MB_DB_TYPE: mysql
|
||||
@@ -159,4 +179,5 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/cross-branch-migration-test
|
||||
with:
|
||||
base-ref: ${{ github.base_ref }}
|
||||
base-ref: ${{ env.BASE_REF }}
|
||||
head-ref: ${{ env.HEAD_REF }}
|
||||
|
||||
11
.github/workflows/docs_bump_detected.yml
vendored
@@ -18,10 +18,15 @@ jobs:
|
||||
env:
|
||||
SOURCE_BRANCH: ${{ github.head_ref || github.ref }}
|
||||
TARGET_BRANCH: ${{ github.event.pull_request.base.ref }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
steps:
|
||||
- name: Report changed docs files exist
|
||||
run: |
|
||||
echo "A change in the docs directory was detected."
|
||||
echo "A PR with changes in the docs directory was detected."
|
||||
echo "Sending workflow trigger to create/update the corresponding PR in docs repo."
|
||||
echo "source branch: $SOURCE_BRANCH"
|
||||
echo "target branch: $TARGET_BRANCH"
|
||||
echo "pr number: $PR_NUMBER"
|
||||
|
||||
- name: Trigger repo dispatch
|
||||
uses: actions/github-script@v7
|
||||
@@ -33,5 +38,7 @@ jobs:
|
||||
repo: "docs.metabase.github.io",
|
||||
event_type: "docs_update",
|
||||
client_payload: {
|
||||
dispatch_type: "docs_update",
|
||||
source_branch: process.env.SOURCE_BRANCH,
|
||||
target_branch: process.env.TARGET_BRANCH}});
|
||||
target_branch: process.env.TARGET_BRANCH,
|
||||
pr_number: process.env.PR_NUMBER}});
|
||||
|
||||
43
.github/workflows/docs_close_detected.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Docs Close Detected
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
branches:
|
||||
- 'master'
|
||||
- 'release-x.[0-9]+.x'
|
||||
paths:
|
||||
- 'docs/**'
|
||||
|
||||
jobs:
|
||||
push_and_merge_workflow_to_docs_metabase_github_io_job:
|
||||
if: github.event.pull_request.merged == false
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SOURCE_BRANCH: ${{ github.head_ref || github.ref }}
|
||||
TARGET_BRANCH: ${{ github.event.pull_request.base.ref }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
steps:
|
||||
- name: Report changed docs files exist
|
||||
run: |
|
||||
echo "A PR with changes to the docs directory was closed."
|
||||
echo "Sending workflow trigger to close corresponding PR in docs repo."
|
||||
echo "source branch: $SOURCE_BRANCH"
|
||||
echo "target branch: $TARGET_BRANCH"
|
||||
echo "pr number: $PR_NUMBER"
|
||||
|
||||
- name: Trigger repo dispatch
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
|
||||
script: | #js
|
||||
github.rest.repos.createDispatchEvent({
|
||||
owner: "${{ github.repository_owner }}",
|
||||
repo: "docs.metabase.github.io",
|
||||
event_type: "docs_close",
|
||||
client_payload: {
|
||||
dispatch_type: "docs_close",
|
||||
source_branch: process.env.SOURCE_BRANCH,
|
||||
target_branch: process.env.TARGET_BRANCH,
|
||||
pr_number: process.env.PR_NUMBER}});
|
||||
9
.github/workflows/docs_merge_detected.yml
vendored
@@ -17,10 +17,15 @@ jobs:
|
||||
env:
|
||||
SOURCE_BRANCH: ${{ github.head_ref || github.ref }}
|
||||
TARGET_BRANCH: ${{ github.event.pull_request.base.ref }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
steps:
|
||||
- name: Report changed docs files exist
|
||||
run: |
|
||||
echo "A PR with changes to the docs directory was merged."
|
||||
echo "Sending workflow trigger to merge corresponding PR in docs repo."
|
||||
echo "source branch: $SOURCE_BRANCH"
|
||||
echo "target branch: $TARGET_BRANCH"
|
||||
echo "pr number: $PR_NUMBER"
|
||||
|
||||
- name: Trigger repo dispatch
|
||||
uses: actions/github-script@v7
|
||||
@@ -32,5 +37,7 @@ jobs:
|
||||
repo: "docs.metabase.github.io",
|
||||
event_type: "docs_merge",
|
||||
client_payload: {
|
||||
dispatch_type: "docs_merge",
|
||||
source_branch: process.env.SOURCE_BRANCH,
|
||||
target_branch: process.env.TARGET_BRANCH}});
|
||||
target_branch: process.env.TARGET_BRANCH,
|
||||
pr_number: process.env.PR_NUMBER}});
|
||||
|
||||
119
.github/workflows/drivers.yml
vendored
@@ -12,8 +12,38 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# This job will determine if the tier 3 driver tests should be skipped.
|
||||
# It will always run first.
|
||||
determine-driver-skips:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
skip: ${{ steps.check_team_and_branch.outputs.skip }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Check if tier3 drivers should run
|
||||
id: check_team_and_branch
|
||||
run: |
|
||||
IS_MASTER_OR_RELEASE="${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/release-') }}"
|
||||
HAS_TEAM_LABEL="${{ contains(github.event.pull_request.labels.*.name, '.Team/Drivers') || contains(github.event.pull_request.labels.*.name, '.Team/Querying') || contains(github.event.pull_request.labels.*.name, '.Team/SemanticLayer') }}"
|
||||
|
||||
|
||||
echo "Is master or release: ${IS_MASTER_OR_RELEASE}"
|
||||
echo "Has '.Team/Drivers' or '.Team/Querying' or '.Team/SemanticLayer' label: ${HAS_TEAM_LABEL}"
|
||||
if [[ "${IS_MASTER_OR_RELEASE}" == "true" ]]; then
|
||||
echo "skip=false" >> $GITHUB_OUTPUT
|
||||
echo "Merging into master or a release branch. Tier 3 driver tests will run."
|
||||
elif [[ "${HAS_TEAM_LABEL}" == "true" ]]; then
|
||||
echo "skip=false" >> $GITHUB_OUTPUT
|
||||
echo "A relevant team label is present. Tier 3 driver tests will run."
|
||||
else
|
||||
echo "skip=true" >> $GITHUB_OUTPUT
|
||||
echo "Not labeled with required team and not merging into master/release. Tier 3 driver tests will be skipped."
|
||||
fi
|
||||
shell: bash
|
||||
be-tests-athena-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -129,7 +159,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-druid-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -164,7 +195,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-druid-jdbc-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -199,7 +231,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-databricks-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -233,7 +266,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-databricks-multi-catalog-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -314,7 +348,7 @@ jobs:
|
||||
enable-ssl-tests: 'false'
|
||||
- name: MySQL 8.0
|
||||
junit-name: be-tests-mysql-8-0-ee
|
||||
image: cimg/mysql:8.0
|
||||
image: mysql:8.0
|
||||
env:
|
||||
enable-ssl-tests: 'false'
|
||||
- name: MySQL Latest
|
||||
@@ -324,28 +358,8 @@ jobs:
|
||||
enable-ssl-tests: 'true'
|
||||
job:
|
||||
- name: Driver Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only-tags [:mb/driver-tests]
|
||||
- name: Enterprise Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only '"enterprise/backend/test"'
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 1)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:partition/total 2
|
||||
:partition/index 0
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 2)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:partition/total 2
|
||||
:partition/index 1
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
|
||||
services:
|
||||
mysql:
|
||||
@@ -403,7 +417,6 @@ jobs:
|
||||
- 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 }}
|
||||
@@ -421,7 +434,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-mongo:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
@@ -470,7 +484,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-mongo-ssl:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
@@ -534,7 +549,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-mongo-sharded-cluster-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -567,7 +583,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-oracle:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
@@ -657,29 +674,8 @@ jobs:
|
||||
enable-ssl-tests: 'true'
|
||||
job:
|
||||
- name: Driver Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only-tags [:mb/driver-tests]
|
||||
- name: Enterprise Tests
|
||||
build-static-viz: false
|
||||
test-args: >-
|
||||
:only '"enterprise/backend/test"'
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 1)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:exclude-tags [:mb/driver-tests]
|
||||
:partition/total 2
|
||||
:partition/index 0
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
- name: EE App DB Tests (Part 2)
|
||||
build-static-viz: true
|
||||
test-args: >-
|
||||
:only '"test"'
|
||||
:partition/total 2
|
||||
:partition/index 1
|
||||
exclude-tag: ':mb/driver-tests'
|
||||
name: "${{ matrix.version.name }} ${{ matrix.job.name }}"
|
||||
env:
|
||||
# Only run old migrations tests on pushes to master or release branches. All other branches should skip tests
|
||||
@@ -724,7 +720,6 @@ jobs:
|
||||
- name: Test ${{ matrix.version.name }} (${{ matrix.job.name }})
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
build-static-viz: ${{ matrix.job.build-static-viz }}
|
||||
junit-name: 'be-tests-${{ matrix.version.junit-name }}'
|
||||
test-args: >-
|
||||
${{ matrix.job.test-args }}
|
||||
@@ -742,7 +737,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-presto-jdbc-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -898,7 +894,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-sparksql-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -931,7 +928,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-sqlite-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -959,7 +957,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-sqlserver:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
@@ -1009,7 +1008,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-starburst-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
@@ -1046,7 +1046,8 @@ jobs:
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-vertica-ee:
|
||||
if: ${{ !inputs.skip }}
|
||||
needs: determine-driver-skips
|
||||
if: ${{ !inputs.skip && !(needs.determine-driver-skips.outputs.skip == 'true') }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
|
||||
@@ -128,8 +128,10 @@ jobs:
|
||||
DISPLAY: ""
|
||||
# Any env starting with `CYPRESS_` will be available to all Cypress tests via `Cypress.env()`
|
||||
# Example: you can get `CYPRESS_FOO` with `Cypress.env("FOO")`
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
|
||||
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
|
||||
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
|
||||
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
|
||||
CYPRESS_PULL_REQUEST_ID: ${{ github.event.pull_request.number || '' }}
|
||||
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title || github.event.head_commit.message || github.event.head.sha }}
|
||||
TZ: US/Pacific # to make node match the instance tz
|
||||
@@ -138,12 +140,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare Docker containers
|
||||
uses: ./.github/actions/e2e-prepare-containers
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
# 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
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 3
|
||||
outputs:
|
||||
e2e_all: ${{ steps.changes.outputs.e2e_all }}
|
||||
e2e_embedding_sdk: ${{ steps.changes.outputs.e2e_embedding_sdk }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test which files changed
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
needs: [files-changed, get-build-requirements]
|
||||
if: |
|
||||
!cancelled() &&
|
||||
needs.files-changed.outputs.e2e_all == 'true'
|
||||
needs.files-changed.outputs.e2e_embedding_sdk == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 25
|
||||
env:
|
||||
@@ -109,8 +109,10 @@ jobs:
|
||||
DISPLAY: ""
|
||||
# Any env starting with `CYPRESS_` will be available to all Cypress tests via `Cypress.env()`
|
||||
# Example: you can get `CYPRESS_FOO` with `Cypress.env("FOO")`
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
|
||||
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
|
||||
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
|
||||
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
|
||||
CYPRESS_PULL_REQUEST_ID: ${{ github.event.pull_request.number || '' }}
|
||||
CYPRESS_IS_EMBEDDING_SDK: true
|
||||
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title || github.event.head_commit.message || github.event.head.sha }}
|
||||
@@ -120,12 +122,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare Docker containers
|
||||
uses: ./.github/actions/e2e-prepare-containers
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Retrieve uberjar artifact for ee
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
name: E2E Cross-version Tests
|
||||
|
||||
# See `bin/backward-compatibility-test.js` for the documentation of this workflow.
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
@@ -143,8 +145,10 @@ jobs:
|
||||
- name: Run the tests
|
||||
env:
|
||||
MB_EDITION: ee
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
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 \
|
||||
|
||||
12
.github/workflows/e2e-cross-version.yml
vendored
@@ -66,8 +66,10 @@ jobs:
|
||||
docker run -d \
|
||||
-v $PWD/my-metabase:/metabase.db \
|
||||
-p 3000:3000 \
|
||||
-e CYPRESS_ALL_FEATURES_TOKEN=${{ secrets.ENTERPRISE_TOKEN }} \
|
||||
-e CYPRESS_NO_FEATURES_TOKEN=${{ secrets.E2E_STARTER_TOKEN }} \
|
||||
-e CYPRESS_MB_ALL_FEATURES_TOKEN=${{ secrets.MB_ALL_FEATURES_TOKEN }} \
|
||||
-e CYPRESS_MB_STARTER_CLOUD_TOKEN=${{ secrets.MB_STARTER_CLOUD_TOKEN }} \
|
||||
-e CYPRESS_MB_PRO_CLOUD_TOKEN=${{ secrets.MB_PRO_CLOUD_TOKEN }} \
|
||||
-e CYPRESS_MB_PRO_SELF_HOSTED_TOKEN=${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }} \
|
||||
--name metabase-${{ matrix.version.source }} \
|
||||
${{ env.DOCKER_SOURCE_IMAGE }}
|
||||
- name: Wait for Metabase to start on port 3000
|
||||
@@ -97,8 +99,10 @@ jobs:
|
||||
docker run -d \
|
||||
-v $PWD/my-metabase:/metabase.db \
|
||||
-p 3001:3000 \
|
||||
-e CYPRESS_ALL_FEATURES_TOKEN=${{ secrets.ENTERPRISE_TOKEN }} \
|
||||
-e CYPRESS_NO_FEATURES_TOKEN=${{ secrets.E2E_STARTER_TOKEN }} \
|
||||
-e CYPRESS_MB_ALL_FEATURES_TOKEN=${{ secrets.MB_ALL_FEATURES_TOKEN }} \
|
||||
-e CYPRESS_MB_STARTER_CLOUD_TOKEN=${{ secrets.MB_STARTER_CLOUD_TOKEN }} \
|
||||
-e CYPRESS_MB_PRO_CLOUD_TOKEN=${{ secrets.MB_PRO_CLOUD_TOKEN }} \
|
||||
-e CYPRESS_MB_PRO_SELF_HOSTED_TOKEN=${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }} \
|
||||
--name metabase-${{ matrix.version.target }} \
|
||||
${{ env.DOCKER_TARGET_IMAGE }}
|
||||
- name: Wait for Metabase to start on port 3001
|
||||
|
||||
@@ -191,6 +191,12 @@ jobs:
|
||||
name: embedding-sdk-${{ github.event.pull_request.head.sha || github.sha }}
|
||||
path: resources/embedding-sdk
|
||||
|
||||
# In order to check compatibility between Sample Apps and Embedding SDK, the job for each sample app:
|
||||
# - pulls a Sample App
|
||||
# - 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/dev.md`
|
||||
e2e-sample-apps-tests:
|
||||
needs: [get-build-requirements, get-sample-apps-data, build]
|
||||
strategy:
|
||||
@@ -208,7 +214,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number || '' }}
|
||||
HASH: ${{ github.event.pull_request.head.sha || github.sha }}-${{ github.run_attempt }}
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
|
||||
CYPRESS_IS_EMBEDDING_SDK: true
|
||||
TZ: US/Pacific # to make node match the instance tz
|
||||
CYPRESS_CI: true
|
||||
@@ -308,6 +314,13 @@ jobs:
|
||||
run: |
|
||||
exit 1
|
||||
|
||||
# The job checks integration of the Embedding SDK with consumer's apps that use different frameworks/bundlers,
|
||||
# or when we want to test some tricky integration cases like conflicting types.
|
||||
# The job
|
||||
# - 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/dev.md`
|
||||
e2e-host-apps-tests:
|
||||
needs: [ get-build-requirements, build ]
|
||||
strategy:
|
||||
@@ -330,7 +343,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number || '' }}
|
||||
HASH: ${{ github.event.pull_request.head.sha || github.sha }}-${{ github.run_attempt }}
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
|
||||
CYPRESS_IS_EMBEDDING_SDK: true
|
||||
TZ: US/Pacific # to make node match the instance tz
|
||||
CYPRESS_CI: true
|
||||
|
||||
@@ -63,8 +63,10 @@ jobs:
|
||||
DISPLAY: ""
|
||||
QA_DB_ENABLED: ${{ contains(fromJSON('["sql", "mongo"]'), inputs.qa_db) }}
|
||||
CYPRESS_QA_DB_MONGO: ${{ inputs.qa_db == 'mongo' }}
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
|
||||
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
|
||||
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
|
||||
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
|
||||
MB_SNOWPLOW_AVAILABLE: true
|
||||
MB_SNOWPLOW_URL: "http://localhost:9090" # Snowplow micro
|
||||
MB_EDITION: ${{ inputs.mb_edition }}
|
||||
@@ -84,6 +86,7 @@ jobs:
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
maildev: true
|
||||
openldap: true
|
||||
snowplow: true
|
||||
postgres: ${{ inputs.qa_db == 'sql' }}
|
||||
mysql: ${{ inputs.qa_db == 'sql' }}
|
||||
mongo: ${{ inputs.qa_db == 'mongo' }}
|
||||
@@ -103,8 +106,6 @@ jobs:
|
||||
- name: Prepare Cypress environment
|
||||
id: cypress-prep
|
||||
uses: ./.github/actions/prepare-cypress
|
||||
- name: Run Snowplow micro
|
||||
uses: ./.github/actions/run-snowplow-micro
|
||||
- name: Run Metabase
|
||||
run: node e2e/runner/run_cypress_ci.js start
|
||||
- name: Generate database snapshots
|
||||
|
||||
26
.github/workflows/e2e-test.yml
vendored
@@ -44,8 +44,10 @@ jobs:
|
||||
JOB_NAME: ${{ inputs.name }}
|
||||
# Any env starting with `CYPRESS_` will be available to all Cypress tests via `Cypress.env()`
|
||||
# Example: you can get `CYPRESS_FOO` with `Cypress.env("FOO")`
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
CYPRESS_MB_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
|
||||
CYPRESS_MB_STARTER_CLOUD_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
|
||||
CYPRESS_MB_PRO_CLOUD_TOKEN: ${{ secrets.MB_PRO_CLOUD_TOKEN }}
|
||||
CYPRESS_MB_PRO_SELF_HOSTED_TOKEN: ${{ secrets.MB_PRO_SELF_HOSTED_TOKEN }}
|
||||
CYPRESS_PULL_REQUEST_ID: ${{ github.event.pull_request.number || '' }}
|
||||
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title || github.event.head_commit.message || github.event.head.sha }}
|
||||
MB_EXPERIMENTAL_SEARCH_BLOCK_ON_QUEUE: true
|
||||
@@ -56,12 +58,6 @@ jobs:
|
||||
CYPRESS_CI: true
|
||||
CYPRESS_QA_DB_MONGO: ${{ inputs.name == 'mongo' }}
|
||||
CYPRESS_IS_EMBEDDING_SDK: ${{ inputs.name == 'embedding-sdk' }}
|
||||
mongo: ${{ inputs.name == 'mongo' }}
|
||||
postgres: ${{ inputs.name != 'mongo' }}
|
||||
mysql: ${{ inputs.name != 'mongo' }}
|
||||
openldap: true
|
||||
maildev: true
|
||||
webhook: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -71,11 +67,12 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
maildev: true
|
||||
openldap: ${{ env.openldap }}
|
||||
postgres: ${{ env.postgres }}
|
||||
mysql: ${{ env.mysql }}
|
||||
mongo: ${{ env.mongo }}
|
||||
webhook: ${{ env.webhook }}
|
||||
openldap: true
|
||||
webhook: true
|
||||
snowplow: true
|
||||
postgres: ${{ inputs.name != 'mongo' }}
|
||||
mysql: ${{ inputs.name != 'mongo' }}
|
||||
mongo: ${{ inputs.name == 'mongo' }}
|
||||
|
||||
- name: Run Embedding SDK Storybook
|
||||
if: inputs.name == 'embedding-sdk'
|
||||
@@ -111,9 +108,6 @@ jobs:
|
||||
if: github.run_attempt != '1'
|
||||
run: echo "specs=$(cat failed-specs)" >> $GITHUB_ENV
|
||||
|
||||
- name: Run Snowplow micro
|
||||
uses: ./.github/actions/run-snowplow-micro
|
||||
|
||||
- name: Run Metabase
|
||||
run: node e2e/runner/run_cypress_ci.js start
|
||||
|
||||
|
||||
14
.github/workflows/embedding-sdk.yml
vendored
@@ -18,8 +18,9 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 3
|
||||
outputs:
|
||||
documentation: ${{ steps.changes.outputs.documentation }}
|
||||
e2e_embedding_sdk: ${{ steps.changes.outputs.e2e_embedding_sdk }}
|
||||
frontend_embedding_sdk_sources: ${{ steps.changes.outputs.frontend_embedding_sdk_sources }}
|
||||
embedding_documentation: ${{ steps.changes.outputs.embedding_documentation }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test which files changed
|
||||
@@ -33,8 +34,9 @@ jobs:
|
||||
needs: [files-changed]
|
||||
if: |
|
||||
!cancelled() &&
|
||||
(needs.files-changed.outputs.frontend_embedding_sdk_sources == 'true' ||
|
||||
needs.files-changed.outputs.documentation == 'true')
|
||||
(needs.files-changed.outputs.e2e_embedding_sdk == 'true' ||
|
||||
needs.files-changed.outputs.frontend_embedding_sdk_sources == 'true' ||
|
||||
needs.files-changed.outputs.embedding_documentation == 'true')
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
@@ -75,7 +77,7 @@ jobs:
|
||||
embedding-sdk-docs-snippets-type-check:
|
||||
needs: [files-changed, build]
|
||||
if: |
|
||||
needs.files-changed.outputs.documentation == 'true' &&
|
||||
needs.files-changed.outputs.embedding_documentation == 'true' &&
|
||||
needs.build.result == 'success'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
@@ -140,6 +142,7 @@ jobs:
|
||||
if: ${{ steps.docs-generation.outcome == 'failure' }}
|
||||
run: exit 1
|
||||
|
||||
# See `Component e2e tests` in `enterprise/frontend/src/embedding-sdk/dev.md`
|
||||
sdk-e2e-tests:
|
||||
uses: ./.github/workflows/e2e-component-tests-embedding-sdk.yml
|
||||
needs: [build]
|
||||
@@ -153,8 +156,9 @@ jobs:
|
||||
uses: ./.github/workflows/e2e-component-tests-embedding-sdk-cross-version.yml
|
||||
secrets: inherit
|
||||
|
||||
# See `bin/backward-compatibility-test.js` for the documentation of this workflow.
|
||||
cross-version-for-breaking-changes:
|
||||
# run on: every pr that targets a release branch
|
||||
# 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
|
||||
|
||||
13
.github/workflows/pre-release.yml
vendored
@@ -103,8 +103,14 @@ jobs:
|
||||
env:
|
||||
MB_EDITION: ${{ matrix.edition }}
|
||||
DISPLAY: ""
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
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 }}
|
||||
# these are needed for backwards compatibility with release branches earlier than v55, since
|
||||
# this workflow always runs from master, but we run tests from the release branch
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.MB_ALL_FEATURES_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.MB_STARTER_CLOUD_TOKEN }}
|
||||
# disabled because of out of memory issues
|
||||
# probably related to https://github.com/cypress-io/cypress/issues/27415
|
||||
CYPRESS_NO_COMMAND_LOG: 1
|
||||
@@ -122,6 +128,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
maildev: true
|
||||
snowplow: true
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
- name: Prepare JDK 21
|
||||
@@ -132,8 +139,6 @@ jobs:
|
||||
- name: Prepare Cypress environment
|
||||
id: cypress-prep
|
||||
uses: ./.github/actions/prepare-cypress
|
||||
- name: Run Snowplow micro
|
||||
uses: ./.github/actions/run-snowplow-micro
|
||||
- uses: actions/download-artifact@v4
|
||||
name: Retrieve uberjar artifact for ${{ matrix.edition }}
|
||||
with:
|
||||
|
||||
16
.github/workflows/release-tag.yml
vendored
@@ -250,19 +250,9 @@ jobs:
|
||||
|
||||
- name: Tag the docker image
|
||||
run: | # sh
|
||||
docker pull $DOCKERHUB_REPO\:$DOCKERHUB_VERSION
|
||||
docker tag $DOCKERHUB_REPO\:$DOCKERHUB_VERSION $DOCKERHUB_REPO\:$TAG_NAME
|
||||
docker image ls $DOCKERHUB_REPO
|
||||
|
||||
SOURCE_ID=$(docker image ls $DOCKERHUB_REPO\:$DOCKERHUB_VERSION -q)
|
||||
TAGGED_ID=$(docker image ls $DOCKERHUB_REPO\:$TAG_NAME -q)
|
||||
|
||||
if [[ $SOURCE_ID != $TAGGED_ID ]]; then
|
||||
echo "Error tagging docker image"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker push $DOCKERHUB_REPO\:$TAG_NAME
|
||||
docker buildx imagetools create --tag \
|
||||
$DOCKERHUB_REPO\:$TAG_NAME \
|
||||
$DOCKERHUB_REPO\:$DOCKERHUB_VERSION
|
||||
|
||||
push-git-tags:
|
||||
permissions: write-all
|
||||
|
||||
7
.github/workflows/run-tests.yml
vendored
@@ -71,6 +71,13 @@ jobs:
|
||||
with:
|
||||
skip: ${{ needs.files-changed.outputs.backend_all != 'true' && needs.static-viz-files-changed.outputs.static_viz != 'true' }}
|
||||
|
||||
app-db-tests:
|
||||
needs: files-changed
|
||||
uses: ./.github/workflows/app-db.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
skip: ${{ needs.files-changed.outputs.backend_all != 'true' }}
|
||||
|
||||
driver-tests:
|
||||
needs: files-changed
|
||||
uses: ./.github/workflows/drivers.yml
|
||||
|
||||
1
.github/workflows/translation-update.yml
vendored
@@ -43,6 +43,7 @@ jobs:
|
||||
command_args: |
|
||||
--config locales/crowdin.yml
|
||||
-e=el
|
||||
-e=et
|
||||
-e=es-MX
|
||||
-e=gu-IN
|
||||
-e=hr
|
||||
|
||||
2
.gitignore
vendored
@@ -36,6 +36,7 @@
|
||||
/coverage
|
||||
/crate-*
|
||||
/cypress
|
||||
cypress.env.json
|
||||
/deploy/artifacts/*
|
||||
/docs/**/node_modules
|
||||
/docs/**/package.json
|
||||
@@ -146,6 +147,7 @@ llm-payloads
|
||||
.aider*
|
||||
/config.yml
|
||||
CLAUDE.local.md
|
||||
.claude/settings.local.json
|
||||
|
||||
.eslintcache
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -10,7 +10,7 @@ const mainAppStories = [
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: mainAppStories,
|
||||
staticDirs: ["../resources/frontend_client"],
|
||||
staticDirs: ["../resources/frontend_client", "./msw-public"],
|
||||
addons: [
|
||||
"@storybook/addon-webpack5-compiler-babel",
|
||||
"@storybook/addon-essentials",
|
||||
|
||||
307
.storybook/msw-public/mockServiceWorker.js
Normal file
@@ -0,0 +1,307 @@
|
||||
/* eslint-disable */
|
||||
/* tslint:disable */
|
||||
|
||||
/**
|
||||
* Mock Service Worker.
|
||||
* @see https://github.com/mswjs/msw
|
||||
* - Please do NOT modify this file.
|
||||
* - Please do NOT serve this file on production.
|
||||
*/
|
||||
|
||||
const PACKAGE_VERSION = "2.7.5";
|
||||
const INTEGRITY_CHECKSUM = "00729d72e3b82faf54ca8b9621dbb96f";
|
||||
const IS_MOCKED_RESPONSE = Symbol("isMockedResponse");
|
||||
const activeClientIds = new Set();
|
||||
|
||||
self.addEventListener("install", function () {
|
||||
self.skipWaiting();
|
||||
});
|
||||
|
||||
self.addEventListener("activate", function (event) {
|
||||
event.waitUntil(self.clients.claim());
|
||||
});
|
||||
|
||||
self.addEventListener("message", async function (event) {
|
||||
const clientId = event.source.id;
|
||||
|
||||
if (!clientId || !self.clients) {
|
||||
return;
|
||||
}
|
||||
|
||||
const client = await self.clients.get(clientId);
|
||||
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
const allClients = await self.clients.matchAll({
|
||||
type: "window",
|
||||
});
|
||||
|
||||
switch (event.data) {
|
||||
case "KEEPALIVE_REQUEST": {
|
||||
sendToClient(client, {
|
||||
type: "KEEPALIVE_RESPONSE",
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "INTEGRITY_CHECK_REQUEST": {
|
||||
sendToClient(client, {
|
||||
type: "INTEGRITY_CHECK_RESPONSE",
|
||||
payload: {
|
||||
packageVersion: PACKAGE_VERSION,
|
||||
checksum: INTEGRITY_CHECKSUM,
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "MOCK_ACTIVATE": {
|
||||
activeClientIds.add(clientId);
|
||||
|
||||
sendToClient(client, {
|
||||
type: "MOCKING_ENABLED",
|
||||
payload: {
|
||||
client: {
|
||||
id: client.id,
|
||||
frameType: client.frameType,
|
||||
},
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "MOCK_DEACTIVATE": {
|
||||
activeClientIds.delete(clientId);
|
||||
break;
|
||||
}
|
||||
|
||||
case "CLIENT_CLOSED": {
|
||||
activeClientIds.delete(clientId);
|
||||
|
||||
const remainingClients = allClients.filter((client) => {
|
||||
return client.id !== clientId;
|
||||
});
|
||||
|
||||
// Unregister itself when there are no more clients
|
||||
if (remainingClients.length === 0) {
|
||||
self.registration.unregister();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener("fetch", function (event) {
|
||||
const { request } = event;
|
||||
|
||||
// Bypass navigation requests.
|
||||
if (request.mode === "navigate") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Opening the DevTools triggers the "only-if-cached" request
|
||||
// that cannot be handled by the worker. Bypass such requests.
|
||||
if (request.cache === "only-if-cached" && request.mode !== "same-origin") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bypass all requests when there are no active clients.
|
||||
// Prevents the self-unregistered worked from handling requests
|
||||
// after it's been deleted (still remains active until the next reload).
|
||||
if (activeClientIds.size === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate unique request ID.
|
||||
const requestId = crypto.randomUUID();
|
||||
event.respondWith(handleRequest(event, requestId));
|
||||
});
|
||||
|
||||
async function handleRequest(event, requestId) {
|
||||
const client = await resolveMainClient(event);
|
||||
const response = await getResponse(event, client, requestId);
|
||||
|
||||
// Send back the response clone for the "response:*" life-cycle events.
|
||||
// Ensure MSW is active and ready to handle the message, otherwise
|
||||
// this message will pend indefinitely.
|
||||
if (client && activeClientIds.has(client.id)) {
|
||||
(async function () {
|
||||
const responseClone = response.clone();
|
||||
|
||||
sendToClient(
|
||||
client,
|
||||
{
|
||||
type: "RESPONSE",
|
||||
payload: {
|
||||
requestId,
|
||||
isMockedResponse: IS_MOCKED_RESPONSE in response,
|
||||
type: responseClone.type,
|
||||
status: responseClone.status,
|
||||
statusText: responseClone.statusText,
|
||||
body: responseClone.body,
|
||||
headers: Object.fromEntries(responseClone.headers.entries()),
|
||||
},
|
||||
},
|
||||
[responseClone.body],
|
||||
);
|
||||
})();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// Resolve the main client for the given event.
|
||||
// Client that issues a request doesn't necessarily equal the client
|
||||
// that registered the worker. It's with the latter the worker should
|
||||
// communicate with during the response resolving phase.
|
||||
async function resolveMainClient(event) {
|
||||
const client = await self.clients.get(event.clientId);
|
||||
|
||||
if (activeClientIds.has(event.clientId)) {
|
||||
return client;
|
||||
}
|
||||
|
||||
if (client?.frameType === "top-level") {
|
||||
return client;
|
||||
}
|
||||
|
||||
const allClients = await self.clients.matchAll({
|
||||
type: "window",
|
||||
});
|
||||
|
||||
return allClients
|
||||
.filter((client) => {
|
||||
// Get only those clients that are currently visible.
|
||||
return client.visibilityState === "visible";
|
||||
})
|
||||
.find((client) => {
|
||||
// Find the client ID that's recorded in the
|
||||
// set of clients that have registered the worker.
|
||||
return activeClientIds.has(client.id);
|
||||
});
|
||||
}
|
||||
|
||||
async function getResponse(event, client, requestId) {
|
||||
const { request } = event;
|
||||
|
||||
// Clone the request because it might've been already used
|
||||
// (i.e. its body has been read and sent to the client).
|
||||
const requestClone = request.clone();
|
||||
|
||||
function passthrough() {
|
||||
// Cast the request headers to a new Headers instance
|
||||
// so the headers can be manipulated with.
|
||||
const headers = new Headers(requestClone.headers);
|
||||
|
||||
// Remove the "accept" header value that marked this request as passthrough.
|
||||
// This prevents request alteration and also keeps it compliant with the
|
||||
// user-defined CORS policies.
|
||||
const acceptHeader = headers.get("accept");
|
||||
if (acceptHeader) {
|
||||
const values = acceptHeader.split(",").map((value) => value.trim());
|
||||
const filteredValues = values.filter(
|
||||
(value) => value !== "msw/passthrough",
|
||||
);
|
||||
|
||||
if (filteredValues.length > 0) {
|
||||
headers.set("accept", filteredValues.join(", "));
|
||||
} else {
|
||||
headers.delete("accept");
|
||||
}
|
||||
}
|
||||
|
||||
return fetch(requestClone, { headers });
|
||||
}
|
||||
|
||||
// Bypass mocking when the client is not active.
|
||||
if (!client) {
|
||||
return passthrough();
|
||||
}
|
||||
|
||||
// Bypass initial page load requests (i.e. static assets).
|
||||
// The absence of the immediate/parent client in the map of the active clients
|
||||
// means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
|
||||
// and is not ready to handle requests.
|
||||
if (!activeClientIds.has(client.id)) {
|
||||
return passthrough();
|
||||
}
|
||||
|
||||
// Notify the client that a request has been intercepted.
|
||||
const requestBuffer = await request.arrayBuffer();
|
||||
const clientMessage = await sendToClient(
|
||||
client,
|
||||
{
|
||||
type: "REQUEST",
|
||||
payload: {
|
||||
id: requestId,
|
||||
url: request.url,
|
||||
mode: request.mode,
|
||||
method: request.method,
|
||||
headers: Object.fromEntries(request.headers.entries()),
|
||||
cache: request.cache,
|
||||
credentials: request.credentials,
|
||||
destination: request.destination,
|
||||
integrity: request.integrity,
|
||||
redirect: request.redirect,
|
||||
referrer: request.referrer,
|
||||
referrerPolicy: request.referrerPolicy,
|
||||
body: requestBuffer,
|
||||
keepalive: request.keepalive,
|
||||
},
|
||||
},
|
||||
[requestBuffer],
|
||||
);
|
||||
|
||||
switch (clientMessage.type) {
|
||||
case "MOCK_RESPONSE": {
|
||||
return respondWithMock(clientMessage.data);
|
||||
}
|
||||
|
||||
case "PASSTHROUGH": {
|
||||
return passthrough();
|
||||
}
|
||||
}
|
||||
|
||||
return passthrough();
|
||||
}
|
||||
|
||||
function sendToClient(client, message, transferrables = []) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const channel = new MessageChannel();
|
||||
|
||||
channel.port1.onmessage = (event) => {
|
||||
if (event.data && event.data.error) {
|
||||
return reject(event.data.error);
|
||||
}
|
||||
|
||||
resolve(event.data);
|
||||
};
|
||||
|
||||
client.postMessage(
|
||||
message,
|
||||
[channel.port2].concat(transferrables.filter(Boolean)),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async function respondWithMock(response) {
|
||||
// Setting response status code to 0 is a no-op.
|
||||
// However, when responding with a "Response.error()", the produced Response
|
||||
// instance will have status code set to 0. Since it's not possible to create
|
||||
// a Response instance with status code 0, handle that use-case separately.
|
||||
if (response.status === 0) {
|
||||
return Response.error();
|
||||
}
|
||||
|
||||
const mockedResponse = new Response(response.body, response);
|
||||
|
||||
Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
|
||||
value: true,
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
return mockedResponse;
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import { css, Global, useTheme } from "@emotion/react";
|
||||
import { baseStyle, rootStyle } from "metabase/css/core/base.styled";
|
||||
import { defaultFontFiles } from "metabase/css/core/fonts.styled";
|
||||
import { saveDomImageStyles } from "metabase/visualizations/lib/image-exports";
|
||||
import { initialize, mswLoader } from "msw-storybook-addon";
|
||||
|
||||
// Note: Changing the names of the stories may impact loki visual testing. Please ensure that
|
||||
// Any story name changes are also reflected in the loki.config.js storiesFilter array.
|
||||
@@ -124,6 +125,15 @@ function CssVariables() {
|
||||
return <Global styles={styles} />;
|
||||
}
|
||||
|
||||
const preview = { parameters, decorators };
|
||||
/*
|
||||
* Initializes MSW
|
||||
* See https://github.com/mswjs/msw-storybook-addon#configuring-msw
|
||||
* to learn how to customize it
|
||||
*/
|
||||
|
||||
initialize({
|
||||
onUnhandledRequest: "bypass",
|
||||
});
|
||||
const preview = { parameters, decorators, loaders: [mswLoader] };
|
||||
|
||||
export default preview;
|
||||
|
||||
@@ -2,6 +2,18 @@
|
||||
/* eslint-disable no-console */
|
||||
/* global process */
|
||||
|
||||
// This workflow is experimental POC, non-required, and is owned by team
|
||||
// Embedding. For the time being, unless you think you did a breaking change on
|
||||
// the backend, you can safely ignore this if it fails. If you're working on CI or
|
||||
// related work and can't get this to pass, please reach out to team Embedding.
|
||||
|
||||
// This implements a POC of a way of testing for breaking changes explained in
|
||||
// https://www.notion.so/metabase/Tech-Run-e2e-with-different-versions-of-FE-and-BE-to-detect-breaking-changes-1b669354c9018068b55bc7f2ad4ca83a
|
||||
// It builds a uberjar with the frontend and a backend code from two different
|
||||
// commits, and runs the e2e tests from the frontend commit on the uberjar. The
|
||||
// goal is to try and detect breaking changes between the frontend and backend
|
||||
// code.
|
||||
|
||||
const os = require("os");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
@@ -27,6 +39,12 @@ const BE_FOLDER = path.join(TMP_FOLDER, "metabase-be");
|
||||
const JAR_PATH = path.join(BE_FOLDER, "target/uberjar/metabase.jar");
|
||||
|
||||
const getTestFiles = () => {
|
||||
// This is not ideal as we're "hardcoding" the path to the files. The
|
||||
// alternative would have been to add a specific @tag to the tests we wanted
|
||||
// to run, but because we're running the test files from the frontend commit,
|
||||
// which is an "older" commit, that commit wouldn't have these tags. We went
|
||||
// with this in this POC, but we should revisit this if we graduate this to
|
||||
// "official" testing.
|
||||
const questionFiles = getFilesInsideFolder(
|
||||
path.join(FE_FOLDER, "e2e/test/scenarios/question"),
|
||||
).map((file) => path.join("e2e/test/scenarios/question", file)); // make sure the path is how we expect, starting with "e2e/test..."
|
||||
@@ -40,7 +58,7 @@ const getTestFiles = () => {
|
||||
// place to put files if we want to skip them
|
||||
const SKIPPED_FILES = [];
|
||||
|
||||
console.log(`Using frontend from ${FE_GIT_REF}`);
|
||||
console.log(`Using frontend (and test files and helpers) from ${FE_GIT_REF}`);
|
||||
console.log(`Using backend from ${BE_GIT_REF}`);
|
||||
console.log("---");
|
||||
console.log("To test locally run:");
|
||||
@@ -132,10 +150,10 @@ function start() {
|
||||
|
||||
const dbFile = path.join(os.tmpdir(), `metabase-test-${process.pid}.db`);
|
||||
|
||||
const cypressToken = process.env.CYPRESS_ALL_FEATURES_TOKEN;
|
||||
const cypressToken = process.env.CYPRESS_MB_ALL_FEATURES_TOKEN;
|
||||
if (typeof cypressToken === "undefined") {
|
||||
console.error(
|
||||
"Error: CYPRESS_ALL_FEATURES_TOKEN environment variable is not set. This is required for the 'start' command.",
|
||||
"Error: CYPRESS_MB_ALL_FEATURES_TOKEN environment variable is not set. This is required for the 'start' command.",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
14
cypress.env.json.example
Normal file
@@ -0,0 +1,14 @@
|
||||
# Use this file to create a `cypress.env.json` in the root of this project.
|
||||
# Documentation: https://docs.cypress.io/app/references/environment-variables#Option-2-cypressenvjson
|
||||
|
||||
# Remove all lines starting with "#" (including this one)
|
||||
{
|
||||
"MB_SNOWPLOW_URL": "http://localhost:9090",
|
||||
"MB_SNOWPLOW_AVAILABLE": "true",
|
||||
"MB_ALL_FEATURES_TOKEN": "get it from the password manager",
|
||||
"MB_STARTER_CLOUD_TOKEN": "get it from the password manager",
|
||||
"MB_PRO_CLOUD_TOKEN": "get it from the password manager",
|
||||
"MB_PRO_SELF_HOSTED_TOKEN": "get it from the password manager",
|
||||
"MB_EDITION": "ee",
|
||||
"QA_DB_ENABLED": "true"
|
||||
}
|
||||
20
deps.edn
@@ -135,14 +135,14 @@
|
||||
org.slf4j/jcl-over-slf4j]}
|
||||
org.apache.tika/tika-core {:mvn/version "3.1.0"}
|
||||
org.apache.xmlgraphics/batik-all {:mvn/version "1.19"} ; SVG -> image
|
||||
org.bouncycastle/bcpkix-jdk18on {:mvn/version "1.80"} ; Bouncy Castle crypto library -- explicit version of BC specified to resolve illegal reflective access errors
|
||||
org.bouncycastle/bcprov-jdk18on {:mvn/version "1.80"}
|
||||
org.bouncycastle/bcpkix-jdk18on {:mvn/version "1.81"} ; Bouncy Castle crypto library -- explicit version of BC specified to resolve illegal reflective access errors
|
||||
org.bouncycastle/bcprov-jdk18on {:mvn/version "1.81"}
|
||||
org.clj-commons/claypoole {:mvn/version "1.2.2"} ; Threadpool tools for Clojure
|
||||
org.clj-commons/dirigiste {:mvn/version "1.0.4"} ; Instrumented object pooling
|
||||
org.clj-commons/hickory {:mvn/version "0.7.7" ; Parse HTML into Clojure data structures
|
||||
:exclusions [org.jsoup/jsoup]}
|
||||
org.clojars.pntblnk/clj-ldap {:mvn/version "0.0.17"} ; LDAP client
|
||||
org.clojure/clojure {:mvn/version "1.12.0"}
|
||||
org.clojure/clojure {:mvn/version "1.12.1"}
|
||||
org.clojure/core.async {:mvn/version "1.7.701"
|
||||
:exclusions [org.clojure/tools.reader]}
|
||||
org.clojure/core.logic {:mvn/version "1.1.0"} ; optimized pattern matching library for Clojure
|
||||
@@ -161,9 +161,9 @@
|
||||
org.clojure/tools.namespace {:mvn/version "1.5.0"}
|
||||
org.clojure/tools.reader {:mvn/version "1.5.2"}
|
||||
org.clojure/tools.trace {:mvn/version "0.8.0"} ; function tracing
|
||||
org.eclipse.jetty/jetty-server {:mvn/version "12.0.21"}
|
||||
org.eclipse.jetty/jetty-unixdomain-server {:mvn/version "12.0.21"}
|
||||
org.eclipse.jetty.ee9/jetty-ee9-servlet {:mvn/version "12.0.21"}
|
||||
org.eclipse.jetty/jetty-server {:mvn/version "12.0.22"}
|
||||
org.eclipse.jetty/jetty-unixdomain-server {:mvn/version "12.0.22"}
|
||||
org.eclipse.jetty.ee9/jetty-ee9-servlet {:mvn/version "12.0.22"}
|
||||
org.eclipse.jetty.ee9.websocket/jetty-ee9-websocket-jetty-server {:mvn/version "12.0.21"}
|
||||
org.flatland/ordered {:mvn/version "1.15.12"} ; ordered maps & sets
|
||||
org.graalvm.polyglot/js-community {:mvn/version "24.2.1" :extension "pom"} ; JavaScript engine
|
||||
@@ -188,8 +188,8 @@
|
||||
redux/redux {:git/url "https://github.com/metabase/redux"
|
||||
:sha "4a37feaf817a2a6b5ef688c927f6fd4375964433"}
|
||||
riddley/riddley {:mvn/version "0.2.0"} ; code walking lib -- used interally by Potemkin, manifold, etc.
|
||||
ring/ring-core {:mvn/version "1.14.1"} ; HTTP abstraction
|
||||
ring/ring-jetty-adapter {:mvn/version "1.14.1" ; Ring adapter for Jetty
|
||||
ring/ring-core {:mvn/version "1.14.2"} ; HTTP abstraction
|
||||
ring/ring-jetty-adapter {:mvn/version "1.14.2" ; Ring adapter for Jetty
|
||||
:exclusions [org.eclipse.jetty/jetty-server
|
||||
org.eclipse.jetty/jetty-unixdomain-server
|
||||
org.eclipse.jetty.ee9/jetty-ee9-servlet
|
||||
@@ -266,7 +266,7 @@
|
||||
:exclusions [org.clojure/clojure
|
||||
org.clojure/clojurescript]} ; lets you write test fixtures that are clear, concise, and easy to maintain (clojure.spec)
|
||||
rewrite-clj/rewrite-clj {:mvn/version "1.2.50"} ; clojure source parsing and rewriting
|
||||
ring/ring-devel {:mvn/version "1.14.1"} ; reload clojure files on the fly
|
||||
ring/ring-devel {:mvn/version "1.14.2"} ; reload clojure files on the fly
|
||||
ring/ring-mock {:mvn/version "0.6.1"} ; creating Ring request maps for testing purposes
|
||||
talltale/talltale {:mvn/version "0.5.14"}} ; generates fake data, useful for prototyping or load testing
|
||||
:extra-paths ["dev/src" "local/src" "test" "test_resources" ".clj-kondo/src" ".clj-kondo/test"]
|
||||
@@ -785,7 +785,7 @@
|
||||
;; get the H2 shell with clojure -X:dev:h2
|
||||
:h2
|
||||
{:extra-paths ["dev/src"]
|
||||
:exec-fn dev.h2-shell/shell
|
||||
:exec-fn dev.h2/shell
|
||||
:jvm-opts ["-Dfile.encoding=UTF-8"]}
|
||||
|
||||
:generate-automagic-dashboards-pot
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
[clojure.test]
|
||||
[dev.debug-qp :as debug-qp]
|
||||
[dev.explain :as dev.explain]
|
||||
[dev.h2 :as dev.h2]
|
||||
[dev.memory :as dev.memory]
|
||||
[dev.migrate :as dev.migrate]
|
||||
[dev.model-tracking :as model-tracking]
|
||||
@@ -95,7 +96,8 @@
|
||||
|
||||
(comment
|
||||
debug-qp/keep-me
|
||||
model-tracking/keep-me)
|
||||
model-tracking/keep-me
|
||||
dev.h2/keep-me)
|
||||
|
||||
#_:clj-kondo/ignore
|
||||
(defn tap>-spy [x]
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
(ns dev.h2-shell
|
||||
(ns dev.h2
|
||||
(:require
|
||||
[environ.core :as env]
|
||||
[metabase.app-db.data-source :as mdb.data-source]
|
||||
[metabase.app-db.env :as mdb.env]))
|
||||
[metabase.app-db.env :as mdb.env])
|
||||
(:import (org.h2.tools Server)))
|
||||
|
||||
(comment mdb.data-source/keep-me)
|
||||
|
||||
@@ -19,3 +20,13 @@
|
||||
url (.url data-source)]
|
||||
(println "Connecting to database at URL" url)
|
||||
url)])))
|
||||
|
||||
(def ^:private tcp-listener (atom nil))
|
||||
|
||||
(defn tcp-listen
|
||||
"Starts a TCP server for the H2 app-db database on port 9092."
|
||||
[]
|
||||
(when @tcp-listener
|
||||
(throw (ex-info "TCP listener is already running" {:port 9092})))
|
||||
(reset! tcp-listener (.start (Server/createTcpServer (into-array ["-tcp" "-tcpAllowOthers" "-tcpPort" "9092"]))))
|
||||
(println (str "H2 TCP server started (no username or password): jdbc:h2:tcp://localhost:9092/" (#'metabase.app-db.env/env->db-file metabase.app-db.env/env))))
|
||||