1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-24 17:51:14 +02:00

Merge branch 'main' into chore/unleash-ai-filterflagstoarchive-flag-cleanup

This commit is contained in:
Tymoteusz Czech 2025-08-28 16:13:29 +02:00 committed by GitHub
commit c5ddb3e1be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 137 deletions

View File

@ -178,6 +178,9 @@ export const CreationArchiveChart: FC<ICreationArchiveChartProps> = ({
display: true, display: true,
text: 'Number of flags', text: 'Number of flags',
}, },
ticks: {
stepSize: 1,
},
}, },
}, },
}), }),

View File

@ -13,10 +13,7 @@ function getCurrentArchiveRatio(
InstanceInsightsSchema['creationArchiveTrends'] InstanceInsightsSchema['creationArchiveTrends']
>, >,
) { ) {
if ( if (!groupedCreationArchiveData) {
!groupedCreationArchiveData ||
Object.keys(groupedCreationArchiveData).length === 0
) {
return 0; return 0;
} }
@ -24,7 +21,7 @@ function getCurrentArchiveRatio(
let totalCreated = 0; let totalCreated = 0;
Object.values(groupedCreationArchiveData).forEach((projectData) => { Object.values(groupedCreationArchiveData).forEach((projectData) => {
const latestData = projectData[projectData.length - 1]; const latestData = projectData[0];
if (latestData) { if (latestData) {
totalArchived += latestData.archivedFlags || 0; totalArchived += latestData.archivedFlags || 0;
const createdSum = latestData.createdFlags const createdSum = latestData.createdFlags

View File

@ -351,10 +351,9 @@ export default class FeatureController extends Controller {
} }
async calculateMeta(query: IFeatureToggleQuery): Promise<IMeta> { async calculateMeta(query: IFeatureToggleQuery): Promise<IMeta> {
const etagByEnvEnabled = this.flagResolver.isEnabled('etagByEnv');
const revisionId = const revisionId =
await this.configurationRevisionService.getMaxRevisionId( await this.configurationRevisionService.getMaxRevisionId(
etagByEnvEnabled ? query.environment : undefined, query.environment,
); );
const queryHash = hashSum(query); const queryHash = hashSum(query);

View File

@ -60,6 +60,7 @@ export type IFlagKey =
| 'addConfiguration' | 'addConfiguration'
| 'fetchMode' | 'fetchMode'
| 'etagByEnv'; | 'etagByEnv';
| 'fetchMode';
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;

View File

@ -40,10 +40,8 @@ const allEnvsTokenSecret = validTokens[2].secret;
async function setup({ async function setup({
etagVariant, etagVariant,
etagByEnvEnabled,
}: { }: {
etagVariant: string | undefined; etagVariant: string | undefined;
etagByEnvEnabled: boolean;
}): Promise<{ app: IUnleashTest; db: ITestDb }> { }): Promise<{ app: IUnleashTest; db: ITestDb }> {
const db = await dbInit(`ignored`, getLogger); const db = await dbInit(`ignored`, getLogger);
@ -63,7 +61,6 @@ async function setup({
enabled: etagVariant !== undefined, enabled: etagVariant !== undefined,
feature_enabled: etagVariant !== undefined, feature_enabled: etagVariant !== undefined,
}, },
etagByEnv: etagByEnvEnabled,
}, },
}, },
}, },
@ -178,28 +175,21 @@ async function validateInitialState({
describe.each([ describe.each([
{ {
etagVariant: undefined, etagVariant: undefined,
etagByEnvEnabled: false,
}, },
{ {
etagVariant: 'v2', etagVariant: 'v2',
etagByEnvEnabled: false,
},
{
etagVariant: 'v2',
etagByEnvEnabled: true,
}, },
])( ])(
'feature 304 api client (etag variant = $etagVariant)', 'feature 304 api client (etag variant = $etagVariant)',
({ etagVariant, etagByEnvEnabled }) => { ({ etagVariant }) => {
let app: IUnleashTest; let app: IUnleashTest;
let db: ITestDb; let db: ITestDb;
const etagVariantEnabled = etagVariant !== undefined; const etagVariantEnabled = etagVariant !== undefined;
const etagVariantName = etagVariant ?? 'disabled'; const etagVariantName = etagVariant ?? 'disabled';
const expectedDevEventId = etagByEnvEnabled ? 13 : 15; const expectedDevEventId = 13;
beforeAll(async () => { beforeAll(async () => {
({ app, db } = await setup({ ({ app, db } = await setup({
etagVariant, etagVariant,
etagByEnvEnabled,
})); }));
await initialize({ app, db }); await initialize({ app, db });
await validateInitialState({ app, db }); await validateInitialState({ app, db });
@ -279,73 +269,7 @@ describe.each([
); );
}); });
test.runIf(!etagByEnvEnabled)( test('production environment gets a different etag than development', async () => {
'production environment gets same event id in etag than development',
async () => {
const { headers: prodHeaders } = await app.request
.get('/api/client/features?bla=1')
.set('Authorization', prodTokenSecret)
.expect(200);
expect(prodHeaders.etag).toEqual(
`"67e24428:15${etagVariantEnabled ? `:${etagVariantName}` : ''}"`,
);
const { headers: devHeaders } = await app.request
.get('/api/client/features')
.set('Authorization', devTokenSecret)
.expect(200);
expect(devHeaders.etag).toEqual(
`"76d8bb0e:15${etagVariantEnabled ? `:${etagVariantName}` : ''}"`,
);
},
);
test.runIf(!etagByEnvEnabled)(
'modifying dev environment also invalidates prod tokens',
async () => {
const currentDevEtag = `"76d8bb0e:${expectedDevEventId}${etagVariantEnabled ? `:${etagVariantName}` : ''}"`;
const currentProdEtag = `"67e24428:15${etagVariantEnabled ? `:${etagVariantName}` : ''}"`;
await app.request
.get('/api/client/features')
.set('if-none-match', currentProdEtag)
.set('Authorization', prodTokenSecret)
.expect(304);
await app.request
.get('/api/client/features')
.set('Authorization', devTokenSecret)
.set('if-none-match', currentDevEtag)
.expect(304);
await app.enableFeature('X', DEFAULT_ENV);
await app.services.configurationRevisionService.updateMaxRevisionId();
await app.request
.get('/api/client/features')
.set('Authorization', prodTokenSecret)
.set('if-none-match', currentProdEtag)
.expect(200);
const { headers: devHeaders } = await app.request
.get('/api/client/features')
.set('Authorization', devTokenSecret)
.set('if-none-match', currentDevEtag)
.expect(200);
// Note: this test yields a different result if run in isolation
// this is because the id 19 depends on a previous test adding a feature
// otherwise the id will be 18
expect(devHeaders.etag).toEqual(
`"76d8bb0e:19${etagVariantEnabled ? `:${etagVariantName}` : ''}"`,
);
},
);
test.runIf(etagByEnvEnabled)(
'production environment gets a different etag than development',
async () => {
const { headers: prodHeaders } = await app.request const { headers: prodHeaders } = await app.request
.get('/api/client/features?bla=1') .get('/api/client/features?bla=1')
.set('Authorization', prodTokenSecret) .set('Authorization', prodTokenSecret)
@ -363,12 +287,9 @@ describe.each([
expect(devHeaders.etag).toEqual( expect(devHeaders.etag).toEqual(
`"76d8bb0e:13${etagVariantEnabled ? `:${etagVariantName}` : ''}"`, `"76d8bb0e:13${etagVariantEnabled ? `:${etagVariantName}` : ''}"`,
); );
}, });
);
test.runIf(etagByEnvEnabled)( test('modifying dev environment should only invalidate dev tokens', async () => {
'modifying dev environment should only invalidate dev tokens',
async () => {
const currentDevEtag = `"76d8bb0e:13${etagVariantEnabled ? `:${etagVariantName}` : ''}"`; const currentDevEtag = `"76d8bb0e:13${etagVariantEnabled ? `:${etagVariantName}` : ''}"`;
const currentProdEtag = `"67e24428:15${etagVariantEnabled ? `:${etagVariantName}` : ''}"`; const currentProdEtag = `"67e24428:15${etagVariantEnabled ? `:${etagVariantName}` : ''}"`;
await app.request await app.request
@ -404,7 +325,6 @@ describe.each([
expect(devHeaders.etag).toEqual( expect(devHeaders.etag).toEqual(
`"76d8bb0e:19${etagVariantEnabled ? `:${etagVariantName}` : ''}"`, `"76d8bb0e:19${etagVariantEnabled ? `:${etagVariantName}` : ''}"`,
); );
}, });
);
}, },
); );