Compare commits
1 Commits
attach-ren
...
scatter_pl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4452fb699 |
@@ -1,5 +1,4 @@
|
||||
;; -*- comment-column: 100; -*-
|
||||
{:config-paths ["macros" "src"]
|
||||
{:config-paths ["macros"]
|
||||
:linters
|
||||
{:aliased-namespace-symbol {:level :warning}
|
||||
:invalid-arity {:skip-args [metabase.lib.util.match/match]} ; TODO (cam): can we fix these?
|
||||
@@ -15,7 +14,6 @@
|
||||
:redundant-fn-wrapper {:level :warning}
|
||||
:refer-all {:level :warning, :exclude [clojure.test]}
|
||||
:single-key-in {:level :warning}
|
||||
:unsorted-required-namespaces {:level :warning}
|
||||
:unused-referred-var {:exclude {compojure.core [GET DELETE POST PUT]}}
|
||||
:use {:level :warning}
|
||||
:warn-on-reflection {:level :warning}
|
||||
@@ -24,7 +22,6 @@
|
||||
:metabase/i-like-making-cams-eyes-bleed-with-horrifically-long-tests {:level :warning}
|
||||
:metabase/mbql-query-first-arg {:level :warning}
|
||||
:metabase/missing-test-expr-requires-in-cljs {:level :warning}
|
||||
:metabase/require-shape-checker {:level :warning}
|
||||
:metabase/test-helpers-use-non-thread-safe-functions {:level :warning}
|
||||
:metabase/validate-deftest {:level :warning}
|
||||
:metabase/validate-logging {:level :warning}
|
||||
@@ -125,191 +122,7 @@
|
||||
{:exclude
|
||||
[colorize.core]}
|
||||
|
||||
;; A "module" is any `metabase.x` namespace in `src`.
|
||||
:metabase/ns-module-checker
|
||||
{:level :warning
|
||||
|
||||
;; Map of module name => the "core" external public-facing API namespace(s). You have three options here:
|
||||
;;
|
||||
;; 1. Special sentinel value `:any` means means this module does not (yet) have external public-facing API
|
||||
;; namespace(s). This is mostly a temporary placeholder until we go in and create module namespaces, which means
|
||||
;; you should go create one.
|
||||
;;
|
||||
;; 2. A set of namespace symbols. All namespaces in other modules will only be allowed ;; to use namespaces from
|
||||
;; this set. Ideally this set should only have one namespace, but restricting it to a set of several is still
|
||||
;; better than `:any`.
|
||||
;;
|
||||
;; 3. `nil` or not listed here -- we default to assuming there is one API namespace that matches the name of the
|
||||
;; module itself, e.g. the module namespace for `metabase.setup` would be `metabase.setup`.
|
||||
;;
|
||||
;; `nil` or an empty set Otherwise this should be a set of namespace symbols.
|
||||
;;
|
||||
;; PRO TIP: Check out the `dev.deps-graph` namespace for helpful tools to see where a module is used externally.
|
||||
:api-namespaces
|
||||
{metabase.actions #{metabase.actions.core}
|
||||
metabase.analytics #{metabase.analytics.prometheus
|
||||
metabase.analytics.snowplow
|
||||
metabase.analytics.stats} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.analyze #{metabase.analyze}
|
||||
metabase.api #{metabase.api.common
|
||||
metabase.api.dataset
|
||||
metabase.api.permission-graph
|
||||
metabase.api.routes} ; TODO -- consolidate these into a real API namespace. I think the `*current-user*` type stuff might need to be moved into a separate module.
|
||||
metabase.async #{metabase.async.streaming-response
|
||||
metabase.async.streaming-response.thread-pool
|
||||
metabase.async.util} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.bootstrap #{metabase.bootstrap}
|
||||
metabase.cmd #{} ; there are no namespaces here since you shouldn't be using this in any other module.
|
||||
metabase.config #{metabase.config}
|
||||
metabase.core #{metabase.core.initialization-status} ; TODO -- only namespace used outside of EE, this probably belongs in `metabase.server` anyway since that's the only place it's used.
|
||||
metabase.db #{metabase.db
|
||||
metabase.db.metadata-queries ; TODO this should probably be separate from metabase.db
|
||||
metabase.db.query ; TODO this is mostly util stuff like `metabase.db.query/query` that we don't even need anymore.
|
||||
metabase.db.setup} ; TODO these are only calling `metabase.db.setup/setup-db!` and there's a slightly different version in `metabase.db`
|
||||
metabase.driver :any ; TODO -- 19 namespaces!!!! CRY
|
||||
metabase.email #{metabase.email
|
||||
metabase.email.messages} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.embed #{metabase.embed.settings}
|
||||
metabase.events #{metabase.events}
|
||||
metabase.formatter #{metabase.formatter}
|
||||
metabase.integrations #{metabase.integrations.common
|
||||
metabase.integrations.google
|
||||
metabase.integrations.ldap
|
||||
metabase.integrations.slack} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.legacy-mbql #{metabase.legacy-mbql.normalize
|
||||
metabase.legacy-mbql.predicates
|
||||
metabase.legacy-mbql.schema
|
||||
metabase.legacy-mbql.schema.helpers
|
||||
metabase.legacy-mbql.util} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.lib :any ; TODO -- :cry: 34 externally referenced namespaces, but maybe half of them are schema namespaces which technically don't need to be required.
|
||||
metabase.logger #{metabase.logger}
|
||||
metabase.metabot #{metabase.metabot}
|
||||
metabase.models :any ; TODO -- scream, 62 namespaces used elsewhere, but to be fair a lot of these don't *need* to be required.
|
||||
metabase.moderation #{metabase.moderation}
|
||||
metabase.native-query-analyzer #{metabase.native-query-analyzer}
|
||||
metabase.permissions #{metabase.permissions.util} ; TODO -- this is currently the only namespace in this module. Give it a real API namespace?
|
||||
metabase.plugins #{metabase.plugins
|
||||
metabase.plugins.classloader} ; TODO -- not 100% sure the classloader belongs here
|
||||
metabase.public-settings #{metabase.public-settings
|
||||
metabase.public-settings.premium-features}
|
||||
metabase.pulse #{metabase.pulse
|
||||
metabase.pulse.attachment
|
||||
metabase.pulse.markdown
|
||||
metabase.pulse.parameters
|
||||
metabase.pulse.preview
|
||||
metabase.pulse.render
|
||||
metabase.pulse.render.image-bundle
|
||||
metabase.pulse.render.js-svg
|
||||
metabase.pulse.render.style} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.query-processor :any ; TODO omg scream, 29 namespaces used outside of the module. WHAT THE HECC
|
||||
metabase.related #{metabase.related}
|
||||
metabase.sample-data #{metabase.sample-data}
|
||||
metabase.search #{metabase.search}
|
||||
metabase.server #{metabase.server
|
||||
metabase.server.handler
|
||||
metabase.server.middleware.auth
|
||||
metabase.server.middleware.exceptions
|
||||
metabase.server.middleware.json
|
||||
metabase.server.middleware.misc
|
||||
metabase.server.middleware.offset-paging
|
||||
metabase.server.middleware.session
|
||||
metabase.server.protocols
|
||||
metabase.server.request.util} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.setup #{metabase.setup}
|
||||
metabase.shared #{metabase.shared.dashboards.constants
|
||||
metabase.shared.formatting.constants
|
||||
metabase.shared.formatting.date
|
||||
metabase.shared.formatting.numbers
|
||||
metabase.shared.models.visualization-settings
|
||||
metabase.shared.parameters.parameters
|
||||
metabase.shared.util.currency
|
||||
metabase.shared.util.i18n
|
||||
metabase.shared.util.internal.time-common
|
||||
metabase.shared.util.namespaces
|
||||
metabase.shared.util.time} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.sync #{metabase.sync
|
||||
metabase.sync.analyze
|
||||
metabase.sync.concurrent
|
||||
metabase.sync.field-values
|
||||
metabase.sync.schedules
|
||||
metabase.sync.sync-metadata
|
||||
metabase.sync.sync-metadata.fields
|
||||
metabase.sync.sync-metadata.tables
|
||||
metabase.sync.util} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.task #{metabase.task
|
||||
metabase.task.index-values
|
||||
metabase.task.persist-refresh} ; TODO -- consolidate these into a real API namespace.
|
||||
metabase.troubleshooting #{metabase.troubleshooting}
|
||||
metabase.types #{metabase.types}
|
||||
metabase.upload #{metabase.upload}
|
||||
metabase.util :any ; I think util being `:any` is actually something I am ok with. But this has 32 namespaces.
|
||||
metabase.xrays #{metabase.xrays}}
|
||||
|
||||
;; Map of module => other modules you're allowed to use there. You have two options here:
|
||||
;;
|
||||
;; 1. `:any` means namespaces in this module are allowed to use any other module -- allowed modules are not
|
||||
;; enforced for this module. Module API namespaces for modules that have them defined are still enforced. For
|
||||
;; ones that are `nil`, please go in and add a list of allowed modules. `:any` is mostly meant a temporary
|
||||
;; placeholder until we can fill these all out, so feel free to fix these.
|
||||
;;
|
||||
;; 2. A set of module symbols. This is the list of modules that are allowed to be referenced. An empty set means no
|
||||
;; other modules are allowed to be referenced; this is the default for any modules that aren't listed here.
|
||||
:allowed-modules
|
||||
{metabase.actions :any
|
||||
metabase.analytics :any
|
||||
metabase.analyze :any
|
||||
metabase.api :any
|
||||
metabase.async :any
|
||||
metabase.bootstrap #{}
|
||||
metabase.cmd :any
|
||||
metabase.compatibility :any
|
||||
metabase.config #{metabase.plugins}
|
||||
metabase.core :any
|
||||
metabase.db :any
|
||||
metabase.driver :any
|
||||
metabase.email :any
|
||||
metabase.embed :any
|
||||
metabase.events :any
|
||||
metabase.formatter :any
|
||||
metabase.integrations :any
|
||||
metabase.legacy-mbql :any
|
||||
metabase.lib :any
|
||||
metabase.logger #{metabase.config
|
||||
metabase.plugins}
|
||||
metabase.metabot :any
|
||||
metabase.models :any
|
||||
metabase.moderation :any
|
||||
metabase.native-query-analyzer :any
|
||||
metabase.permissions :any
|
||||
metabase.plugins :any
|
||||
metabase.public-settings :any
|
||||
metabase.pulse :any
|
||||
metabase.query-processor :any
|
||||
metabase.related :any
|
||||
metabase.sample-data :any
|
||||
metabase.search :any
|
||||
metabase.server :any
|
||||
metabase.setup :any
|
||||
metabase.shared :any
|
||||
metabase.sync :any
|
||||
metabase.task :any
|
||||
metabase.troubleshooting :any
|
||||
metabase.types #{metabase.util}
|
||||
metabase.upload :any
|
||||
metabase.util :any
|
||||
metabase.xrays :any}
|
||||
|
||||
;; namespaces matching these patterns (with `re-find`) are excluded from the module linter. Since regex literals
|
||||
;; aren't allowed in EDN just used the `(str <regex>)` version i.e. two slashes instead of one.
|
||||
;;
|
||||
;; this is mostly intended for excluding test namespaces or those rare 'glue' namespaces that glue multiple modules
|
||||
;; together, e.g. `metabase.lib.metadata.jvm`.
|
||||
:ignored-namespace-patterns
|
||||
#{"-test$" ; anything ending in `-test`
|
||||
"test[-.]util" ; anything that contains `test.util` or `test-util`
|
||||
"test\\.impl" ; anything that contains `test.impl`
|
||||
"^metabase\\.test" ; anything starting with `metabase.test`
|
||||
"^metabase\\.http-client$"}} ; `metabase.http-client` which is a test-only namespace despite its name.
|
||||
:unsorted-required-namespaces {:level :warning}
|
||||
|
||||
:consistent-alias
|
||||
{:aliases
|
||||
@@ -407,9 +220,13 @@
|
||||
metabase.api.tiles api.tiles
|
||||
metabase.api.timeline api.timeline
|
||||
metabase.api.timeline-event api.timeline-event
|
||||
metabase.api.transform api.transform
|
||||
metabase.api.user api.user
|
||||
metabase.api.util api.util
|
||||
metabase.async.streaming-response.thread-pool thread-pool
|
||||
metabase.automagic-dashboards.core magic
|
||||
metabase.automagic-dashboards.dashboard-templates dashboard-templates
|
||||
metabase.automagic-dashboards.populate populate
|
||||
metabase.cmd.copy.h2 copy.h2
|
||||
metabase.config config
|
||||
metabase.config.file config.file
|
||||
@@ -419,6 +236,7 @@
|
||||
metabase.db.metadata-queries metadata-queries
|
||||
metabase.db.spec mdb.spec
|
||||
metabase.db.query mdb.query
|
||||
metabase.domain-entities.specs de.specs
|
||||
metabase.driver.common.parameters params
|
||||
metabase.driver.common.parameters.dates params.dates
|
||||
metabase.driver.common.parameters.operators params.ops
|
||||
@@ -429,6 +247,10 @@
|
||||
metabase.driver.druid.js druid.js
|
||||
metabase.driver.druid.query-processor druid.qp
|
||||
metabase.driver.druid.sync druid.sync
|
||||
metabase.driver.googleanalytics.client ga.client
|
||||
metabase.driver.googleanalytics.execute ga.execute
|
||||
metabase.driver.googleanalytics.metadata ga.metadata
|
||||
metabase.driver.googleanalytics.query-processor ga.qp
|
||||
metabase.driver.impl driver.impl
|
||||
metabase.driver.mongo.execute mongo.execute
|
||||
metabase.driver.mongo.parameters mongo.params
|
||||
@@ -559,6 +381,9 @@
|
||||
metabase.test.util.js test.js
|
||||
metabase.test.util.timezone test.tz
|
||||
metabase.timeseries-query-processor-test.util tqpt
|
||||
metabase.transforms.core tf
|
||||
metabase.transforms.materialize tf.materialize
|
||||
metabase.transforms.specs tf.specs
|
||||
metabase.util.cron u.cron
|
||||
metabase.util.date-2 u.date
|
||||
metabase.util.date-2.common u.date.common
|
||||
@@ -579,7 +404,6 @@
|
||||
metabase.util.schema su
|
||||
metabase.util.ui-logic ui-logic
|
||||
metabase.util.urls urls
|
||||
metabase.xrays xrays
|
||||
metabuild-common.core u
|
||||
metabuild-common.output out
|
||||
metabuild-common.shell shell
|
||||
@@ -611,6 +435,7 @@
|
||||
metabase.db.data-migrations/defmigration clojure.core/def
|
||||
metabase.db.liquibase/with-liquibase clojure.core/let
|
||||
metabase.db.schema-migrations-test.impl/with-temp-empty-app-db clojure.core/let
|
||||
metabase.domain-entities.malli/defn schema.core/defn
|
||||
metabase.driver.mongo.query-processor/mongo-let clojure.core/let
|
||||
metabase.driver.mongo.connection/with-mongo-client clojure.core/let
|
||||
metabase.driver.mongo.connection/with-mongo-database clojure.core/let
|
||||
@@ -641,33 +466,32 @@
|
||||
metabase.test/with-actions clojure.core/let
|
||||
metabase.test/with-open-channels clojure.core/let
|
||||
metabase.test/with-single-admin-user clojure.core/fn
|
||||
metabase.test/with-temp-dir clojure.core/let
|
||||
metabase.test/with-temp-empty-app-db clojure.core/let
|
||||
metabase.test/with-temp-file clojure.core/let
|
||||
metabase.test/with-user-in-groups clojure.core/let
|
||||
metabase.upload-test/with-upload-table! clojure.core/let
|
||||
metabase.util.files/with-open-path-to-resource clojure.core/let
|
||||
metabase.util.malli.defn/defn schema.core/defn
|
||||
metabase.util.malli.fn/fn schema.core/fn
|
||||
metabase.util.malli/defmethod schema.core/defmethod
|
||||
metabase.util.malli/defn schema.core/defn
|
||||
metabase.util.malli/fn schema.core/fn
|
||||
metabase.util.ssh/with-ssh-tunnel clojure.core/let
|
||||
metabase.xrays.domain-entities.malli/defn schema.core/defn
|
||||
monger.operators/defoperator clojure.core/def
|
||||
potemkin.types/defprotocol+ clojure.core/defprotocol
|
||||
potemkin.types/defrecord+ clojure.core/defrecord
|
||||
potemkin.types/deftype+ clojure.core/deftype
|
||||
potemkin/defprotocol+ clojure.core/defprotocol
|
||||
potemkin/defrecord+ clojure.core/defrecord
|
||||
potemkin/deftype+ clojure.core/deftype
|
||||
toucan.db/with-call-counting clojure.core/fn
|
||||
toucan2.core/with-call-count clojure.core/fn}
|
||||
|
||||
metabase.test/with-temp-dir clojure.core/let
|
||||
metabase.test/with-temp-empty-app-db clojure.core/let
|
||||
metabase.test/with-temp-file clojure.core/let
|
||||
metabase.test/with-user-in-groups clojure.core/let
|
||||
metabase.upload-test/with-upload-table! clojure.core/let
|
||||
metabase.util.files/with-open-path-to-resource clojure.core/let
|
||||
metabase.util.malli.defn/defn schema.core/defn
|
||||
metabase.util.malli.fn/fn schema.core/fn
|
||||
metabase.util.malli/defmethod schema.core/defmethod
|
||||
metabase.util.malli/defn schema.core/defn
|
||||
metabase.util.malli/fn schema.core/fn
|
||||
metabase.util.ssh/with-ssh-tunnel clojure.core/let
|
||||
monger.operators/defoperator clojure.core/def
|
||||
potemkin.types/defprotocol+ clojure.core/defprotocol
|
||||
potemkin.types/defrecord+ clojure.core/defrecord
|
||||
potemkin.types/deftype+ clojure.core/deftype
|
||||
potemkin/defprotocol+ clojure.core/defprotocol
|
||||
potemkin/defrecord+ clojure.core/defrecord
|
||||
potemkin/deftype+ clojure.core/deftype
|
||||
toucan.db/with-call-counting clojure.core/fn
|
||||
toucan2.core/with-call-count clojure.core/fn}
|
||||
|
||||
:hooks
|
||||
{:analyze-call
|
||||
{clojure.core/ns hooks.clojure.core/lint-ns
|
||||
cljs.test/deftest hooks.clojure.test/deftest
|
||||
{cljs.test/deftest hooks.clojure.test/deftest
|
||||
cljs.test/is hooks.clojure.test/is
|
||||
cljs.test/use-fixtures hooks.clojure.test/use-fixtures
|
||||
clojure.test/deftest hooks.clojure.test/deftest
|
||||
@@ -684,9 +508,6 @@
|
||||
metabase.api.card-test/with-temp-native-card! hooks.common/with-two-bindings
|
||||
metabase.api.card-test/with-temp-native-card-with-params! hooks.common/with-two-bindings
|
||||
metabase.api.collection-test/with-french-user-and-personal-collection hooks.common/with-two-top-level-bindings
|
||||
metabase.api.common/defendpoint hooks.metabase.api.common/defendpoint
|
||||
metabase.api.common/defendpoint-async hooks.metabase.api.common/defendpoint
|
||||
metabase.api.common/defendpoint-async-schema hooks.metabase.api.common/defendpoint
|
||||
metabase.api.dashboard-test/with-chain-filter-fixtures hooks.common/let-one-with-optional-value
|
||||
metabase.api.dashboard-test/with-simple-dashboard-with-tabs hooks.common/with-one-binding
|
||||
metabase.api.card-test/with-card-param-values-fixtures hooks.common/let-one-with-optional-value
|
||||
@@ -785,11 +606,15 @@
|
||||
metabase.api.card-test/with-ordered-items macros.metabase.api.card-test/with-ordered-items
|
||||
metabase.api.collection-test/with-collection-hierarchy macros.metabase.api.collection-test/with-collection-hierarchy
|
||||
metabase.api.collection-test/with-some-children-of-collection macros.metabase.api.collection-test/with-some-children-of-collection
|
||||
metabase.api.common/defendpoint macros.metabase.api.common/defendpoint
|
||||
metabase.api.common/defendpoint-async macros.metabase.api.common/defendpoint
|
||||
metabase.api.common/defendpoint-async-schema macros.metabase.api.common/defendpoint
|
||||
metabase.api.common/define-routes macros.metabase.api.common/define-routes
|
||||
metabase.api.embed-test/with-embedding-enabled-and-temp-card-referencing macros.metabase.api.embed-test/with-embedding-enabled-and-temp-card-referencing
|
||||
metabase.api.embed-test/with-embedding-enabled-and-temp-dashcard-referencing macros.metabase.api.embed-test/with-embedding-enabled-and-temp-dashcard-referencing
|
||||
metabase.api.public-test/with-sharing-enabled-and-temp-card-referencing macros.metabase.api.public-test/with-sharing-enabled-and-temp-card-referencing
|
||||
metabase.api.public-test/with-sharing-enabled-and-temp-dashcard-referencing macros.metabase.api.public-test/with-sharing-enabled-and-temp-dashcard-referencing
|
||||
metabase.domain-entities.malli/define-getters-and-setters macros.metabase.domain-entities.malli/define-getters-and-setters
|
||||
metabase.lib.filter/deffilter macros.metabase.lib.filter/deffilter
|
||||
metabase.lib.common/defop macros.metabase.lib.common/defop
|
||||
metabase.models.params.chain-filter-test/chain-filter macros.metabase.models.params.chain-filter-test/chain-filter
|
||||
@@ -805,8 +630,7 @@
|
||||
metabase.test/with-group-for-user macros.metabase.test.data.users/with-group-for-user
|
||||
metabase.test/with-persistence-enabled macros.metabase.test.persistence/with-persistence-enabled
|
||||
metabase.test/with-temp-env-var-value! macros.metabase.test.util/with-temp-env-var-value!
|
||||
metabase.test/with-temporary-raw-setting-values macros.metabase.test.util/with-temporary-raw-setting-values
|
||||
metabase.xrays.domain-entities.malli/define-getters-and-setters macros.metabase.xrays.domain-entities.malli/define-getters-and-setters}}
|
||||
metabase.test/with-temporary-raw-setting-values macros.metabase.test.util/with-temporary-raw-setting-values}}
|
||||
|
||||
:config-in-comment
|
||||
{:linters {:unresolved-symbol {:level :off}}}
|
||||
@@ -818,14 +642,14 @@
|
||||
;; the following patterns are considered to be test namespaces:
|
||||
;;
|
||||
;; - Any namespace ending in `-test` or `-test.whatever`
|
||||
;; - Any namespace containing in `test-util`
|
||||
;; - Any namespace ending in `test-util`
|
||||
;; - Any namespace that starts with `metabase.test`
|
||||
;;
|
||||
;; this list isn't exhaustive because it misses some stuff like the test runner and HTTP client but it's easier to go
|
||||
;; fix those namespaces than it is to make this regex super hairy.
|
||||
[{:pattern "(?:.*-test(?:\\..*)?$)|(?:.*test-util)|(?:^metabase\\.test.*)"
|
||||
[{:pattern "(?:.*-test(?:\\..*)?$)|(?:.*test-util$)|(?:^metabase\\.test.*)"
|
||||
:name test-namespaces}
|
||||
{:pattern "^(?!.*-test(?:\\..*)?$)(?!.*test-util)(?!^metabase\\.test.*).*$"
|
||||
{:pattern "^(?!.*-test(?:\\..*)?$)(?!.*test-util$)(?!^metabase\\.test.*).*$"
|
||||
:name source-namespaces}
|
||||
{:pattern "(?:(?:^metabase\\.cmd.*)|(?:^build.*)|(?:^metabuild-common.*)|(?:^release.*)|(?:^i18n.*)|(?:^lint-migrations-file$))"
|
||||
:name printable-namespaces}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns hooks.clojure.core
|
||||
(:require
|
||||
[clj-kondo.hooks-api :as hooks]
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defn- node->qualified-symbol [node]
|
||||
@@ -16,7 +15,7 @@
|
||||
(catch Exception _
|
||||
nil)))
|
||||
|
||||
(def ^:private symbols-allowed-in-fns-not-ending-in-an-exclamation-point
|
||||
(def ^:private white-card-symbols
|
||||
'#{;; these toucan methods might actually set global values if it's used outside of a transaction,
|
||||
;; but since mt/with-temp runs in a transaction, so we'll ignore them in this case.
|
||||
toucan2.core/delete!
|
||||
@@ -160,7 +159,7 @@
|
||||
(walk f child)))]
|
||||
(walk (fn [form]
|
||||
(when-let [qualified-symbol (node->qualified-symbol form)]
|
||||
(when (and (not (contains? symbols-allowed-in-fns-not-ending-in-an-exclamation-point qualified-symbol))
|
||||
(when (and (not (contains? white-card-symbols qualified-symbol))
|
||||
(end-with-exclamation? qualified-symbol))
|
||||
(hooks/reg-finding! (assoc (meta form-name)
|
||||
:message (format "The name of this %s should end with `!` because it contains calls to non thread safe form `%s`."
|
||||
@@ -204,126 +203,3 @@
|
||||
:findings))
|
||||
|
||||
(do (non-thread-safe-form-should-end-with-exclamation* (hooks/parse-string form)) nil))
|
||||
|
||||
(defn- ns-form-node->require-node [ns-form-node]
|
||||
(some (fn [node]
|
||||
(when (and (hooks/list-node? node)
|
||||
(let [first-child (first (:children node))]
|
||||
(and (hooks/keyword-node? first-child)
|
||||
(= (hooks/sexpr first-child) :require))))
|
||||
node))
|
||||
(:children ns-form-node)))
|
||||
|
||||
(defn- lint-require-shapes [ns-form-node]
|
||||
(doseq [node (-> ns-form-node
|
||||
ns-form-node->require-node
|
||||
:children
|
||||
rest)]
|
||||
(cond
|
||||
(not (hooks/vector-node? node))
|
||||
(hooks/reg-finding! (assoc (meta node)
|
||||
:message "All :required namespaces should be wrapped in vectors [:metabase/require-shape-checker]"
|
||||
:type :metabase/require-shape-checker))
|
||||
|
||||
(hooks/vector-node? (second (:children node)))
|
||||
(hooks/reg-finding! (assoc (meta node)
|
||||
:message "Don't use prefix forms inside :require [:metabase/require-shape-checker]"
|
||||
:type :metabase/require-shape-checker)))))
|
||||
|
||||
(defn- require-node->namespace-symb-nodes [require-node]
|
||||
(let [[_ns & args] (:children require-node)]
|
||||
(into []
|
||||
;; prefixed namespace forms are NOT SUPPORTED!!!!!!!!1
|
||||
(keep (fn [node]
|
||||
(cond
|
||||
(hooks/vector-node? node)
|
||||
;; propagate the metadata attached to this vector in case there's a `:clj-kondo/ignore` form.
|
||||
(vary-meta (first (:children node)) (partial merge (meta require-node) (meta node)))
|
||||
|
||||
;; this should also be dead code since we require requires to be vectors
|
||||
(hooks/token-node? node)
|
||||
(vary-meta node (partial merge (meta require-node)))
|
||||
|
||||
:else
|
||||
(printf "Don't know how to figure out what namespace is being required in %s\n" (pr-str node)))))
|
||||
args)))
|
||||
|
||||
(defn- ns-form-node->ns-symb [ns-form-node]
|
||||
(some-> (some (fn [node]
|
||||
(when (and (hooks/token-node? node)
|
||||
(not= (hooks/sexpr node) 'ns))
|
||||
node))
|
||||
(:children ns-form-node))
|
||||
hooks/sexpr))
|
||||
|
||||
(defn- module
|
||||
"E.g.
|
||||
|
||||
(module 'metabase.qp.middleware.wow) => 'metabase.qp"
|
||||
[ns-symb]
|
||||
(some-> (re-find #"^metabase\.[^.]+" (str ns-symb)) symbol))
|
||||
|
||||
(defn- ignored-namespace? [ns-symb config]
|
||||
(some
|
||||
(fn [pattern-str]
|
||||
(re-find (re-pattern pattern-str) (str ns-symb)))
|
||||
(:ignored-namespace-patterns config)))
|
||||
|
||||
(defn- module-api-namespaces
|
||||
"Set API namespaces for a given module. `:any` means you can use anything, there are no API namespaces for this
|
||||
module (yet). If unspecified, the default is just the namespace with the same name as the module e.g.
|
||||
`metabase.db`."
|
||||
[module config]
|
||||
(let [module-config (get-in config [:api-namespaces module])]
|
||||
(cond
|
||||
(= module-config :any)
|
||||
nil
|
||||
|
||||
(set? module-config)
|
||||
module-config
|
||||
|
||||
:else
|
||||
#{module})))
|
||||
|
||||
(defn- lint-modules [ns-form-node config]
|
||||
(let [ns-symb (ns-form-node->ns-symb ns-form-node)]
|
||||
(when-not (ignored-namespace? ns-symb config)
|
||||
(when-let [current-module (module ns-symb)]
|
||||
(let [allowed-modules (get-in config [:allowed-modules current-module])
|
||||
required-namespace-symb-nodes (-> ns-form-node
|
||||
ns-form-node->require-node
|
||||
require-node->namespace-symb-nodes)]
|
||||
(doseq [node required-namespace-symb-nodes
|
||||
:let [clj-kondo-ignore (some-> (meta node) :clj-kondo/ignore hooks/sexpr set)]
|
||||
:when (not (contains? clj-kondo-ignore :metabase/ns-module-checker))
|
||||
:let [required-namespace (hooks/sexpr node)
|
||||
required-module (module required-namespace)]
|
||||
;; ignore stuff not in a module i.e. non-Metabase stuff.
|
||||
:when required-module
|
||||
:let [in-current-module? (= required-module current-module)]
|
||||
:when (not in-current-module?)
|
||||
:let [allowed-module? (or (= allowed-modules :any)
|
||||
(contains? (set allowed-modules) required-module))
|
||||
module-api-namespaces (module-api-namespaces required-module config)
|
||||
allowed-module-namespace? (or (empty? module-api-namespaces)
|
||||
(contains? module-api-namespaces required-namespace))]]
|
||||
(when-let [error (cond
|
||||
(not allowed-module?)
|
||||
(format "Module %s should not be used in the %s module. [:metabase/ns-module-checker :allowed-modules %s]"
|
||||
required-module
|
||||
current-module
|
||||
current-module)
|
||||
|
||||
(not allowed-module-namespace?)
|
||||
(format "Namespace %s is not an allowed external API namespace for the %s module. [:metabase/ns-module-checker :api-namespaces %s]"
|
||||
required-namespace
|
||||
required-module
|
||||
required-module))]
|
||||
(hooks/reg-finding! (assoc (meta node)
|
||||
:message error
|
||||
:type :metabase/ns-module-checker)))))))))
|
||||
|
||||
(defn lint-ns [x]
|
||||
(lint-require-shapes (:node x))
|
||||
(lint-modules (:node x) (get-in x [:config :linters :metabase/ns-module-checker]))
|
||||
x)
|
||||
@@ -22,7 +22,6 @@
|
||||
metabase.actions.test-util/with-actions-test-data
|
||||
metabase.actions.test-util/with-actions-test-data-and-actions-enabled
|
||||
metabase.actions.test-util/with-actions-test-data-tables
|
||||
metabase.analytics.snowplow-test/with-fake-snowplow-collector
|
||||
metabase.email-test/with-expected-messages
|
||||
metabase.email-test/with-fake-inbox
|
||||
metabase.test.data.users/with-group
|
||||
@@ -32,6 +31,7 @@
|
||||
metabase.test.util.log/with-log-messages-for-level
|
||||
metabase.test.util.misc/with-single-admin-user
|
||||
metabase.test.util/with-all-users-permission
|
||||
metabase.test.util/with-column-remappings
|
||||
metabase.test.util/with-discarded-collections-perms-changes
|
||||
metabase.test.util/with-env-keys-renamed-by
|
||||
metabase.test.util/with-locale
|
||||
@@ -49,6 +49,7 @@
|
||||
metabase.test/with-actions-test-data-and-actions-enabled
|
||||
metabase.test/with-actions-test-data-tables
|
||||
metabase.test/with-all-users-permission
|
||||
metabase.test/with-column-remappings
|
||||
metabase.test/with-discarded-collections-perms-changes
|
||||
metabase.test/with-env-keys-renamed-by
|
||||
metabase.test/with-expected-messages
|
||||
@@ -376,15 +376,8 @@
|
||||
(when (hooks/token-node? node)
|
||||
(let [sexpr (hooks/sexpr node)]
|
||||
(when (symbol? sexpr)
|
||||
(let [resolved (hooks/resolve {:name sexpr})]
|
||||
(cond
|
||||
(and resolved (:ns resolved))
|
||||
(symbol (name (:ns resolved)) (name (:name resolved)))
|
||||
|
||||
;; if it wasn't resolved but is still qualified it's probably using the full namespace name rather than an
|
||||
;; alias.
|
||||
(qualified-symbol? sexpr)
|
||||
sexpr)))))
|
||||
(when-let [resolved (hooks/resolve {:name sexpr})]
|
||||
(symbol (name (:ns resolved)) (name (:name resolved)))))))
|
||||
;; some symbols like `*count/Integer` aren't resolvable.
|
||||
(catch Exception _
|
||||
nil)))
|
||||
@@ -38,6 +38,8 @@
|
||||
engines
|
||||
enum-cardinality-threshold
|
||||
follow-up-email-sent
|
||||
ga-code
|
||||
ga-enabled
|
||||
google-auth-auto-create-accounts-domain
|
||||
google-auth-client-id
|
||||
google-auth-configured
|
||||
@@ -162,6 +164,7 @@
|
||||
token-status
|
||||
toucan-name
|
||||
uncached-setting
|
||||
uploads-table-prefix
|
||||
user-visibility
|
||||
version
|
||||
version-info
|
||||
@@ -54,24 +54,19 @@
|
||||
(str (api/sexpr f) "f"))
|
||||
:type :metabase/validate-logging))))
|
||||
|
||||
(defn- format-node? [node]
|
||||
(when (api/list-node? node)
|
||||
(let [[x] (:children node)]
|
||||
(and (api/token-node? x)
|
||||
(or (= (hooks.common/node->qualified-symbol x) 'clojure.core/format)
|
||||
(= (api/sexpr x) 'format))))))
|
||||
|
||||
(defn- warn-against-log+format-instead-of-logf
|
||||
"Tell people to use things like infof instead of info + format."
|
||||
[{[f] :children, :as node} [x :as args]]
|
||||
(when (and (= (count args) 1)
|
||||
(api/list-node? x))
|
||||
(when (format-node? x)
|
||||
(api/reg-finding! (assoc (meta node)
|
||||
:message (format "Use %s instead of %s + format"
|
||||
(str (api/sexpr f) "f")
|
||||
(api/sexpr f))
|
||||
:type :metabase/validate-logging)))))
|
||||
(let [[y] (:children x)]
|
||||
(when (and (api/token-node? y)
|
||||
(= (hooks.common/node->qualified-symbol y) 'clojure.core/format))
|
||||
(api/reg-finding! (assoc (meta node)
|
||||
:message (format "Use %s instead of %s + format"
|
||||
(str (api/sexpr f) "f")
|
||||
(api/sexpr f))
|
||||
:type :metabase/validate-logging))))))
|
||||
|
||||
(defn info
|
||||
"Valid log, debug, etc."
|
||||
@@ -79,8 +74,7 @@
|
||||
(common-checks node)
|
||||
(let [[_f & args] (:children node)
|
||||
[_e & [x :as args]] (if (and (api/token-node? (first args))
|
||||
(or (api/string-node? (second args))
|
||||
(format-node? (second args))))
|
||||
(api/string-node? (second args)))
|
||||
args
|
||||
(cons nil args))]
|
||||
(when (api/string-node? x)
|
||||
@@ -124,3 +118,40 @@
|
||||
(check-for-i18n-format-specifiers node format-string)
|
||||
(check-format-string-arg-count node format-string args)))
|
||||
x)
|
||||
|
||||
(comment
|
||||
;; should fail, missing a format arg
|
||||
(infof
|
||||
{:node (api/parse-string
|
||||
(str '(log/warnf "Migration lock was acquired after %d retries.")))})
|
||||
|
||||
(infof
|
||||
{:node (api/parse-string
|
||||
(str '(log/warnf e "Migration lock was acquired after %d retries.")))})
|
||||
|
||||
;; should fail, too many format args
|
||||
(infof
|
||||
{:node (api/parse-string
|
||||
(str '(log/warnf "Migration lock was acquired after %d retries." 1 2)))})
|
||||
|
||||
(infof
|
||||
{:node (api/parse-string
|
||||
(str '(log/warnf e "Migration lock was acquired after %d retries." 1 2)))})
|
||||
|
||||
(infof
|
||||
{:node (api/parse-string
|
||||
(str '(log/warnf "Migration lock was acquired after {0} retries." 1)))})
|
||||
|
||||
;; should fail, has format args but is warn rather than warnf
|
||||
(info
|
||||
{:node (api/parse-string
|
||||
(str '(log/warn e "Migration lock was acquired after %d retries." 1 2)))})
|
||||
|
||||
;; should fail -- should not use i18n/tru or i18n/trs
|
||||
(infof
|
||||
{:node (api/parse-string
|
||||
(str '(log/warnf (metabase.util.i18n/tru "Migration lock was acquired after {0} retries." 1))))})
|
||||
|
||||
(info
|
||||
{:node (api/parse-string
|
||||
(str '(log/warn (metabase.util.i18n/trs "Migration lock was acquired after {0} retries." 1))))}))
|
||||
@@ -1,7 +1,26 @@
|
||||
(ns macros.metabase.api.common)
|
||||
(ns macros.metabase.api.common
|
||||
(:require
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defmacro define-routes
|
||||
"Macro for api.common/define-routes"
|
||||
[& args]
|
||||
`(do (def ~'routes "docstring" nil)
|
||||
~@args))
|
||||
|
||||
(defn route-fn-name
|
||||
"route fn hook"
|
||||
[method route]
|
||||
(let [route (if (vector? route) (first route) route)]
|
||||
(-> (str (name method) route)
|
||||
(str/replace #"/" "_")
|
||||
symbol)))
|
||||
|
||||
(defmacro defendpoint
|
||||
"Macro for api.common/defendpoint*"
|
||||
[method route & body]
|
||||
(let [method-fn (symbol "compojure.core" (str method))
|
||||
route-name (route-fn-name method route)]
|
||||
`(do
|
||||
~method-fn
|
||||
(defn ~route-name ~@body))))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(ns macros.metabase.xrays.domain-entities.malli)
|
||||
(ns macros.metabase.domain-entities.malli)
|
||||
|
||||
(defmacro define-getters-and-setters [schema & defs]
|
||||
`(do
|
||||
@@ -1,45 +0,0 @@
|
||||
(ns hooks.metabase.api.common
|
||||
(:require
|
||||
[clj-kondo.hooks-api :as api]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defn route-fn-name
|
||||
"route fn hook"
|
||||
[method route]
|
||||
(let [route (if (vector? route) (first route) route)]
|
||||
(-> (str (name method) route)
|
||||
(str/replace #"/" "_")
|
||||
symbol)))
|
||||
|
||||
(defn defendpoint
|
||||
[arg]
|
||||
(letfn [(update-defendpoint [node]
|
||||
(let [[_defendpoint method route & body] (:children node)]
|
||||
(api/list-node
|
||||
(list
|
||||
(api/token-node 'do)
|
||||
(api/token-node (symbol "compojure.core" (str (api/sexpr method))))
|
||||
(-> (api/list-node
|
||||
(list*
|
||||
(api/token-node 'clojure.core/defn)
|
||||
(api/token-node (route-fn-name (api/sexpr method) (api/sexpr route)))
|
||||
body))
|
||||
(with-meta (meta node)))))))]
|
||||
(update arg :node update-defendpoint)))
|
||||
|
||||
(comment
|
||||
(-> {:node (-> '(api/defendpoint POST "/:id/copy"
|
||||
"Copy a `Card`, with the new name 'Copy of _name_'"
|
||||
[id]
|
||||
{id [:maybe ms/PositiveInt]}
|
||||
(let [orig-card (api/read-check Card id)
|
||||
new-name (str (trs "Copy of ") (:name orig-card))
|
||||
new-card (assoc orig-card :name new-name)]
|
||||
(-> (card/create-card! new-card @api/*current-user*)
|
||||
hydrate-card-details
|
||||
(assoc :last-edit-info (last-edit/edit-information-for-user @api/*current-user*)))))
|
||||
pr-str
|
||||
api/parse-string)}
|
||||
defendpoint
|
||||
:node
|
||||
api/sexpr))
|
||||
@@ -1,19 +0,0 @@
|
||||
(ns ^:mb/once hooks.common-test
|
||||
(:require
|
||||
[clj-kondo.hooks-api :as api]
|
||||
[clj-kondo.impl.utils]
|
||||
[clojure.test :refer :all]
|
||||
[hooks.common]))
|
||||
|
||||
(deftest ^:parallel node->qualified-symbol-test
|
||||
(binding [clj-kondo.impl.utils/*ctx* {:namespaces (atom nil)}]
|
||||
(is (= 'metabase.util.i18n/tru
|
||||
(hooks.common/node->qualified-symbol (api/parse-string "metabase.util.i18n/tru"))))))
|
||||
|
||||
(deftest ^:parallel node->qualified-symbol-test-2
|
||||
(binding [clj-kondo.impl.utils/*ctx* {:namespaces (atom {:clj {:clj '{hooks.common-test {:qualify-ns {i18n metabase.util.i18n}}}}})
|
||||
:lang :clj
|
||||
:base-lang :clj
|
||||
:ns {:name 'hooks.common-test}}]
|
||||
(is (= 'metabase.util.i18n/tru
|
||||
(hooks.common/node->qualified-symbol (api/parse-string "i18n/tru"))))))
|
||||
@@ -1,77 +0,0 @@
|
||||
(ns ^:mb/once hooks.metabase.util.log-test
|
||||
(:require
|
||||
[clj-kondo.hooks-api :as api]
|
||||
[clj-kondo.impl.utils]
|
||||
[clojure.string :as str]
|
||||
[clojure.test :refer :all]
|
||||
[hooks.metabase.util.log]))
|
||||
|
||||
(defn- warnings
|
||||
[form]
|
||||
(let [f (if (str/ends-with? (name (first form)) "f")
|
||||
hooks.metabase.util.log/infof
|
||||
hooks.metabase.util.log/info)]
|
||||
(binding [clj-kondo.impl.utils/*ctx* {:config {:linters {:metabase/validate-logging {:level :warning}}}
|
||||
:ignores (atom nil)
|
||||
:findings (atom [])
|
||||
:namespaces (atom {})}]
|
||||
(f {:node (api/parse-string (pr-str form))})
|
||||
(mapv :message @(:findings clj-kondo.impl.utils/*ctx*)))))
|
||||
|
||||
(deftest ^:parallel warn-on-missing-format-args-test
|
||||
(testing "should fail, missing a format arg"
|
||||
(are [form] (= ["log format string expects 1 arguments instead of 0."]
|
||||
(warnings (quote form)))
|
||||
(metabase.util.log/warnf "Migration lock was acquired after %d retries.")
|
||||
(metabase.util.log/warnf e "Migration lock was acquired after %d retries."))))
|
||||
|
||||
(deftest ^:parallel warn-on-too-many-format-args-test-1
|
||||
(testing "should fail, too many format args"
|
||||
(are [form] (= ["log format string expects 1 arguments instead of 2."]
|
||||
(warnings (quote form)))
|
||||
(metabase.util.log/warnf "Migration lock was acquired after %d retries." 1 2)
|
||||
(metabase.util.log/warnf e "Migration lock was acquired after %d retries." 1 2))))
|
||||
|
||||
(deftest ^:parallel warn-on-too-many-format-args-test-2
|
||||
(testing "should fail, too many format args"
|
||||
(are [form] (= ["this looks like an i18n format string. Don't use identifiers like {0} in logging."
|
||||
"Don't use metabase.util.log/warnf with no format string arguments, use metabase.util.log/warn instead."
|
||||
"log format string expects 0 arguments instead of 1."]
|
||||
(warnings (quote form)))
|
||||
(metabase.util.log/warnf "Migration lock was acquired after {0} retries." 1)
|
||||
(metabase.util.log/warnf e "Migration lock was acquired after {0} retries." 1))))
|
||||
|
||||
(deftest ^:parallel warn-on-format-args-without-logf-test
|
||||
(testing "should fail, has format args but is warn rather than warnf"
|
||||
(are [form] (= ["metabase.util.log/warn used with a format string, use metabase.util.log/warnf instead."]
|
||||
(warnings (quote form)))
|
||||
(metabase.util.log/warn "Migration lock was acquired after %d retries." 1)
|
||||
(metabase.util.log/warn e "Migration lock was acquired after %d retries." 1))))
|
||||
|
||||
(deftest ^:parallel warn-on-format-without-logf-test
|
||||
(testing "should fail, has format args but is warn rather than warnf"
|
||||
(are [form] (= ["Use metabase.util.log/warnf instead of metabase.util.log/warn + format"]
|
||||
(warnings (quote form)))
|
||||
(metabase.util.log/warn (format "Migration lock was acquired after %d retries." 1))
|
||||
(metabase.util.log/warn e (format "Migration lock was acquired after %d retries." 1)))))
|
||||
|
||||
(deftest ^:parallel warn-on-logf-with-no-format-args-test
|
||||
(testing "should fail, has format args but is warn rather than warnf"
|
||||
(are [form] (= ["Don't use metabase.util.log/warnf with no format string arguments, use metabase.util.log/warn instead."]
|
||||
(warnings (quote form)))
|
||||
(metabase.util.log/warnf "Migration lock cleared.")
|
||||
(metabase.util.log/warnf e "Migration lock cleared."))))
|
||||
|
||||
(deftest ^:parallel warn-on-i18n-test-1
|
||||
(testing "should fail -- should not use i18n/tru or i18n/trs"
|
||||
(are [form] (= ["do not i18n the logs!"]
|
||||
(warnings (quote form)))
|
||||
(metabase.util.log/warnf (metabase.util.i18n/tru "Migration lock was acquired after {0} retries." 1))
|
||||
(metabase.util.log/warnf e (metabase.util.i18n/tru "Migration lock was acquired after {0} retries." 1)))))
|
||||
|
||||
(deftest ^:parallel warn-on-i18n-test-2
|
||||
(testing "should fail -- should not use i18n/tru or i18n/trs"
|
||||
(are [form] (= ["do not i18n the logs!"]
|
||||
(warnings (quote form)))
|
||||
(metabase.util.log/warn (metabase.util.i18n/trs "Migration lock was acquired after {0} retries." 1))
|
||||
(metabase.util.log/warn e (metabase.util.i18n/trs "Migration lock was acquired after {0} retries." 1)))))
|
||||
5
.github/actions/build-e2e-matrix/action.yml
vendored
@@ -16,6 +16,7 @@ runs:
|
||||
const java = 11;
|
||||
|
||||
const defaultRunner = "ubuntu-22.04";
|
||||
const beefierRunner = "buildjet-2vcpu-ubuntu-2204";
|
||||
|
||||
const defaultOptions = {
|
||||
"java-version": java,
|
||||
@@ -36,9 +37,7 @@ runs:
|
||||
["dashboard-filters", {} ],
|
||||
["embedding", {} ],
|
||||
["filters", {} ],
|
||||
["filters-reproductions", {}],
|
||||
["joins", {} ],
|
||||
["metrics", {} ],
|
||||
["models", {} ],
|
||||
["native", {} ],
|
||||
["native-filters", {} ],
|
||||
@@ -46,8 +45,6 @@ runs:
|
||||
["organization", {} ],
|
||||
["permissions", {} ],
|
||||
["question", {} ],
|
||||
["question-reproductions", {} ],
|
||||
["search", {}],
|
||||
["sharing", {} ],
|
||||
["visualizations-charts", {} ],
|
||||
["visualizations-tabular", {} ],
|
||||
|
||||
2
.github/actions/prepare-frontend/action.yml
vendored
@@ -23,6 +23,6 @@ runs:
|
||||
if: ${{ !contains(github.event.head_commit.message, '[ci nocache]') }}
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-node-modules-${{ hashFiles('**/yarn.lock', '**/patches/*.patch') }}
|
||||
key: ${{ runner.os }}-node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
- run: yarn install --frozen-lockfile --prefer-offline
|
||||
shell: bash
|
||||
|
||||
86
.github/github-slack-map.json
vendored
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"abdhabli": "U06BAV8JFDW",
|
||||
"adam-james-v": "U02P27ZRRR8",
|
||||
"agodbey": "U05UJR2C35Z",
|
||||
"albertoperdomo": "U05811B1WLX",
|
||||
"AlessioLaiso": "U06MAAUDTS6",
|
||||
"alexandermkinn": "U023UTA4MUL",
|
||||
"alexyarosh": "U06GXH3RVPU",
|
||||
"alxnddr": "U01S9BUHH8X",
|
||||
"brunobergher": "U01M2JJVA80",
|
||||
"bshepherdson": "U03AK3B43GA",
|
||||
"calherries": "U03KFGJ7X8S",
|
||||
"camsaul": "U07DG6C3X",
|
||||
"cbalusek": "U02M2Q0DJLD",
|
||||
"cdeweyx": "U02BX2BKPQS",
|
||||
"crisptrutski": "U06C5MNFF0S",
|
||||
"dahyeik": "U03MG3BCS22",
|
||||
"darksciencebase": "U04P2DVHG3U",
|
||||
"deniskaber": "U04QX6Z5N00",
|
||||
"devurandom": "U03N1ATKF7T",
|
||||
"dhuniverse": "U04RRCGJPJN",
|
||||
"dpsutton": "U01BP8Z3CVA",
|
||||
"EmmadUsmani": "U04QX6YUP7A",
|
||||
"escherize": "U02U4E60EHG",
|
||||
"filipesilva": "U04S45X3FLN",
|
||||
"FilmonK": "U05J39TB4A1",
|
||||
"gusaiani": "U020JGYQHK8",
|
||||
"heypoom": "U06TVDSUPGE",
|
||||
"iethree": "U5A85JL4V",
|
||||
"ignacio-mb": "U0558P1CZ5L",
|
||||
"imrkd": "U02MJBX8G65",
|
||||
"ixipixi": "U06C5JCNKM1",
|
||||
"jeff-bruemmer": "U014JGU9XK2",
|
||||
"JesseSDevaney": "U0511SK58DC",
|
||||
"jessillions": "U04P2AKMX4K",
|
||||
"jesusfloresmetabase": "U04MZ6TGQLA",
|
||||
"jill-lafond": "U0537V0L2DN",
|
||||
"johnswanson": "U0600BZ1XMK",
|
||||
"jrayski": "U03C28SM11N",
|
||||
"k8beeman": "U06PYT3N7EV",
|
||||
"kamilmielnik": "U057ENEC60M",
|
||||
"kdoh": "U078VJFED",
|
||||
"kidd": "U01JM8WM6N4",
|
||||
"kulyk": "U01TH98M6J2",
|
||||
"lbrdnk": "U06035L3V34",
|
||||
"le0li0n": "U06RDA3M6BZ",
|
||||
"likeshumidity": "U047NDX34UU",
|
||||
"losrebellos": "U022B12KVK6",
|
||||
"luizarakaki": "U02KWASDKHC",
|
||||
"margaretrimek": "U02AZVBQQU9",
|
||||
"maxzheng": "U03TBN466EN",
|
||||
"mazameli": "U0ALDAVHA",
|
||||
"metamben": "U03AN4TRM6Y",
|
||||
"mngr": "U06GXDTJQQ3",
|
||||
"mwsmales": "U043FSUUSNL",
|
||||
"nemanjaglumac": "U01BA9754AC",
|
||||
"NevRA": "U04T9044T7G",
|
||||
"ngapuileung": "U04HP1D66N4",
|
||||
"noahmoss": "U01V8S8DG78",
|
||||
"npfitz": "U037YBQFRR7",
|
||||
"npretto": "U05K43X7RV5",
|
||||
"oisincoveney": "U0511SKLXCN",
|
||||
"Onlinehead": "U02S8HGAB8A",
|
||||
"oreonl": "U05V7TSK1QQ",
|
||||
"paoliniluis": "U01GWGPG2CF",
|
||||
"perivamsi": "U05K2EFAT5G",
|
||||
"piranha": "U060FQBFE5P",
|
||||
"psalinasy": "U04LYLXV207",
|
||||
"qnkhuat": "U02LA6FF5N1",
|
||||
"rafpaf": "U0697CU8TTP",
|
||||
"ranquild": "U028HG073GS",
|
||||
"romeovs": "U06DHN2JA5D",
|
||||
"salsakran": "U078V228G",
|
||||
"sloansparger": "U06CJAUPV3K",
|
||||
"snoe": "U03AG715B61",
|
||||
"Somtom": "U06BREDB5V3",
|
||||
"taqattack": "U06C70CJ6RM",
|
||||
"Tony-metabase": "U03RFTD5SLR",
|
||||
"trinya": "U06CJJB3JJZ",
|
||||
"tsmacdonald": "U01BKUL0MHV",
|
||||
"uladzimirdev": "U04TU6TNPLZ",
|
||||
"vbenedetti": "U04MRS3JTLH",
|
||||
"victoriaspek": "U02KD3E703E",
|
||||
"WiNloSt": "U02MYNXD605",
|
||||
"zbodi74": "U05EV72TPN2"
|
||||
}
|
||||
3
.github/team.json
vendored
@@ -14,7 +14,6 @@
|
||||
{
|
||||
"name": "Embedding",
|
||||
"label": ".Team/Embedding",
|
||||
"projectUrl": "https://github.com/orgs/metabase/projects/88/views/1",
|
||||
"members": ["WiNloSt", "deniskaber", "oisincoveney", "npretto", "heypoom"]
|
||||
},
|
||||
{
|
||||
@@ -32,7 +31,7 @@
|
||||
{
|
||||
"name": "Query Processor",
|
||||
"label": ".Team/QueryProcessor",
|
||||
"projectUrl": "https://github.com/orgs/metabase/projects/83/views/8",
|
||||
"projectUrl": "https://github.com/orgs/metabase/projects/85/views/1",
|
||||
"members": ["camsaul", "snoe", "bshepherdson", "metamben", "lbrdnk"]
|
||||
},
|
||||
{
|
||||
|
||||
8
.github/workflows/auto-backport.yml
vendored
@@ -11,7 +11,11 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
|
||||
- uses: tibdex/github-app-token@v2.1.0
|
||||
id: generate-token
|
||||
with:
|
||||
app_id: ${{ secrets.METABASE_BOT_APP_ID }}
|
||||
private_key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}
|
||||
- uses: ./.github/actions/find-squashed-commit
|
||||
name: Find commit
|
||||
id: find_commit
|
||||
@@ -78,7 +82,7 @@ jobs:
|
||||
TARGET_BRANCH: ${{ steps.get_latest_release_branch.outputs.branch-name }}
|
||||
ORIGINAL_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
|
||||
ORIGINAL_TITLE: ${{ github.event.pull_request.title }}
|
||||
GITHUB_TOKEN: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
COMMIT: ${{ steps.find_commit.outputs.commit }}
|
||||
|
||||
- name: Auto approve backport PR
|
||||
|
||||
2
.github/workflows/build-for-release.yml
vendored
@@ -113,7 +113,7 @@ jobs:
|
||||
uses: actions/github-script@v7
|
||||
id: release_branch
|
||||
with:
|
||||
result-encoding: string
|
||||
result_encoding: string
|
||||
script: | # js
|
||||
const { getReleaseBranch } = require('${{ github.workspace }}/release/dist/index.cjs');
|
||||
const version = '${{ inputs.version }}';
|
||||
|
||||
37
.github/workflows/drivers-stress-test.yml
vendored
@@ -21,6 +21,7 @@ on:
|
||||
- Athena
|
||||
- BigQuery
|
||||
- Druid
|
||||
- Google Analytics
|
||||
- Google Classpath Test
|
||||
- Maria DB
|
||||
- Maria DB (latest)
|
||||
@@ -108,6 +109,42 @@ jobs:
|
||||
junit-name: 'be-tests-druid-ee'
|
||||
test-args: ":only ${{ inputs.test }} :times ${{ inputs.times }}"
|
||||
|
||||
be-tests-googleanalytics-ee:
|
||||
if: inputs.driver == 'Google Analytics'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
CI: 'true'
|
||||
DRIVERS: googleanalytics
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test Google Analytics driver
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
junit-name: 'be-tests-googleanalytics-ee'
|
||||
test-args: ":only ${{ inputs.test }} :times ${{ inputs.times }}"
|
||||
|
||||
be-google-related-drivers-classpath-test:
|
||||
if: inputs.driver == 'Google Classpath Test'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
CI: 'true'
|
||||
DRIVERS: 'googleanalytics,bigquery-cloud-sdk'
|
||||
MB_BIGQUERY_TEST_PROJECT_ID: ${{ secrets.BIGQUERY_TEST_PROJECT_ID }}
|
||||
MB_BIGQUERY_TEST_CLIENT_ID: ${{ secrets.MB_BIGQUERY_TEST_CLIENT_ID }}
|
||||
MB_BIGQUERY_TEST_CLIENT_SECRET: ${{ secrets.MB_BIGQUERY_TEST_CLIENT_SECRET }}
|
||||
MB_BIGQUERY_TEST_ACCESS_TOKEN: ${{ secrets.MB_BIGQUERY_TEST_ACCESS_TOKEN }}
|
||||
MB_BIGQUERY_TEST_REFRESH_TOKEN: ${{ secrets.MB_BIGQUERY_TEST_REFRESH_TOKEN }}
|
||||
MB_BIGQUERY_CLOUD_SDK_TEST_SERVICE_ACCOUNT_JSON: ${{ secrets.MB_BIGQUERY_CLOUD_SDK_TEST_SERVICE_ACCOUNT_JSON }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test Google Related Drivers Classpath
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
junit-name: 'be-google-related-drivers-classpath-test'
|
||||
test-args: ':only "[metabase.query-processor-test.expressions-test metabase.driver.google-test metabase.driver.googleanalytics-test ${{ inputs.test }}] :times ${{ inputs.times }}"'
|
||||
|
||||
be-tests-mariadb-10-2-ee:
|
||||
if: inputs.driver == 'Maria DB'
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
60
.github/workflows/drivers.yml
vendored
@@ -160,6 +160,66 @@ jobs:
|
||||
aws-region: ${{ vars.AWS_REGION }}
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-googleanalytics-ee:
|
||||
needs: files-changed
|
||||
if: github.event.pull_request.draft == false && needs.files-changed.outputs.backend_all == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
CI: 'true'
|
||||
DRIVERS: googleanalytics
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test Google Analytics driver
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
junit-name: 'be-tests-googleanalytics-ee'
|
||||
test-args: ":exclude-tags '[:mb/once]'"
|
||||
- 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-google-related-drivers-classpath-test:
|
||||
needs: files-changed
|
||||
if: github.event.pull_request.draft == false && needs.files-changed.outputs.backend_all == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
CI: 'true'
|
||||
DRIVERS: 'googleanalytics,bigquery-cloud-sdk'
|
||||
MB_BIGQUERY_TEST_PROJECT_ID: ${{ secrets.BIGQUERY_TEST_PROJECT_ID }}
|
||||
MB_BIGQUERY_TEST_CLIENT_ID: ${{ secrets.MB_BIGQUERY_TEST_CLIENT_ID }}
|
||||
MB_BIGQUERY_TEST_CLIENT_SECRET: ${{ secrets.MB_BIGQUERY_TEST_CLIENT_SECRET }}
|
||||
MB_BIGQUERY_TEST_ACCESS_TOKEN: ${{ secrets.MB_BIGQUERY_TEST_ACCESS_TOKEN }}
|
||||
MB_BIGQUERY_TEST_REFRESH_TOKEN: ${{ secrets.MB_BIGQUERY_TEST_REFRESH_TOKEN }}
|
||||
MB_BIGQUERY_CLOUD_SDK_TEST_SERVICE_ACCOUNT_JSON: ${{ secrets.MB_BIGQUERY_CLOUD_SDK_TEST_SERVICE_ACCOUNT_JSON }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test Google Related Drivers Classpath
|
||||
uses: ./.github/actions/test-driver
|
||||
with:
|
||||
junit-name: 'be-google-related-drivers-classpath-test'
|
||||
test-args: ':only "[metabase.query-processor-test.expressions-test metabase.driver.google-test metabase.driver.googleanalytics-test]"'
|
||||
- name: Upload Test Results
|
||||
uses: ./.github/actions/upload-test-results
|
||||
if: always()
|
||||
with:
|
||||
input-path: ./target/junit/
|
||||
output-name: ${{ github.job }}
|
||||
bucket: ${{ vars.AWS_S3_TEST_RESULTS_BUCKET }}
|
||||
aws-access-key-id: ${{ secrets.AWS_TEST_RESULTS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_TEST_RESULTS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ vars.AWS_REGION }}
|
||||
trunk-api-token: ${{ secrets.TRUNK_API_TOKEN }}
|
||||
|
||||
be-tests-mariadb-10-2-ee:
|
||||
needs: files-changed
|
||||
if: github.event.pull_request.draft == false && needs.files-changed.outputs.backend_all == 'true'
|
||||
|
||||
57
.github/workflows/e2e-tests.yml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
- "release-**"
|
||||
- 'release-**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
|
||||
@@ -87,11 +87,10 @@ jobs:
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
CYPRESS_PULL_REQUEST_ID: ${{ github.event.pull_request.number || '' }}
|
||||
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title || github.event.head_commit.message || github.even.head.sha }}
|
||||
COMMIT_INFO_MESSAGE : ${{ github.event.pull_request.title || github.event.head_commit.message || github.even.head.sha }}
|
||||
MB_SNOWPLOW_AVAILABLE: true
|
||||
MB_SNOWPLOW_URL: "http://localhost:9090" # Snowplow micro
|
||||
CYPRESS_REPLAYIO_ENABLED: 1
|
||||
CYPRESS_REPLAYIO_ENABLE_UPLOAD: 1
|
||||
RECORD_REPLAY_METADATA_FILE: /tmp/replay-metadata.json
|
||||
RECORD_REPLAY_METADATA_TEST_RUN_ID: ${{ github.run_id }}
|
||||
REPLAY_API_KEY: ${{ secrets.REPLAY_IO_TOKEN }}
|
||||
@@ -144,7 +143,7 @@ jobs:
|
||||
run: |
|
||||
yarn run test-cypress-run \
|
||||
--env grepTags=@OSS,grepOmitFiltered=true \
|
||||
--spec './e2e/test/scenarios/**/*.cy.spec.(js|ts)' \
|
||||
--spec './e2e/test/scenarios/**/*.cy.spec.js' \
|
||||
--browser 'replay-chromium'
|
||||
|
||||
- name: Run slow and resource-intensive Cypress tests
|
||||
@@ -152,7 +151,7 @@ jobs:
|
||||
run: |
|
||||
yarn run test-cypress-run \
|
||||
--env grepTags="@slow",grepOmitFiltered=true \
|
||||
--spec './e2e/test/scenarios/**/*.cy.spec.(js|ts)' \
|
||||
--spec './e2e/test/scenarios/**/*.cy.spec.js' \
|
||||
--browser 'replay-chromium'
|
||||
|
||||
- name: Run Flaky Cypress tests
|
||||
@@ -160,7 +159,7 @@ jobs:
|
||||
run: |
|
||||
yarn run test-cypress-run \
|
||||
--env grepTags="@flaky --@quarantine",grepOmitFiltered=true \
|
||||
--spec './e2e/test/scenarios/**/*.cy.spec.(js|ts)' \
|
||||
--spec './e2e/test/scenarios/**/*.cy.spec.js' \
|
||||
--browser 'replay-chromium'
|
||||
|
||||
- name: Run EE Cypress tests on ${{ matrix.name }}
|
||||
@@ -176,7 +175,7 @@ jobs:
|
||||
run: |
|
||||
yarn run test-cypress-run \
|
||||
--env grepTags="@mongo --@quarantine",grepOmitFiltered=true \
|
||||
--spec './e2e/test/scenarios/**/*.cy.spec.(js|ts)' \
|
||||
--spec './e2e/test/scenarios/**/*.cy.spec.js' \
|
||||
--browser 'replay-chromium'
|
||||
env:
|
||||
CYPRESS_QA_DB_MONGO: true
|
||||
@@ -217,3 +216,47 @@ jobs:
|
||||
steps:
|
||||
- run: |
|
||||
echo "Didn't run due to conditional filtering"
|
||||
|
||||
visual-regression-tests:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 60
|
||||
needs: [build]
|
||||
if: |
|
||||
!cancelled() && needs.build.result == 'success'
|
||||
name: percy-visual-regression-tests
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare Docker containers
|
||||
uses: ./.github/actions/e2e-prepare-containers
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
maildev: true
|
||||
|
||||
- name: Retrieve uberjar artifact for ${{ matrix.edition }}
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-ee-${{ github.event.pull_request.head.sha || github.sha }}-uberjar
|
||||
|
||||
- name: Get the version info
|
||||
run: |
|
||||
jar xf target/uberjar/metabase.jar version.properties
|
||||
mv version.properties resources/
|
||||
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
|
||||
- name: Prepare JDK 11
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Prepare Cypress environment
|
||||
uses: ./.github/actions/prepare-cypress
|
||||
|
||||
- name: Percy Test
|
||||
run: yarn run test-visual-run
|
||||
env:
|
||||
PERCY_TOKEN: ${{ github.ref == 'refs/heads/master' && secrets.PERCY_TOKEN || ''}}
|
||||
|
||||
15
.github/workflows/loki-update.yml
vendored
@@ -12,7 +12,6 @@ jobs:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
|
||||
ref: ${{ github.head_ref }}
|
||||
|
||||
- name: Prepare frontend environment
|
||||
@@ -45,19 +44,25 @@ jobs:
|
||||
- name: Update Loki Snapshots
|
||||
run: yarn test-visual:loki-update
|
||||
|
||||
- uses: tibdex/github-app-token@v2.1.0
|
||||
id: generate-token
|
||||
with:
|
||||
app_id: ${{ secrets.METABASE_BOT_APP_ID }}
|
||||
private_key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Commit and Push Changes
|
||||
run: |
|
||||
git config --global user.name "Metabase Automation"
|
||||
git config --global user.email "github-automation@metabase.com"
|
||||
git config --global user.name "Metabase bot"
|
||||
git config --global user.email "metabase-bot@metabase.com"
|
||||
git add .loki/**
|
||||
git commit -m "Update Loki Snapshots"
|
||||
git push
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
- name: Remove 'loki-update' label
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
github-token: ${{secrets.METABASE_AUTOMATION_USER_TOKEN}}
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
github.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
|
||||
91
.github/workflows/percy-issue-comment.yml
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
# Triggers Percy job by "@metabase-bot run visual tests" comment in a PR
|
||||
name: PercyIssueComment
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
pr_info:
|
||||
if: github.event.comment.body == '@metabase-bot run visual tests'
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
pull_request_number: ${{ fromJson(steps.fetch_pr.outputs.data).head.number }}
|
||||
branch_name: ${{ fromJson(steps.fetch_pr.outputs.data).head.ref }}
|
||||
commit_sha: ${{ fromJson(steps.fetch_pr.outputs.data).head.sha }}
|
||||
steps:
|
||||
- uses: tibdex/github-app-token@v2.1.0
|
||||
id: generate-token
|
||||
with:
|
||||
app_id: ${{ secrets.METABASE_BOT_APP_ID }}
|
||||
private_key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.pr_info.outputs.branch_name }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Verify Membership
|
||||
id: verify-membership
|
||||
uses: ./.github/actions/verify-membership
|
||||
with:
|
||||
github_token: ${{ steps.generate-token.outputs.token }}
|
||||
organization_name: metabase
|
||||
username: ${{ github.event.comment.user.login }}
|
||||
- run: |
|
||||
result=${{ steps.verify-membership.outputs.is_member }}
|
||||
if [ $result == false ]; then
|
||||
echo User ${{ github.event.comment.user.login }} is not a member of Metabase organization
|
||||
exit 1
|
||||
fi
|
||||
- name: Fetch issue
|
||||
uses: octokit/request-action@v2.x
|
||||
id: fetch_issue
|
||||
with:
|
||||
route: GET ${{ github.event.issue.url }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Fetch PR
|
||||
uses: octokit/request-action@v2.x
|
||||
id: fetch_pr
|
||||
with:
|
||||
route: GET ${{ fromJson(steps.fetch_issue.outputs.data).pull_request.url }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
percy:
|
||||
timeout-minutes: 30
|
||||
runs-on: buildjet-4vcpu-ubuntu-2004
|
||||
needs: [pr_info]
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
MB_EDITION: ee
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.pr_info.outputs.branch_name }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: percy-issue-comment
|
||||
|
||||
- name: Prepare cypress environment
|
||||
uses: ./.github/actions/prepare-cypress
|
||||
- run: ./bin/build.sh
|
||||
- name: Get the version info
|
||||
run: |
|
||||
jar xf target/uberjar/metabase.jar version.properties
|
||||
mv version.properties resources/
|
||||
- name: Run maildev
|
||||
run: docker run -d -p 1080:1080 -p 1025:1025 maildev/maildev:2.0.5
|
||||
- name: Percy Test
|
||||
run: yarn run test-visual-run
|
||||
env:
|
||||
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
|
||||
PERCY_COMMIT: ${{ needs.pr_info.outputs.commit_sha }}
|
||||
PERCY_BRANCH: ${{ needs.pr_info.outputs.branch_name }}
|
||||
PERCY_PULL_REQUEST: ${{ needs.pr_info.outputs.pull_request_number }}
|
||||
39
.github/workflows/percy-visual-label.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# Triggers Percy job on pull requests that contain "visual" label
|
||||
name: Percy visual tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [synchronize, labeled]
|
||||
|
||||
jobs:
|
||||
percy:
|
||||
if: contains(github.event.pull_request.labels.*.name, 'visual')
|
||||
timeout-minutes: 30
|
||||
runs-on: buildjet-4vcpu-ubuntu-2004
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
MB_EDITION: ee
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: percy-visual-label
|
||||
- name: Prepare cypress environment
|
||||
uses: ./.github/actions/prepare-cypress
|
||||
- run: ./bin/build.sh
|
||||
- name: Get the version info
|
||||
run: |
|
||||
jar xf target/uberjar/metabase.jar version.properties
|
||||
mv version.properties resources/
|
||||
- name: Run maildev
|
||||
run: docker run -d -p 1080:1080 -p 1025:1025 maildev/maildev:2.0.5
|
||||
- name: Percy Test
|
||||
run: yarn run test-visual-run
|
||||
env:
|
||||
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
|
||||
7
.github/workflows/pre-release.yml
vendored
@@ -114,16 +114,11 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
edition: [oss, ee]
|
||||
folder: [onboarding, search]
|
||||
env:
|
||||
MB_EDITION: ${{ matrix.edition }}
|
||||
DISPLAY: ""
|
||||
CYPRESS_ALL_FEATURES_TOKEN: ${{ secrets.ENTERPRISE_TOKEN }}
|
||||
CYPRESS_NO_FEATURES_TOKEN: ${{ secrets.E2E_STARTER_TOKEN }}
|
||||
CYPRESS_REPLAYIO_ENABLED: 1
|
||||
# disabled because of out of memory issues
|
||||
# probably related to https://github.com/cypress-io/cypress/issues/27415
|
||||
CYPRESS_NO_COMMAND_LOG: 1
|
||||
MB_SNOWPLOW_AVAILABLE: true
|
||||
MB_SNOWPLOW_URL: "http://localhost:9090" # Snowplow micro
|
||||
TERM: xterm
|
||||
@@ -163,7 +158,7 @@ jobs:
|
||||
- name: Run a few important Cypress tests as sanity check
|
||||
run: |
|
||||
mkdir -p ./target/uberjar && cp metabase.jar ./target/uberjar/metabase.jar
|
||||
yarn test-cypress-run --folder ${{ matrix.folder }}
|
||||
yarn test-cypress-run --folder onboarding
|
||||
|
||||
- name: Upload Cypress Artifacts upon failure
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
254
.github/workflows/release-embedding-sdk.yml
vendored
@@ -1,254 +0,0 @@
|
||||
name: Release Metabase Embedding SDK for React
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
# TODO: Add a version validation, so the workflow won't fail when publishing to npm
|
||||
sdk_version:
|
||||
description: 'SDK version (e.g. 0.1.3)'
|
||||
type: string
|
||||
required: true
|
||||
git_ref:
|
||||
description: 'Valid git reference e.g. branches, tags, hashes'
|
||||
type: string
|
||||
required: true
|
||||
|
||||
concurrency:
|
||||
# We want to ensure only one job is running at a time because
|
||||
# there could be a conflict when updating the readme file.
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check-git-tag:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
tag: embedding-sdk-${{ inputs.sdk_version }}
|
||||
steps:
|
||||
- name: Check out the code using the provided ref
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.git_ref }}
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: check tags
|
||||
run: |
|
||||
if [ $(git tag -l | grep $tag) ]
|
||||
then
|
||||
echo "::error::Tag '${{ env.tag }}' already exists. If you expect to run this workflow with the same tag, please remove the tag first and rerun this workflow again."
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
test:
|
||||
needs: check-git-tag
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Check out the code using the provided ref
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.git_ref }}
|
||||
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: "release-sdk"
|
||||
|
||||
- name: Run unit tests
|
||||
run: yarn embedding-sdk:test-unit
|
||||
|
||||
build-sdk:
|
||||
needs: test
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Check out the code using the provided ref
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.git_ref }}
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: "release-sdk"
|
||||
|
||||
- name: Update readme
|
||||
run: |
|
||||
./bin/embedding-sdk/release_utils.bash update_readme ${{ inputs.sdk_version }}
|
||||
|
||||
- name: Bump published npm package version
|
||||
run: |
|
||||
./bin/embedding-sdk/release_utils.bash update_package_json_template ${{ inputs.sdk_version }}
|
||||
|
||||
# TODO: Remove this step after the build utils script is merged to master
|
||||
- name: Upload release utils script, so it can be used later on when checking out `master` branch
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: release-util
|
||||
path: ./bin/embedding-sdk/release_utils.bash
|
||||
|
||||
- name: Update changelog
|
||||
run: |
|
||||
yarn embedding-sdk:generate-changelog
|
||||
|
||||
- name: Build SDK bundle
|
||||
run: yarn run build-embedding-sdk
|
||||
|
||||
- name: Generate SDK package.json in the build directory
|
||||
run: yarn run embedding-sdk:generate-package
|
||||
|
||||
- name: Upload built SDK package as artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: metabase-sdk
|
||||
path: ./resources/embedding-sdk
|
||||
|
||||
- name: Upload changelog
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdk-changelog
|
||||
path: ./enterprise/frontend/src/embedding-sdk/CHANGELOG.md
|
||||
|
||||
build-jar:
|
||||
needs: test
|
||||
uses: ./.github/workflows/uberjar-sdk.yml
|
||||
with:
|
||||
git_ref: ${{ inputs.git_ref }}
|
||||
image_name: embedding-sdk-${{ inputs.sdk_version }}
|
||||
secrets: inherit
|
||||
|
||||
upload-jar:
|
||||
needs: build-jar
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
name: Retrieve uberjar artifact
|
||||
with:
|
||||
name: metabase-ee-uberjar
|
||||
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_S3_RELEASE_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_S3_RELEASE_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ vars.AWS_REGION }}
|
||||
|
||||
- name: Upload uberjar to S3
|
||||
env:
|
||||
BUCKET: ${{ vars.AWS_S3_DOWNLOADS_BUCKET }}
|
||||
BUCKET_PATH: sdk/v${{ inputs.sdk_version }}/metabase.jar
|
||||
FILE: ./target/uberjar/metabase.jar
|
||||
shell: bash
|
||||
run: |
|
||||
aws s3 cp $FILE s3://$BUCKET/$BUCKET_PATH
|
||||
|
||||
publish-npm:
|
||||
needs: [build-sdk, upload-jar]
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Check out master to prepare for a SDK version bump PR
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# when we created version update PR, it would only have diff from 2 files SDK readme and SDK package.json template
|
||||
ref: master
|
||||
|
||||
- name: Setup git user
|
||||
run: |
|
||||
git config --global user.email "metabase-bot@metabase.com"
|
||||
git config --global user.name "Metabase bot"
|
||||
|
||||
# TODO: Remove this step after the build utils script is merged to master
|
||||
- name: Download release utils script
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: release-util
|
||||
path: ./bin/embedding-sdk/
|
||||
|
||||
- name: Update readme
|
||||
run: |
|
||||
bash ./bin/embedding-sdk/release_utils.bash update_readme ${{ inputs.sdk_version }}
|
||||
|
||||
- name: Bump published npm package version
|
||||
run: |
|
||||
bash ./bin/embedding-sdk/release_utils.bash update_package_json_template ${{ inputs.sdk_version }}
|
||||
|
||||
- name: Retrieve SDK changelog
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: sdk-changelog
|
||||
|
||||
# We need to do this because it's impossible to download an artifact to an existing location
|
||||
- name: Move over the downloaded changelog
|
||||
run: |
|
||||
mv CHANGELOG.md ./enterprise/frontend/src/embedding-sdk/CHANGELOG.md
|
||||
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ secrets.METABASE_BOT_APP_ID }}
|
||||
private-key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Create a PR updating readme + published version, and changelog
|
||||
run: |
|
||||
git checkout -b update-sdk-version-${{ inputs.sdk_version }}
|
||||
git commit -a -m 'Update Readme version references and published npm version to ${{ inputs.sdk_version }}'
|
||||
git push origin HEAD
|
||||
gh pr create --base master\
|
||||
--assignee "${GITHUB_ACTOR}"\
|
||||
--title "Update SDK version to ${{ inputs.sdk_version }}"\
|
||||
--body "Update Readme version references and published npm package version to ${{ inputs.sdk_version }}"
|
||||
gh pr edit --add-reviewer @metabase/embedding
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- name: Retrieve build SDK package artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-sdk
|
||||
path: sdk
|
||||
|
||||
- name: Publish to NPM
|
||||
run: |
|
||||
cd sdk
|
||||
echo //registry.npmjs.org/:_authToken=${{ secrets.NPM_RELEASE_TOKEN }} > .npmrc
|
||||
npm publish
|
||||
|
||||
git-tag:
|
||||
needs: publish-npm
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
tag: embedding-sdk-${{ inputs.sdk_version }}
|
||||
steps:
|
||||
- name: Check out the code using the provided ref
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.git_ref }}
|
||||
|
||||
- name: Setup git user
|
||||
run: |
|
||||
git config --global user.email "metabase-bot@metabase.com"
|
||||
git config --global user.name "Metabase bot"
|
||||
|
||||
- name: Create a new git tag
|
||||
run: |
|
||||
git tag ${{ env.tag }}
|
||||
|
||||
- name: Push the new tag
|
||||
id : push-tag
|
||||
run: |
|
||||
git push origin ${{ env.tag }}
|
||||
44
.github/workflows/require-percy-tests.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
name: Require Percy specs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
|
||||
jobs:
|
||||
files-changed:
|
||||
if: github.event.pull_request.draft == false && !contains(github.event.pull_request.labels.*.name, 'visual')
|
||||
name: Check which files changed
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 3
|
||||
outputs:
|
||||
visualizations: ${{ steps.changes.outputs.visualizations }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Test which files changed
|
||||
uses: dorny/paths-filter@v3.0.0
|
||||
id: changes
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
filters: .github/file-paths.yaml
|
||||
|
||||
add-label:
|
||||
needs: files-changed
|
||||
if: needs.files-changed.outputs.visualizations == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: tibdex/github-app-token@v2.1.0
|
||||
id: generate-token
|
||||
with:
|
||||
app_id: ${{ secrets.METABASE_BOT_APP_ID }}
|
||||
private_key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ steps.generate-token.outputs.token }}
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ["visual"]
|
||||
})
|
||||
157
.github/workflows/uberjar-sdk.yml
vendored
@@ -1,157 +0,0 @@
|
||||
name: Build + Docker Uberjar for SDK
|
||||
|
||||
on:
|
||||
# This workflow will be called from "release-embedding-sdk.yml"
|
||||
workflow_call:
|
||||
inputs:
|
||||
git_ref:
|
||||
description: 'Valid git reference e.g. branches, tags, hashes'
|
||||
type: string
|
||||
required: true
|
||||
image_name:
|
||||
description: Docker image used to upload to Dockerhub
|
||||
type: string
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build MB ${{ matrix.edition }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 40
|
||||
strategy:
|
||||
matrix:
|
||||
edition: [ee]
|
||||
env:
|
||||
MB_EDITION: ${{ matrix.edition }}
|
||||
INTERACTIVE: false
|
||||
steps:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.git_ref }}
|
||||
- name: Prepare front-end environment
|
||||
uses: ./.github/actions/prepare-frontend
|
||||
- name: Prepare back-end environment
|
||||
uses: ./.github/actions/prepare-backend
|
||||
with:
|
||||
m2-cache-key: uberjar
|
||||
- name: Build
|
||||
run: ./bin/build.sh
|
||||
- name: Prepare uberjar artifact
|
||||
uses: ./.github/actions/prepare-uberjar-artifact
|
||||
with:
|
||||
name: metabase-ee-uberjar
|
||||
|
||||
check_jar_health:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Is ${{ matrix.edition }} (java ${{ matrix.java-version }}) healthy?
|
||||
needs: build
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
edition: [ee]
|
||||
java-version: [11, 17]
|
||||
steps:
|
||||
- name: Prepare JRE (Java Run-time Environment)
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-package: jre
|
||||
java-version: ${{ matrix.java-version }}
|
||||
distribution: 'temurin'
|
||||
- run: java -version
|
||||
- uses: actions/download-artifact@v4
|
||||
name: Retrieve uberjar artifact
|
||||
with:
|
||||
name: metabase-ee-uberjar
|
||||
- name: Launch uberjar
|
||||
run: java -jar ./target/uberjar/metabase.jar &
|
||||
- name: Wait for Metabase to start
|
||||
run: while ! curl 'http://localhost:3000/api/health' | grep '{"status":"ok"}'; do sleep 1; done
|
||||
|
||||
containerize_test_and_push_container:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Containerize ${{ matrix.edition }}
|
||||
needs: check_jar_health
|
||||
strategy:
|
||||
matrix:
|
||||
edition: [ee]
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
steps:
|
||||
- name: Extract and clean branch name
|
||||
shell: bash
|
||||
run: echo "branch=$(echo $GITHUB_REF_NAME | sed 's/[^-._a-zA-Z0-9]/-/g')" >> $GITHUB_OUTPUT
|
||||
id: extract_branch
|
||||
|
||||
- name: Set image name to env
|
||||
run: echo "image_name=${{ inputs.image_name || steps.extract_branch.outputs.branch }}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Verify the intended tag of the container image
|
||||
run: echo "Container image will be tagged as ${{ env.image_name }}-${{ matrix.edition }}"
|
||||
|
||||
- name: Check out the code (Dockerfile needed)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.git_ref }}
|
||||
|
||||
- name: Download uploaded artifacts to insert into container
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: metabase-ee-uberjar
|
||||
path: bin/docker/
|
||||
|
||||
- name: Move the ${{ matrix.edition }} uberjar to the context dir
|
||||
run: mv bin/docker/target/uberjar/metabase.jar bin/docker/.
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v2.5.0
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Build ${{ matrix.edition }} container
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: bin/docker/.
|
||||
platforms: linux/amd64
|
||||
network: host
|
||||
tags: localhost:5000/metabase-dev:${{ env.image_name }}-${{ matrix.edition }}
|
||||
no-cache: true
|
||||
push: true
|
||||
|
||||
- name: Launch ${{ matrix.edition }} container
|
||||
run: docker run --rm -dp 3000:3000 localhost:5000/metabase-dev:${{ env.image_name }}-${{ matrix.edition }}
|
||||
timeout-minutes: 5
|
||||
|
||||
- name: Is Docker running?
|
||||
run: docker ps
|
||||
|
||||
- name: Wait for Metabase to start and reach 100% health
|
||||
run: while ! curl -s 'http://localhost:3000/api/health' | grep '{"status":"ok"}'; do sleep 1; done
|
||||
timeout-minutes: 3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Retag and push images
|
||||
run: docker tag localhost:5000/metabase-dev:${{ env.image_name }}-ee ${{ github.repository_owner }}/metabase-dev:${{ env.image_name }} && docker push ${{ github.repository_owner }}/metabase-dev:${{ env.image_name }}
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
env:
|
||||
TRIVY_OFFLINE_SCAN: true
|
||||
with:
|
||||
image-ref: docker.io/${{ github.repository_owner }}/metabase-dev:${{ env.image_name }}
|
||||
format: sarif
|
||||
output: trivy-results.sarif
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
4
.github/workflows/uberjar.yml
vendored
@@ -116,8 +116,6 @@ jobs:
|
||||
platforms: linux/amd64
|
||||
network: host
|
||||
tags: localhost:5000/metabase-dev:${{ steps.extract_branch.outputs.branch }}-${{ matrix.edition }}
|
||||
build-args: |
|
||||
GIT_COMMIT_SHA=${{ github.sha }}
|
||||
no-cache: true
|
||||
push: true
|
||||
- name: Launch ${{ matrix.edition }} container
|
||||
@@ -242,8 +240,6 @@ jobs:
|
||||
file: bin/docker/Dockerfile_ubuntu
|
||||
network: host
|
||||
tags: localhost:5000/metabase-dev:${{ steps.extract_branch.outputs.branch }}-${{ matrix.edition }}-ubuntu
|
||||
build-args: |
|
||||
GIT_COMMIT_SHA=${{ github.sha }}
|
||||
no-cache: true
|
||||
push: true
|
||||
- name: Launch ${{ matrix.edition }} Ubuntu based container
|
||||
|
||||
3
.gitignore
vendored
@@ -96,8 +96,7 @@ modules/drivers/*/.lsp/*
|
||||
.clj-kondo/*
|
||||
!.clj-kondo/README.md
|
||||
!.clj-kondo/config.edn
|
||||
!.clj-kondo/src/
|
||||
!.clj-kondo/test/
|
||||
!.clj-kondo/hooks/
|
||||
!.clj-kondo/macros/
|
||||
|
||||
# Editor- or environment-specific local files
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |