diff --git a/feature_flags.md b/feature_flags.md index d7f5d737c3..79c73b0556 100644 --- a/feature_flags.md +++ b/feature_flags.md @@ -22,7 +22,7 @@ For any usecase that is not Nuxt based, the code below is the preferred way of u ```typescript import { Environment } from '@speckle/shared' -if (Environment.getFeatureFlags().ENABLE_AUTOMATE_MODULE) +if (Environment.getFeatureFlags().FF_AUTOMATE_MODULE_ENABLED) console.log("Hurray I'm enabled") ``` @@ -34,7 +34,7 @@ So using the feature flag is the same as using any nuxt public runtime config va ```typescript const config = useRuntimeConfig() -if (config.public.ENABLE_AUTOMATE_MODULE) console.log("Hurray I'm enabled") +if (config.public.FF_AUTOMATE_MODULE_ENABLED) console.log("Hurray I'm enabled") ``` ## Definition @@ -53,6 +53,9 @@ To enable the specific feature, please add an environment variable to the `.env` > Note > > Since `znv` uses 1-1 name matching from the environment variables, we prefer using `MACRO_CASE` names. +> As a naming convention we've settled on prefixing the feature flags with `FF_`. +> After that, to provide some structure, the next word should categorize the flag into an app or module its meant to belong to. ie `FF_AUTOMATE_MODULE_ENABLED`. +> The names should also be declarative rather than imperative so that code like `if (FF_FLAG_NAME) { do something }` reads nicely. ## Deployment diff --git a/packages/frontend-2/composables/globals.ts b/packages/frontend-2/composables/globals.ts index b930e0860d..01b9481122 100644 --- a/packages/frontend-2/composables/globals.ts +++ b/packages/frontend-2/composables/globals.ts @@ -3,10 +3,10 @@ import { useGlobalToast } from '~/lib/common/composables/toast' export const useIsAutomateModuleEnabled = () => { const { - public: { ENABLE_AUTOMATE_MODULE } + public: { FF_AUTOMATE_MODULE_ENABLED } } = useRuntimeConfig() - return ref(ENABLE_AUTOMATE_MODULE) + return ref(FF_AUTOMATE_MODULE_ENABLED) } export { useGlobalToast, useActiveUser } diff --git a/packages/server/modules/automate/index.ts b/packages/server/modules/automate/index.ts index 8fb3a47424..5dc4f1a695 100644 --- a/packages/server/modules/automate/index.ts +++ b/packages/server/modules/automate/index.ts @@ -1,12 +1,36 @@ import { moduleLogger } from '@/logging/logging' -import { SpeckleModule } from '@/modules/shared/helpers/typeHelper' -import { ENABLE_AUTOMATE_MODULE } from '@/modules/shared/helpers/envHelper' +import { Optional, SpeckleModule } from '@/modules/shared/helpers/typeHelper' +import { VersionEvents, VersionsEmitter } from '@/modules/core/events/versionsEmitter' +import { onModelVersionCreate } from '@/modules/automate/services/trigger' +import { Environment } from '@speckle/shared' + +let quitListeners: Optional<() => void> = undefined + +const { FF_AUTOMATE_MODULE_ENABLED } = Environment.getFeatureFlags() const automateModule: SpeckleModule = { - async init() { - if (!ENABLE_AUTOMATE_MODULE) return + async init(_, isInitial) { + if (!FF_AUTOMATE_MODULE_ENABLED) return moduleLogger.info('⚙️ Init automate module') + + if (isInitial) { + quitListeners = initializeEventListeners() + } + }, + shutdown() { + if (!FF_AUTOMATE_MODULE_ENABLED) return + quitListeners?.() } } export = automateModule + +const initializeEventListeners = () => { + const quit = VersionsEmitter.listen( + VersionEvents.Created, + async ({ modelId, version }) => { + await onModelVersionCreate({ modelId, versionId: version.id }) + } + ) + return quit +} diff --git a/packages/server/modules/index.js b/packages/server/modules/index.js index 04d41ba47d..b72951e913 100644 --- a/packages/server/modules/index.js +++ b/packages/server/modules/index.js @@ -58,8 +58,8 @@ async function getSpeckleModules() { './accessrequests', './webhooks', './cross-server-sync', - './betaAutomations' - // './automate' + './betaAutomations', + './automate' ] for (const dir of moduleDirs) { diff --git a/packages/shared/src/environment/index.ts b/packages/shared/src/environment/index.ts index b66bd6c33d..f5813675d3 100644 --- a/packages/shared/src/environment/index.ts +++ b/packages/shared/src/environment/index.ts @@ -1,8 +1,10 @@ import { parseEnv } from 'znv' import { z } from 'zod' +//INFO +// As a convention all feature flags should be prefixed with a FF_ const featureFlagSchema = z.object({ - ENABLE_AUTOMATE_MODULE: z.boolean().default(false) + FF_AUTOMATE_MODULE_ENABLED: z.boolean().default(false) }) function parseFeatureFlags() { diff --git a/utils/helm/speckle-server/templates/frontend_2/deployment.yml b/utils/helm/speckle-server/templates/frontend_2/deployment.yml index 7c4c2aa4ba..98ee4a5e64 100644 --- a/utils/helm/speckle-server/templates/frontend_2/deployment.yml +++ b/utils/helm/speckle-server/templates/frontend_2/deployment.yml @@ -126,8 +126,8 @@ spec: value: {{ .Values.analytics.datadog_env | quote }} {{- end }} - - name: ENABLE_AUTOMATE_MODULE - value: {{ .Values.featureFlags.enableAutomateModule | quote }} + - name: FF_AUTOMATE_MODULE_ENABLED + value: {{ .Values.featureFlags.automateModuleEnabled | quote }} priorityClassName: high-priority {{- if .Values.frontend_2.affinity }} diff --git a/utils/helm/speckle-server/templates/server/deployment.yml b/utils/helm/speckle-server/templates/server/deployment.yml index d974e1c921..80d10b5752 100644 --- a/utils/helm/speckle-server/templates/server/deployment.yml +++ b/utils/helm/speckle-server/templates/server/deployment.yml @@ -111,8 +111,8 @@ spec: - name: ENABLE_FE2_MESSAGING value: {{ .Values.server.enableFe2Messaging | quote }} - - name: ENABLE_AUTOMATE_MODULE - value: {{ .Values.featureFlags.enableAutomateModule | quote }} + - name: FF_AUTOMATE_MODULE_ENABLED + value: {{ .Values.featureFlags.automateModuleEnabled | quote }} - name: ONBOARDING_STREAM_URL value: {{ .Values.server.onboarding.stream_url }} diff --git a/utils/helm/speckle-server/values.schema.json b/utils/helm/speckle-server/values.schema.json index 7737150054..db1dfef4e5 100644 --- a/utils/helm/speckle-server/values.schema.json +++ b/utils/helm/speckle-server/values.schema.json @@ -35,7 +35,7 @@ "featureFlags": { "type": "object", "properties": { - "enableAutomateModule": { + "automateModuleEnabled": { "type": "boolean", "description": "High level flag fully toggles the integrated automate module", "default": false diff --git a/utils/helm/speckle-server/values.yaml b/utils/helm/speckle-server/values.yaml index 363523cb0c..648ad40c94 100644 --- a/utils/helm/speckle-server/values.yaml +++ b/utils/helm/speckle-server/values.yaml @@ -35,8 +35,8 @@ cert_manager_issuer: letsencrypt-staging ## This object is a central location to define feature flags for the whole chart. ## @descriptionEnd featureFlags: - ## @param featureFlags.enableAutomateModule High level flag fully toggles the integrated automate module - enableAutomateModule: false + ## @param featureFlags.automateModuleEnabled High level flag fully toggles the integrated automate module + automateModuleEnabled: false analytics: ## @param analytics.enabled Enable or disable analytics