diff --git a/apps/client/src/components/EnvironmentForm.vue b/apps/client/src/components/EnvironmentForm.vue index fe8fbba09..433261a71 100644 --- a/apps/client/src/components/EnvironmentForm.vue +++ b/apps/client/src/components/EnvironmentForm.vue @@ -37,6 +37,7 @@ const props = withDefaults(defineProps<{ cpu: undefined, gpu: undefined, memory: undefined, + autosync: true, stageId: undefined, clusterId: undefined, }), @@ -46,7 +47,7 @@ const props = withDefaults(defineProps<{ const emit = defineEmits<{ addEnvironment: [environment: Omit] - putEnvironment: [environment: Pick] + putEnvironment: [environment: Pick] deleteEnvironment: [environmentId: Environment['id']] cancel: [] }>() @@ -67,10 +68,10 @@ const chosenZoneDescription = computed(() => zoneStore.zonesById[zoneId.value ?? const schema = computed(() => { if (localEnvironment.value?.id) { - const schemaValidation = EnvironmentSchema.pick({ id: true, cpu: true, gpu: true, memory: true }).safeParse(localEnvironment.value) + const schemaValidation = EnvironmentSchema.pick({ id: true, cpu: true, gpu: true, memory: true, autosync: true }).safeParse(localEnvironment.value) return schemaValidation } else { - const schemaValidation = EnvironmentSchema.pick({ clusterId: true, name: true, cpu: true, gpu: true, memory: true, stageId: true }).safeParse(localEnvironment.value) + const schemaValidation = EnvironmentSchema.pick({ clusterId: true, name: true, cpu: true, gpu: true, memory: true, autosync: true, stageId: true }).safeParse(localEnvironment.value) return schemaValidation } }) @@ -277,6 +278,21 @@ watch(localEnvironment.value, () => { :placeholder="ONE_TENTH_STR" @update:model-value="(value: string) => localEnvironment.gpu = localeParseFloat(value)" /> + +
> { - const environment = await initializeEnvironment({ projectId, name, cpu, gpu, memory, clusterId, stageId }) + const environment = await initializeEnvironment({ projectId, name, cpu, gpu, memory, autosync, clusterId, stageId }) const { results } = await hook.project.upsert(projectId) await addLogs({ action: 'Create Environment', data: results, userId, requestId, projectId }) @@ -72,6 +75,7 @@ interface UpdateEnvironmentParam { cpu: Environment['cpu'] gpu: Environment['gpu'] memory: Environment['memory'] + autosync: Environment['autosync'] requestId: string } @@ -82,12 +86,14 @@ export async function updateEnvironment({ cpu, gpu, memory, + autosync, }: UpdateEnvironmentParam) { const env = await updateEnvironmentQuery({ id: environmentId, cpu, gpu, memory, + autosync, }) const { results } = await hook.project.upsert(env.projectId) await addLogs({ action: 'Update Environment', data: results, userId: user.id, requestId, projectId: env.projectId }) diff --git a/apps/server/src/resources/environment/queries.ts b/apps/server/src/resources/environment/queries.ts index 620e693cb..6b228e268 100644 --- a/apps/server/src/resources/environment/queries.ts +++ b/apps/server/src/resources/environment/queries.ts @@ -71,7 +71,7 @@ export function initializeEnvironment(data: Prisma.EnvironmentUncheckedCreateInp }) } -export function updateEnvironment({ id, cpu, gpu, memory }: { id: Environment['id'], cpu: Environment['cpu'], gpu: Environment['gpu'], memory: Environment['memory'] }) { +export function updateEnvironment({ id, cpu, gpu, memory, autosync }: { id: Environment['id'], cpu: Environment['cpu'], gpu: Environment['gpu'], memory: Environment['memory'], autosync: Environment['autosync'] }) { return prisma.environment.update({ where: { id, @@ -80,6 +80,7 @@ export function updateEnvironment({ id, cpu, gpu, memory }: { id: Environment['i cpu, gpu, memory, + autosync, }, }) } diff --git a/apps/server/src/resources/environment/router.spec.ts b/apps/server/src/resources/environment/router.spec.ts index 47337bbb4..098485e8f 100644 --- a/apps/server/src/resources/environment/router.spec.ts +++ b/apps/server/src/resources/environment/router.spec.ts @@ -30,6 +30,7 @@ describe('environmentRouter tests', () => { cpu: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), gpu: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), memory: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), + autosync: faker.datatype.boolean(), clusterId: faker.string.uuid(), stageId: faker.string.uuid(), } @@ -178,6 +179,7 @@ describe('environmentRouter tests', () => { cpu: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), gpu: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), memory: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), + autosync: faker.datatype.boolean(), } }) it('should update environment for authorized user', async () => { diff --git a/apps/server/src/resources/environment/router.ts b/apps/server/src/resources/environment/router.ts index f1cf21b8a..cf3a3ee9e 100644 --- a/apps/server/src/resources/environment/router.ts +++ b/apps/server/src/resources/environment/router.ts @@ -41,6 +41,7 @@ export function environmentRouter() { cpu: requestBody.cpu, gpu: requestBody.gpu, memory: requestBody.memory, + autosync: requestBody.autosync, stageId: requestBody.stageId, requestId: req.id, }) @@ -71,6 +72,7 @@ export function environmentRouter() { cpu: requestBody.cpu, gpu: requestBody.gpu, memory: requestBody.memory, + autosync: requestBody.autosync, requestId: req.id, }) if (result.isError) { diff --git a/packages/hooks/src/hooks/hook-project.ts b/packages/hooks/src/hooks/hook-project.ts index 0bb640a8f..7d531d142 100644 --- a/packages/hooks/src/hooks/hook-project.ts +++ b/packages/hooks/src/hooks/hook-project.ts @@ -24,6 +24,7 @@ export interface Environment { gpu: number memory: number stage: string + autosync: boolean permissions: { userId: UserObject['id'] permissions: { diff --git a/packages/shared/src/contracts/environment.ts b/packages/shared/src/contracts/environment.ts index 0490fefb3..eb2116613 100644 --- a/packages/shared/src/contracts/environment.ts +++ b/packages/shared/src/contracts/environment.ts @@ -51,7 +51,7 @@ export const environmentContract = contractInstance.router({ environmentId: z.string() .uuid(), }), - body: EnvironmentSchema.pick({ cpu: true, gpu: true, memory: true }), + body: EnvironmentSchema.pick({ cpu: true, gpu: true, memory: true, autosync: true }), responses: { 200: EnvironmentSchema, 400: ErrorSchema, diff --git a/packages/shared/src/schemas/environment.ts b/packages/shared/src/schemas/environment.ts index cc9b7d663..c2c43bd76 100644 --- a/packages/shared/src/schemas/environment.ts +++ b/packages/shared/src/schemas/environment.ts @@ -18,6 +18,7 @@ export const EnvironmentSchema = z.object({ cpu: z.coerce.number().gte(0), gpu: z.coerce.number().gte(0), memory: z.coerce.number().gte(0), + autosync: z.boolean(), }).extend(AtDatesToStringExtend) export type Environment = Zod.infer diff --git a/packages/shared/src/utils/schemas.spec.ts b/packages/shared/src/utils/schemas.spec.ts index b393d7eb1..8e115d42c 100644 --- a/packages/shared/src/utils/schemas.spec.ts +++ b/packages/shared/src/utils/schemas.spec.ts @@ -64,6 +64,7 @@ describe('schemas utils', () => { cpu: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), gpu: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), memory: faker.number.float({ min: 0, max: 10, fractionDigits: 1 }), + autosync: faker.datatype.boolean(), projectId: faker.string.uuid(), clusterId: faker.string.uuid(), stageId: faker.string.uuid(), diff --git a/playwright/e2e-tests/environments.spec.ts b/playwright/e2e-tests/environments.spec.ts index b371a44cf..c1a313e34 100644 --- a/playwright/e2e-tests/environments.spec.ts +++ b/playwright/e2e-tests/environments.spec.ts @@ -302,4 +302,33 @@ test.describe('Environments page', { tag: '@e2e' }, () => { page.getByTestId('showDeleteEnvironmentBtn'), ).not.toBeVisible() }) + + test('should show a warning if autosync is deactivated', async ({ + page, + }) => { + await page.goto(clientURL) + await signInCloudPiNative({ page, credentials: testUser }) + await addProject({ page }) + const envName = await addEnvToProject({ + page, + zone: 'publique', + customStageName: 'dev', + customClusterName: 'public1', + }) + await expect(page.getByRole('cell', { name: envName })).toBeVisible() + + // Verify warning message + await page.getByTestId(`environmentTr-${envName}`).click() + await expect(page.getByTestId('input-checkbox-autosyncCbx')).toBeVisible() + await expect(page.getByTestId('input-checkbox-autosyncCbx')).toBeChecked() + await expect(page.getByTestId('noAutosyncAlert')).not.toBeVisible() + + // Act - Uncheck auto-sync to trigger warning message + await page.getByTestId('input-checkbox-autosyncCbx').uncheck({ + force: true, + }) + await expect(page.getByTestId('noAutosyncAlert')).toBeVisible() + await expect(page.getByTestId('noAutosyncAlert')) + .toHaveText('La synchronisation automatique est désactivée. Les déploiements devront être synchronisés manuellement.') + }) }) diff --git a/plugins/argocd/src/functions.ts b/plugins/argocd/src/functions.ts index 887dad7ba..f0c07b1e4 100644 --- a/plugins/argocd/src/functions.ts +++ b/plugins/argocd/src/functions.ts @@ -236,7 +236,7 @@ async function ensureInfraEnvValues(project: Project, environment: Environment, cluster: inClusterLabel, namespace: getConfig().namespace, project: appProjectName, - envChartVersion: process.env.DSO_ENV_CHART_VERSION ?? 'dso-env-1.5.2', + envChartVersion: process.env.DSO_ENV_CHART_VERSION ?? 'dso-env-1.6.0', nsChartVersion: process.env.DSO_NS_CHART_VERSION ?? 'dso-ns-1.1.4', }, environment: { @@ -257,6 +257,7 @@ async function ensureInfraEnvValues(project: Project, environment: Environment, namespace: appNamespace, name: cluster.label, }, + autosync: environment.autosync, vault: vaultCredentials, repositories, },