Skip to content

feat(flags): add unleash to provider dropdowns and onboarding #82836

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,20 @@ function OnboardingContent({
return window.location.hash;
}, []);
const skipConfig = ORIGINAL_HASH === FLAG_HASH_SKIP_CONFIG;
const openFeatureProviders = [ProviderOptions.LAUNCHDARKLY];
const sdkProviders = [ProviderOptions.LAUNCHDARKLY];
const openFeatureProviders = Object.values(ProviderOptions);
const sdkProviders = Object.values(ProviderOptions);

// First dropdown: OpenFeature providers
const openFeatureProviderOptions = openFeatureProviders.map(provider => {
return {
value: provider,
textValue: provider,
label: <TextOverflow>{provider}</TextOverflow>,
label:
provider === ProviderOptions.GENERIC ? (
<TextOverflow>{t('Custom')}</TextOverflow>
) : (
<TextOverflow>{provider}</TextOverflow>
),
};
});

Expand All @@ -180,7 +185,12 @@ function OnboardingContent({
return {
value: provider,
textValue: provider,
label: <TextOverflow>{provider}</TextOverflow>,
label:
provider === ProviderOptions.GENERIC ? (
<TextOverflow>{t('Custom')}</TextOverflow>
) : (
<TextOverflow>{provider}</TextOverflow>
),
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import {
import {hasEveryAccess} from 'sentry/components/acl/access';
import Alert from 'sentry/components/alert';
import {Button} from 'sentry/components/button';
import {PROVIDER_OPTION_TO_URLS} from 'sentry/components/events/featureFlags/utils';
import {
PROVIDER_OPTION_TO_URLS,
ProviderOptions,
} from 'sentry/components/events/featureFlags/utils';
import Input from 'sentry/components/input';
import ExternalLink from 'sentry/components/links/externalLink';
import TextCopyInput from 'sentry/components/textCopyInput';
Expand Down Expand Up @@ -98,7 +101,9 @@ export default function OnboardingIntegrationSection({
<div>
{tct(
"Create a webhook integration with your [link:feature flag service]. When you do so, you'll need to enter a URL, which you can find below.",
{link: <ExternalLink href={PROVIDER_OPTION_TO_URLS[provider]} />}
{
link: <ExternalLink href={PROVIDER_OPTION_TO_URLS[provider]} />,
}
)}
</div>
<InputTitle>{t('Webhook URL')}</InputTitle>
Expand All @@ -112,9 +117,13 @@ export default function OnboardingIntegrationSection({
</SubSection>
<SubSection>
<div>
{t(
"During the process of creating a webhook integration, you'll be given the option to sign the webhook. This is an auto-generated secret code that Sentry requires to verify requests from your feature flag service. Paste the secret below."
)}
{provider === ProviderOptions.UNLEASH
? t(
`During the process of creating a webhook integration, you'll be given the option to add an authorization header. This is a string (or "secret") that you choose so that Sentry can verify requests from your feature flag service. Paste your authorization string below.`
)
: t(
"During the process of creating a webhook integration, you'll be given the option to sign the webhook. This is an auto-generated secret code that Sentry requires to verify requests from your feature flag service. Paste the secret below."
)}
</div>
<InputTitle>{t('Secret')}</InputTitle>
<InputArea>
Expand Down
6 changes: 6 additions & 0 deletions static/app/components/events/featureFlags/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,20 @@ export const sortedFlags = ({

export enum ProviderOptions {
LAUNCHDARKLY = 'LaunchDarkly',
GENERIC = 'Generic',
UNLEASH = 'Unleash',
}

export enum IntegrationOptions {
LAUNCHDARKLY = 'LaunchDarkly',
OPENFEATURE = 'OpenFeature',
GENERIC = 'Generic',
UNLEASH = 'Unleash',
}

export const PROVIDER_OPTION_TO_URLS: Record<ProviderOptions, string> = {
[ProviderOptions.LAUNCHDARKLY]:
'https://app.launchdarkly.com/settings/integrations/webhooks/new?q=Webhooks',
[ProviderOptions.GENERIC]: 'DOCS LINK TODO',
[ProviderOptions.UNLEASH]: 'DOCS LINK TODO',
};
18 changes: 18 additions & 0 deletions static/app/gettingStartedDocs/javascript/javascript.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ client.addHooks(new Sentry.OpenFeatureIntegrationHook());
// Evaluating flags will record the result on the Sentry client.
const result = client.getBooleanValue('my-flag', false);`,
},
[IntegrationOptions.UNLEASH]: {
importStatement: `TODO`,
integration: 'TODO',
sdkInit: `TODO`,
},
[IntegrationOptions.GENERIC]: {
importStatement: ``,
integration: 'featureFlagsIntegration()',
sdkInit: `const flagsIntegration = Sentry.getClient()?.getIntegrationByName<Sentry.FeatureFlagsIntegration>('FeatureFlags');

if (flagsIntegration) {
flagsIntegration.addFeatureFlag('test-flag', false);
} else {
// Something went wrong, check your DSN and/or integrations
}

Sentry.captureException(new Error('Something went wrong!'));`,
},
};

const isAutoInstall = (params: Params) =>
Expand Down
11 changes: 10 additions & 1 deletion static/app/gettingStartedDocs/python/python.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ const FLAG_OPTION_TO_IMPORT: Record<IntegrationOptions, FlagImports> = {
module: 'openfeature',
integration: 'OpenFeatureIntegration',
},
[IntegrationOptions.UNLEASH]: {
module: 'unleash',
integration: 'UnleashIntegration',
},
[IntegrationOptions.GENERIC]: {
module: 'featureflags',
integration: 'FeatureFlagsIntegration',
},
};

const getInstallSnippet = () => `pip install --upgrade sentry-sdk`;
Expand Down Expand Up @@ -265,7 +273,8 @@ sentry_sdk.init(
integrations=[
${FLAG_OPTION_TO_IMPORT[featureFlagOptions.integration].integration}(),
]
)`,
)
`,
},
],
},
Expand Down
1 change: 0 additions & 1 deletion static/app/views/settings/featureFlags/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ describe('OrganizationFeatureFlagsIndex', function () {

await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator'));

// Then list
expect(screen.getByText('launchdarkly')).toBeInTheDocument();
expect(screen.getByText('openfeature')).toBeInTheDocument();

Expand Down
6 changes: 5 additions & 1 deletion static/app/views/settings/featureFlags/newProviderForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ export default function NewProviderForm({
value={selectedProvider}
placeholder={t('Select a provider')}
name="provider"
options={[{value: 'LaunchDarkly', label: 'LaunchDarkly'}]}
options={[
{value: 'LaunchDarkly', label: 'LaunchDarkly'},
{value: 'Unleash', label: 'Unleash'},
{value: 'Generic', label: 'Custom'},
]}
help={t(
'If you have already linked this provider, pasting a new secret will override the existing secret.'
)}
Expand Down
Loading