Skip to content

Commit 044312b

Browse files
authored
Merge pull request #1985 from appwrite/feat-feature-flags
Feat: Feature flags (simple)
2 parents 77642f6 + 96099f4 commit 044312b

File tree

8 files changed

+43
-18
lines changed

8 files changed

+43
-18
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PUBLIC_CONSOLE_MODE=self-hosted
2+
PUBLIC_CONSOLE_FEATURE_FLAGS=
23
PUBLIC_APPWRITE_MULTI_REGION=false
34
PUBLIC_APPWRITE_ENDPOINT=http://localhost/v1
4-
55
PUBLIC_STRIPE_KEY=
66
PUBLIC_GROWTH_ENDPOINT=

.github/workflows/publish.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ jobs:
7878
labels: ${{ steps.meta.outputs.labels }}
7979
build-args: |
8080
"PUBLIC_CONSOLE_MODE=cloud"
81+
"PUBLIC_CONSOLE_FEATURE_FLAGS="sites,csv-import"
8182
"PUBLIC_APPWRITE_MULTI_REGION=true"
8283
"PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}"
8384
"PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY_STAGE }}"
@@ -116,6 +117,7 @@ jobs:
116117
build-args: |
117118
"PUBLIC_CONSOLE_MODE=self-hosted"
118119
"PUBLIC_APPWRITE_MULTI_REGION=false"
120+
"PUBLIC_CONSOLE_FEATURE_FLAGS="sites,csv-import"
119121
"PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}"
120122
121123
publish-cloud-no-regions:
@@ -153,5 +155,6 @@ jobs:
153155
build-args: |
154156
"PUBLIC_CONSOLE_MODE=cloud"
155157
"PUBLIC_APPWRITE_MULTI_REGION=false"
158+
"PUBLIC_CONSOLE_FEATURE_FLAGS="sites,csv-import"
156159
"PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY_STAGE }}"
157160
"PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}"

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ADD ./src /app/src
2121
ADD ./static /app/static
2222

2323
ARG PUBLIC_CONSOLE_MODE
24+
ARG PUBLIC_CONSOLE_FEATURE_FLAGS
2425
ARG PUBLIC_APPWRITE_MULTI_REGION
2526
ARG PUBLIC_APPWRITE_ENDPOINT
2627
ARG PUBLIC_GROWTH_ENDPOINT
@@ -31,6 +32,7 @@ ARG SENTRY_RELEASE
3132
ENV PUBLIC_APPWRITE_ENDPOINT=$PUBLIC_APPWRITE_ENDPOINT
3233
ENV PUBLIC_GROWTH_ENDPOINT=$PUBLIC_GROWTH_ENDPOINT
3334
ENV PUBLIC_CONSOLE_MODE=$PUBLIC_CONSOLE_MODE
35+
ENV PUBLIC_CONSOLE_FEATURE_FLAGS=$PUBLIC_CONSOLE_FEATURE_FLAGS
3436
ENV PUBLIC_APPWRITE_MULTI_REGION=$PUBLIC_APPWRITE_MULTI_REGION
3537
ENV PUBLIC_STRIPE_KEY=$PUBLIC_STRIPE_KEY
3638
ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN

