Skip to content

Commit

Permalink
AXON-144: added experiment support in atlascode
Browse files Browse the repository at this point in the history
  • Loading branch information
cabella-dot committed Feb 21, 2025
1 parent 734f180 commit 820f7cd
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 7 deletions.
8 changes: 7 additions & 1 deletion src/lib/ipc/toUI/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ export enum CommonMessageType {
OnlineStatus = 'onlineStatus',
PMFStatus = 'pmfStatus',
UpdateFeatureFlags = 'updateFeatureFlags',
UpdateExperimentValues = 'updateExperimentValues',
}

export type CommonMessage =
| ReducerAction<CommonMessageType.Error, HostErrorMessage>
| ReducerAction<CommonMessageType.OnlineStatus, OnlineStatusMessage>
| ReducerAction<CommonMessageType.PMFStatus, PMFMessage>
| ReducerAction<CommonMessageType.UpdateFeatureFlags, UpdateFeatureFlagsMessage>;
| ReducerAction<CommonMessageType.UpdateFeatureFlags, UpdateFeatureFlagsMessage>
| ReducerAction<CommonMessageType.UpdateExperimentValues, UpdateExperimentValuesMessage>;

export interface HostErrorMessage {
reason: string;
Expand All @@ -28,3 +30,7 @@ export interface PMFMessage {
export interface UpdateFeatureFlagsMessage {
featureFlags: { [key: string]: boolean };
}

export interface UpdateExperimentValuesMessage {
experimentValues: { [key: string]: any };
}
18 changes: 16 additions & 2 deletions src/react/atlascode/onboarding/OnboardingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { CommonMessageType } from 'src/lib/ipc/toUI/common';
import { OnboardingActionType } from 'src/lib/ipc/fromUI/onboarding';
import { JiraOnboarding } from './JiraOnboarding';
import { BitbucketOnboarding } from './BitbucketOnboarding';
import { Experiments } from 'src/util/featureFlags/features';

const useStyles = makeStyles((theme: Theme) => ({
root: {
Expand Down Expand Up @@ -61,6 +62,7 @@ export const OnboardingPage: React.FunctionComponent = () => {
const { authDialogController, authDialogOpen, authDialogProduct, authDialogEntry } = useAuthDialog();
const [activeStep, setActiveStep] = React.useState(0);
const [useAuthUI, setUseAuthUI] = React.useState(false);
const [useAuthExperiment, setUseAuthExperiment] = React.useState(false);
const [jiraSignInText, setJiraSignInText] = useState('Sign In to Jira Cloud');
const [bitbucketSignInText, setBitbucketSignInText] = useState('Sign In to Bitbucket Cloud');
const [jiraSignInFlow, setJiraSignInFlow] = useState(jiraValueSet.cloud);
Expand All @@ -72,9 +74,21 @@ export const OnboardingPage: React.FunctionComponent = () => {
if (message.command === CommonMessageType.UpdateFeatureFlags) {
const featureValue = message.featureFlags[Features.EnableAuthUI];
setUseAuthUI(featureValue);
} else if (message.command === CommonMessageType.UpdateExperimentValues) {
let experimentValue: boolean;
try {
experimentValue = message.experimentValues[Experiments.NewAuthUIAA] as boolean;
} catch {
controller.postMessage({
type: OnboardingActionType.Error,
error: new Error(`Experiment value not found`),
});
experimentValue = false;
}
setUseAuthExperiment(experimentValue);
}
});
}, []);
}, [controller]);
function getSteps() {
if (useAuthUI) {
return ['Setup Jira', 'Setup BitBucket', 'Explore'];
Expand Down Expand Up @@ -362,7 +376,7 @@ export const OnboardingPage: React.FunctionComponent = () => {
padding: '24px',
}}
>
{useAuthUI ? authUI_v1 : oldAuthUI}
{useAuthUI && useAuthExperiment ? authUI_v1 : oldAuthUI}
</Box>
</div>
</Container>
Expand Down
30 changes: 29 additions & 1 deletion src/util/featureFlags/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AnalyticsClient } from '../../analytics-node-client/src/client.min';

import FeatureGates, { FeatureGateEnvironment, Identifiers } from '@atlaskit/feature-gate-js-client';
import { AnalyticsClientMapper, EventBuilderInterface } from './analytics';
import { Features } from './features';
import { ExperimentGates, Experiments, Features } from './features';

export type FeatureFlagClientOptions = {
analyticsClient: AnalyticsClient;
Expand Down Expand Up @@ -66,6 +66,22 @@ export class FeatureFlagClient {
return gateValue;
}

public static checkExperimentValue(experiment: string): any {
let gateValue: any = undefined;
if (FeatureGates === null) {
console.warn('FeatureGates: FeatureGates is not initialized. Defaulting to Undefined');
} else {
console.log(ExperimentGates[experiment]);
gateValue = FeatureGates.getExperimentValue(
ExperimentGates[experiment].gate,
ExperimentGates[experiment].parameter,
ExperimentGates[experiment].defaultValue,
);
}
console.log(`ExperimentGateValue: ${experiment} -> ${gateValue}`);
return gateValue;
}

public static async evaluateFeatures() {
const featureFlags = await Promise.all(
Object.values(Features).map(async (feature) => {
Expand All @@ -78,4 +94,16 @@ export class FeatureFlagClient {

return featureFlags.reduce((acc, val) => ({ ...acc, ...val }), {});
}

public static async evaluateExperiments() {
const experimentGates = await Promise.all(
Object.values(Experiments).map(async (experiment) => {
return {
[experiment]: await this.checkExperimentValue(experiment),
};
}),
);

return experimentGates.reduce((acc, val) => ({ ...acc, ...val }), {});
}
}
20 changes: 20 additions & 0 deletions src/util/featureFlags/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,23 @@ export enum Features {
EnableNewUriHandler = 'atlascode-enable-new-uri-handler',
EnableAuthUI = 'atlascode-enable-auth-ui',
}

export enum Experiments {
NewAuthUI = 'atlascode_new_auth_ui',
NewAuthUIAA = 'atlascode_new_auth_ui_aa',
}

export const ExperimentGates: ExperimentGate = {
[Experiments.NewAuthUI]: {
gate: 'atlascode_new_auth_ui',
parameter: 'isEnabled',
defaultValue: false,
},
[Experiments.NewAuthUIAA]: {
gate: 'atlascode_new_auth_ui_aa',
parameter: 'isEnabled',
defaultValue: `bruh`,
},
};

type ExperimentGate = { [key: string]: { gate: string; parameter: string; defaultValue: any } };
17 changes: 14 additions & 3 deletions src/webview/singleViewFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,20 @@ export class SingleWebview<FD, R> implements ReactWebview<FD> {
}

// Send feature gates to the panel in a message
const featureFlags = await FeatureFlagClient.evaluateFeatures();
console.log(`FeatureGates: sending ${JSON.stringify(featureFlags)}`);
this.postMessage({ command: CommonMessageType.UpdateFeatureFlags, featureFlags: featureFlags });
this.fireFeatureGates();
this.fireExperimentGates();
}

private async fireFeatureGates() {
const featureGates = await FeatureFlagClient.evaluateFeatures();
console.log(`FeatureGates: sending ${JSON.stringify(featureGates)}`);
this.postMessage({ command: CommonMessageType.UpdateFeatureFlags, featureFlags: featureGates });
}

private async fireExperimentGates() {
const experimentValues = await FeatureFlagClient.evaluateExperiments();
console.log(`ExperimentValues: sending ${JSON.stringify(experimentValues)}`);
this.postMessage({ command: CommonMessageType.UpdateExperimentValues, experimentValues });
}

private onViewStateChanged(e: WebviewPanelOnDidChangeViewStateEvent) {
Expand Down

0 comments on commit 820f7cd

Please sign in to comment.