build.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ async function main() {
2424
log(bold().magenta('APPWRITE CONSOLE'));
2525
log();
2626
logEnv('CONSOLE MODE', env?.PUBLIC_CONSOLE_MODE);
27+
logEnv('CONSOLE FEATURE FLAGS', env?.PUBLIC_CONSOLE_FEATURE_FLAGS);
2728
logEnv('MULTI REGION', env?.PUBLIC_APPWRITE_MULTI_REGION);
2829
logEnv('APPWRITE ENDPOINT', env?.PUBLIC_APPWRITE_ENDPOINT, 'relative');
2930
logEnv('GROWTH ENDPOINT', env?.PUBLIC_GROWTH_ENDPOINT);

compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ services:
55
context: .
66
args:
77
PUBLIC_CONSOLE_MODE: ${PUBLIC_CONSOLE_MODE}
8+
PUBLIC_CONSOLE_FEATURE_FLAGS: ${PUBLIC_CONSOLE_FEATURE_FLAGS}
89
PUBLIC_APPWRITE_MULTI_REGION: ${PUBLIC_APPWRITE_MULTI_REGION}
910
PUBLIC_APPWRITE_ENDPOINT: ${PUBLIC_APPWRITE_ENDPOINT}
1011
PUBLIC_GROWTH_ENDPOINT: ${PUBLIC_GROWTH_ENDPOINT}
@@ -21,6 +22,7 @@ services:
2122
- build/
2223
environment:
2324
- PUBLIC_CONSOLE_MODE
25+
- PUBLIC_CONSOLE_FEATURE_FLAGS
2426
- PUBLIC_APPWRITE_MULTI_REGION
2527
- PUBLIC_APPWRITE_ENDPOINT
2628
- PUBLIC_GROWTH_ENDPOINT

src/lib/flags.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { env } from '$env/dynamic/public';
2+
import type { Account } from './stores/user';
3+
import type { Organization } from './stores/organization';
4+
5+
// Parse feature flags from env as a string array (exact match only)
6+
const flagsRaw = (env.PUBLIC_CONSOLE_FEATURE_FLAGS ?? '').split(',');
7+
8+
function isFlagEnabled(name: string) {
9+
// loose generic to allow safe access while retaining type safety
10+
return <T extends { account?: Account; organization?: Organization }>(data: T) => {
11+
const { account, organization } = data;
12+
13+
return !!(
14+
flagsRaw.includes(name) ||
15+
account?.prefs?.[`flags-${name}`] ||
16+
organization?.prefs?.[`flags-${name}`]
17+
);
18+
};
19+
}
20+
21+
export const flags = {
22+
showSites: isFlagEnabled('sites'),
23+
showCsvImport: isFlagEnabled('csv-import')
24+
};

src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
import { base } from '$app/paths';
2525
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
2626
import type { Models } from '@appwrite.io/console';
27-
import { organization } from '$lib/stores/organization';
28-
import { APPWRITE_OFFICIALS_ORG, isCloud } from '$lib/system';
27+
import { flags } from '$lib/flags';
2928
3029
export let data: PageData;
3130
@@ -88,14 +87,6 @@
8887
$isCsvImportInProgress = false;
8988
}
9089
}
91-
92-
/**
93-
* Controls visibility of CSV Imports feature:
94-
* - Shown if running on self-hosted
95-
* - Shown on cloud only if the organization is Appwrite's.
96-
* - Hidden on cloud for any non-Appwrite organization.
97-
*/
98-
$: showCsvImports = !isCloud || $organization.$id === APPWRITE_OFFICIALS_ORG;
9990
</script>
10091

10192
{#key page.params.collection}
@@ -109,7 +100,7 @@
109100
analyticsSource="database_documents" />
110101
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
111102
<ViewSelector view={data.view} {columns} hideView />
112-
{#if showCsvImports}
103+
{#if flags.showCsvImport(data)}
113104
<Button
114105
secondary
115106
event={Click.DatabaseImportCsv}

src/routes/(console)/project-[region]-[project]/sites/+page.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@ import { Query, type Models } from '@appwrite.io/console';
22
import { sdk } from '$lib/stores/sdk';
33
import { getLimit, getPage, getSearch, getView, pageToOffset, View } from '$lib/helpers/load';
44
import { CARD_LIMIT, Dependencies } from '$lib/constants';
5+
import { flags } from '$lib/flags';
6+
7+
export const load = async ({ url, depends, route, params, parent }) => {
8+
const data = await parent();
59

6-
export const load = async ({ url, depends, route, params }) => {
710
depends(Dependencies.SITES);
811
const page = getPage(url);
912
const search = getSearch(url);
1013
const limit = getLimit(url, route, CARD_LIMIT);
1114
const offset = pageToOffset(page, limit);
1215
const view = getView(url, route, View.Grid, View.Grid);
1316

14-
const sitesLive = false;
15-
16-
if (!sitesLive)
17+
if (!flags.showSites(data)) {
1718
return {
18-
sitesLive,
19+
sitesLive: false,
1920
offset,
2021
limit,
2122
search,
@@ -25,9 +26,10 @@ export const load = async ({ url, depends, route, params }) => {
2526
sites: []
2627
} as Models.SiteList
2728
};
29+
}
2830

2931
return {
30-
sitesLive,
32+
sitesLive: true,
3133
offset,
3234
limit,
3335
search,

0 commit comments

Comments
 (0)