From b028be0f519ff60875aac57ccff994322dd06987 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 20 Oct 2025 09:59:30 +1300 Subject: [PATCH 01/14] Adds updated column in env_vars --- .../20251019203621_add_updated_to_env_vars.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 services/api/database/migrations/20251019203621_add_updated_to_env_vars.js diff --git a/services/api/database/migrations/20251019203621_add_updated_to_env_vars.js b/services/api/database/migrations/20251019203621_add_updated_to_env_vars.js new file mode 100644 index 0000000000..79640724ea --- /dev/null +++ b/services/api/database/migrations/20251019203621_add_updated_to_env_vars.js @@ -0,0 +1,25 @@ +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = function(knex) { + return knex.schema + .alterTable('env_vars', (table) => { + table.datetime('updated').notNullable().defaultTo(knex.fn.now()); + }) + .raw("UPDATE env_vars SET updated='1970-01-01 00:00:00'"); + // Note, we do the above update so that all _existing_ env vars are + // not picked up as needing to be deployed (since we're using 'updated' to track new/updated vars) + // but any newly created items will get the _current_ date/time +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = function(knex) { +return knex.schema + .alterTable('env_vars', (table) => { + table.dropColumn('updated'); + }) +}; From 172a034202adde6c94b76b843d40ed0476678f53 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 20 Oct 2025 13:35:11 +1300 Subject: [PATCH 02/14] Adds some logic to calculate the outstanding updates --- services/api/src/resolvers.js | 5 ++ .../src/resources/env-variables/resolvers.ts | 3 + .../environment/environment_redeploy.ts | 65 +++++++++++++++++++ services/api/src/typeDefs.js | 10 +++ 4 files changed, 83 insertions(+) create mode 100644 services/api/src/resources/environment/environment_redeploy.ts diff --git a/services/api/src/resolvers.js b/services/api/src/resolvers.js index 4883d1445b..027f495c3b 100644 --- a/services/api/src/resolvers.js +++ b/services/api/src/resolvers.js @@ -129,6 +129,10 @@ const { deleteEnvironmentService, } = require('./resources/environment/resolvers'); +const { + getPendingChangesByEnvironmentId, +} = require('./resources/environment/environment_redeploy') + const { getDeployTargetConfigById, getDeployTargetConfigsByProjectId, @@ -522,6 +526,7 @@ async function getResolvers() { facts: getFactsByEnvironmentId, openshift: getOpenshiftByEnvironmentId, kubernetes: getOpenshiftByEnvironmentId, + pendingChanges: getPendingChangesByEnvironmentId, }, Organization: { groups: getGroupsByOrganizationId, diff --git a/services/api/src/resources/env-variables/resolvers.ts b/services/api/src/resources/env-variables/resolvers.ts index 3d6fa5569d..4f5b2e8fbc 100644 --- a/services/api/src/resources/env-variables/resolvers.ts +++ b/services/api/src/resources/env-variables/resolvers.ts @@ -417,6 +417,9 @@ export const addOrUpdateEnvVariableByName: ResolverFn = async ( } } + // Let's set the updated value for the env var + updateData['updated'] = knex.fn.now(); + const createOrUpdateSql = knex('env_vars') .insert({ ...updateData, diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts new file mode 100644 index 0000000000..26f4c914d7 --- /dev/null +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -0,0 +1,65 @@ +// This file contains the logic to determine whether an environment requires a redeploy + +import * as R from 'ramda'; +import { sendToLagoonLogs } from '@lagoon/commons/dist/logs/lagoon-logger'; +import { createRemoveTask, seedNamespace } from '@lagoon/commons/dist/tasks'; +import { ResolverFn } from '..'; +import { logger } from '../../loggers/logger'; +import { isPatchEmpty, query, knex } from '../../util/db'; +import { convertDateToMYSQLDateFormat } from '../../util/convertDateToMYSQLDateTimeFormat'; +import { Helpers } from './helpers'; +import { Sql } from './sql'; +import { Sql as projectSql } from '../project/sql'; +import { Helpers as projectHelpers } from '../project/helpers'; +import { Helpers as openshiftHelpers } from '../openshift/helpers'; +import { Helpers as organizationHelpers } from '../organization/helpers'; +import { getFactFilteredEnvironmentIds } from '../fact/resolvers'; +import { getUserProjectIdsFromRoleProjectIds } from '../../util/auth'; +import { RemoveData, DeployType, AuditType } from '@lagoon/commons/dist/types'; +import { AuditLog } from '../audit/types'; + + +export const getPendingChangesByEnvironmentId: ResolverFn = async( +{ + id +}, +_, +{ sqlClientPool, hasPermission }, +) => { + let pendingChanges = await getPendingEnvVarChanges(sqlClientPool, id); + return pendingChanges; +} + +const getPendingEnvVarChanges = async(sqlClientPool, envId) => { + const sql = ` + SELECT DISTINCT + ev.name, + ev.updated, + e.id, + e.name as env_name, + COALESCE(MAX(d.created) OVER (PARTITION BY e.id), '1970-01-01') as last_deployment + FROM environment as e + LEFT JOIN deployment as d ON e.id = d.environment + INNER JOIN project as p ON p.id = e.project + LEFT JOIN organization as o ON o.id = p.organization + LEFT JOIN env_vars as ev ON ( + ev.environment = e.id OR + ev.project = p.id OR + ev.organization = o.id + ) + WHERE ev.name IS NOT NULL AND e.id = ? + `; + + const results = await query(sqlClientPool, sql, [envId]); + + // Filter in memory for env vars updated after last deployment + const pendingChanges = results.filter(row => { + const updated = new Date(row.updated); + const lastDeployment = new Date(row.last_deployment); + return updated > lastDeployment || true; + }).map(row => { + return {type:"Environment Variable", details: row.name}; + }); + + return pendingChanges; +} \ No newline at end of file diff --git a/services/api/src/typeDefs.js b/services/api/src/typeDefs.js index c668ffb9fb..93176a30a7 100644 --- a/services/api/src/typeDefs.js +++ b/services/api/src/typeDefs.js @@ -897,6 +897,15 @@ const typeDefs = gql` openshiftProjectPattern: String @deprecated(reason: "No longer in use") kubernetes: Kubernetes kubernetesNamespacePattern: String @deprecated(reason: "No longer in use") + """ + Pending changes tell us if we need to redeploy an environment + """ + pendingChanges: [EnvironmentPendingChanges] + } + + type EnvironmentPendingChanges { + type: String + details: String } type EnvironmentHitsMonth { @@ -1005,6 +1014,7 @@ const typeDefs = gql` scope: String name: String value: String + updated: String } type Task { From 358efb0dfc4311161c09f22ef7d916a94f4cafb3 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Fri, 24 Oct 2025 10:08:56 +1300 Subject: [PATCH 03/14] Adds some explanatory text --- services/api/src/resources/environment/environment_redeploy.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index 26f4c914d7..bf17f90cb1 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -26,6 +26,9 @@ export const getPendingChangesByEnvironmentId: ResolverFn = async( _, { sqlClientPool, hasPermission }, ) => { + // Note: as it stands, the only pending changes we have now have to do + // with env vars, but anything can be added in the form + // {type:"string", details:"string"} let pendingChanges = await getPendingEnvVarChanges(sqlClientPool, id); return pendingChanges; } From 1ee1630c550e872ffa59c80d5a11dba3fcdd9be0 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Fri, 24 Oct 2025 11:56:38 +1300 Subject: [PATCH 04/14] Adds source of variable --- .../api/src/resources/environment/environment_redeploy.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index bf17f90cb1..c2a3e0f866 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -40,6 +40,11 @@ const getPendingEnvVarChanges = async(sqlClientPool, envId) => { ev.updated, e.id, e.name as env_name, + COALESCE( + IF(ev.environment IS NULL,NULL,'Environment'), + IF(ev.project IS NULL,NULL,'Project'), + IF(ev.organization IS NULL,NULL,'Organization') + ) as varsource, COALESCE(MAX(d.created) OVER (PARTITION BY e.id), '1970-01-01') as last_deployment FROM environment as e LEFT JOIN deployment as d ON e.id = d.environment @@ -61,7 +66,7 @@ const getPendingEnvVarChanges = async(sqlClientPool, envId) => { const lastDeployment = new Date(row.last_deployment); return updated > lastDeployment || true; }).map(row => { - return {type:"Environment Variable", details: row.name}; + return {type:`Environment Variable - ${row.varsource} level`, details: row.name}; }); return pendingChanges; From a150e86dcc1d4e996b230d8ad4b2787e32a673b4 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Sat, 25 Oct 2025 09:49:35 +1300 Subject: [PATCH 05/14] Update services/api/src/resources/environment/environment_redeploy.ts Co-authored-by: Ben Jackson --- services/api/src/resources/environment/environment_redeploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index c2a3e0f866..5b5948174f 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -64,7 +64,7 @@ const getPendingEnvVarChanges = async(sqlClientPool, envId) => { const pendingChanges = results.filter(row => { const updated = new Date(row.updated); const lastDeployment = new Date(row.last_deployment); - return updated > lastDeployment || true; + return updated > lastDeployment; }).map(row => { return {type:`Environment Variable - ${row.varsource} level`, details: row.name}; }); From 68ef0efb4df5aab25b4c726f5363bfa435811459 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Sat, 25 Oct 2025 09:49:46 +1300 Subject: [PATCH 06/14] Update services/api/src/resources/environment/environment_redeploy.ts Co-authored-by: Ben Jackson --- services/api/src/resources/environment/environment_redeploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index 5b5948174f..6f91e85aee 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -63,7 +63,7 @@ const getPendingEnvVarChanges = async(sqlClientPool, envId) => { // Filter in memory for env vars updated after last deployment const pendingChanges = results.filter(row => { const updated = new Date(row.updated); - const lastDeployment = new Date(row.last_deployment); + const lastDeployment = new Date(row.lastDeployment); return updated > lastDeployment; }).map(row => { return {type:`Environment Variable - ${row.varsource} level`, details: row.name}; From 8fbc8cee60f961aedf2421865b04b97a7e386e83 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 27 Oct 2025 09:15:46 +1300 Subject: [PATCH 07/14] Update services/api/src/typeDefs.js Co-authored-by: Ben Jackson --- services/api/src/typeDefs.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/api/src/typeDefs.js b/services/api/src/typeDefs.js index 93176a30a7..fceb76cff6 100644 --- a/services/api/src/typeDefs.js +++ b/services/api/src/typeDefs.js @@ -906,6 +906,7 @@ const typeDefs = gql` type EnvironmentPendingChanges { type: String details: String + date: String } type EnvironmentHitsMonth { From 7a28ddd06bbe07eb5f7a2de56770ca4920d8a1d5 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 27 Oct 2025 09:51:09 +1300 Subject: [PATCH 08/14] Fixes env var updated query --- .../environment/environment_redeploy.ts | 51 ++++++++----------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index 6f91e85aee..afbdb84a4c 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -35,38 +35,29 @@ _, const getPendingEnvVarChanges = async(sqlClientPool, envId) => { const sql = ` - SELECT DISTINCT - ev.name, - ev.updated, - e.id, - e.name as env_name, - COALESCE( - IF(ev.environment IS NULL,NULL,'Environment'), - IF(ev.project IS NULL,NULL,'Project'), - IF(ev.organization IS NULL,NULL,'Organization') - ) as varsource, - COALESCE(MAX(d.created) OVER (PARTITION BY e.id), '1970-01-01') as last_deployment - FROM environment as e - LEFT JOIN deployment as d ON e.id = d.environment - INNER JOIN project as p ON p.id = e.project - LEFT JOIN organization as o ON o.id = p.organization - LEFT JOIN env_vars as ev ON ( - ev.environment = e.id OR - ev.project = p.id OR - ev.organization = o.id - ) - WHERE ev.name IS NOT NULL AND e.id = ? - `; +select e.id as env_id, e.name as env_name, ev.name as envvar_name, ev.updated as envvar_updated, + COALESCE( + IF(ev.environment IS NULL,NULL,'Environment'), + IF(ev.project IS NULL,NULL,'Project'), + IF(ev.organization IS NULL,NULL,'Organization') + ) as envvar_source +FROM environment as e +INNER JOIN project as p ON p.id = e.project +LEFT JOIN organization as o ON o.id = p.organization +LEFT JOIN env_vars as ev ON ( + ev.environment = e.id OR + ev.project = p.id OR + ev.organization = o.id +) +WHERE ev.name IS NOT NULL AND e.id = ? +AND ev.updated > (select coalesce(max(completed), '0000-00-00 00:00:00') from deployment where environment = ? and status = ?) +ORDER BY ev.updated asc +`; - const results = await query(sqlClientPool, sql, [envId]); + const results = await query(sqlClientPool, sql, [envId, envId, 'complete']); - // Filter in memory for env vars updated after last deployment - const pendingChanges = results.filter(row => { - const updated = new Date(row.updated); - const lastDeployment = new Date(row.lastDeployment); - return updated > lastDeployment; - }).map(row => { - return {type:`Environment Variable - ${row.varsource} level`, details: row.name}; + const pendingChanges = results.map(row => { + return {type:`Environment Variable - ${row.envvarSource} level`, details: row.envvarName, date: row.envvarUpdated}; }); return pendingChanges; From f2aad51a1c3520a85f655e5d45a659e30eb54134 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 27 Oct 2025 09:52:08 +1300 Subject: [PATCH 09/14] Fixes env var updated query --- services/api/src/resources/environment/environment_redeploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index afbdb84a4c..8124d8a766 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -51,7 +51,7 @@ LEFT JOIN env_vars as ev ON ( ) WHERE ev.name IS NOT NULL AND e.id = ? AND ev.updated > (select coalesce(max(completed), '0000-00-00 00:00:00') from deployment where environment = ? and status = ?) -ORDER BY ev.updated asc +ORDER BY ev.updated desc `; const results = await query(sqlClientPool, sql, [envId, envId, 'complete']); From 8a0a3774817b313e761d58a3191df09fa37b63d8 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 27 Oct 2025 11:28:45 +1300 Subject: [PATCH 10/14] Better index use in query --- .../environment/environment_redeploy.ts | 70 ++++++++++++++----- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index 8124d8a766..56a4fc9a80 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -35,26 +35,62 @@ _, const getPendingEnvVarChanges = async(sqlClientPool, envId) => { const sql = ` -select e.id as env_id, e.name as env_name, ev.name as envvar_name, ev.updated as envvar_updated, - COALESCE( - IF(ev.environment IS NULL,NULL,'Environment'), - IF(ev.project IS NULL,NULL,'Project'), - IF(ev.organization IS NULL,NULL,'Organization') - ) as envvar_source -FROM environment as e -INNER JOIN project as p ON p.id = e.project -LEFT JOIN organization as o ON o.id = p.organization -LEFT JOIN env_vars as ev ON ( - ev.environment = e.id OR - ev.project = p.id OR - ev.organization = o.id +WITH last_completed AS ( + SELECT COALESCE(MAX(d.completed), TIMESTAMP('1970-01-01 00:00:00')) AS ts + FROM deployment d + WHERE d.environment = ? AND d.status = 'complete' ) -WHERE ev.name IS NOT NULL AND e.id = ? -AND ev.updated > (select coalesce(max(completed), '0000-00-00 00:00:00') from deployment where environment = ? and status = ?) -ORDER BY ev.updated desc +SELECT * +FROM ( + -- Environment-scoped + SELECT + e.id AS env_id, + e.name AS env_name, + ev.name AS envvar_name, + ev.updated AS envvar_updated, + 'Environment' AS envvar_source + FROM environment e + JOIN env_vars ev ON ev.environment = e.id + CROSS JOIN last_completed lc + WHERE e.id = ? + AND ev.name IS NOT NULL + AND ev.updated > lc.ts + + UNION ALL + + -- Project-scoped + SELECT + e.id, e.name, + ev.name, ev.updated, + 'Project' AS envvar_source + FROM environment e + JOIN project p ON p.id = e.project + JOIN env_vars ev ON ev.project = p.id + CROSS JOIN last_completed lc + WHERE e.id = ? + AND ev.name IS NOT NULL + AND ev.updated > lc.ts + + UNION ALL + + -- Organization-scoped + SELECT + e.id, e.name, + ev.name, ev.updated, + 'Organization' AS envvar_source + FROM environment e + JOIN project p ON p.id = e.project + JOIN organization o ON o.id = p.organization + JOIN env_vars ev ON ev.organization = o.id + CROSS JOIN last_completed lc + WHERE e.id = ? + AND ev.name IS NOT NULL + AND ev.updated > lc.ts +) AS allenvs +ORDER BY allenvs.envvar_updated DESC; `; - const results = await query(sqlClientPool, sql, [envId, envId, 'complete']); + const results = await query(sqlClientPool, sql, [envId, envId, envId, envId]); const pendingChanges = results.map(row => { return {type:`Environment Variable - ${row.envvarSource} level`, details: row.envvarName, date: row.envvarUpdated}; From 5991acb71f422f4aa4503b530889bf9d72616362 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 27 Oct 2025 15:31:02 +1300 Subject: [PATCH 11/14] Update services/api/src/resources/environment/environment_redeploy.ts Co-authored-by: Ben Jackson --- services/api/src/resources/environment/environment_redeploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index 56a4fc9a80..9657bcf6ff 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -36,7 +36,7 @@ _, const getPendingEnvVarChanges = async(sqlClientPool, envId) => { const sql = ` WITH last_completed AS ( - SELECT COALESCE(MAX(d.completed), TIMESTAMP('1970-01-01 00:00:00')) AS ts + SELECT COALESCE(MAX(d.created), TIMESTAMP('1970-01-01 00:00:00')) AS ts FROM deployment d WHERE d.environment = ? AND d.status = 'complete' ) From 16d13b7018e42cb90b6371dec40ca91fc21b0e90 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Mon, 27 Oct 2025 15:31:17 +1300 Subject: [PATCH 12/14] Update services/api/src/resources/environment/environment_redeploy.ts Co-authored-by: Ben Jackson --- services/api/src/resources/environment/environment_redeploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index 9657bcf6ff..0e183b1c87 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -28,7 +28,7 @@ _, ) => { // Note: as it stands, the only pending changes we have now have to do // with env vars, but anything can be added in the form - // {type:"string", details:"string"} + // {type:"string", details:"string", date: "string"} let pendingChanges = await getPendingEnvVarChanges(sqlClientPool, id); return pendingChanges; } From 98f5df88d938cecbc7e701310c5b1ce71bba3c21 Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Tue, 28 Oct 2025 07:25:21 +1300 Subject: [PATCH 13/14] Update services/api/src/resources/environment/environment_redeploy.ts Co-authored-by: Ben Jackson --- services/api/src/resources/environment/environment_redeploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index 0e183b1c87..418a8bd83c 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -93,7 +93,7 @@ ORDER BY allenvs.envvar_updated DESC; const results = await query(sqlClientPool, sql, [envId, envId, envId, envId]); const pendingChanges = results.map(row => { - return {type:`Environment Variable - ${row.envvarSource} level`, details: row.envvarName, date: row.envvarUpdated}; + return {type:`${row.envvarSource} Environment Variable`, details: `Variable name: ${row.envvarName}`, date: row.envvarUpdated}; }); return pendingChanges; From c32d4d2dfd97319b0cb666044a3d77d8ca1b581e Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Tue, 28 Oct 2025 11:29:50 +1300 Subject: [PATCH 14/14] Adds slightly stricter typing to pending changes --- .../api/src/resources/environment/environment_redeploy.ts | 6 +++++- services/api/src/typeDefs.js | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/services/api/src/resources/environment/environment_redeploy.ts b/services/api/src/resources/environment/environment_redeploy.ts index 418a8bd83c..23b87122f2 100644 --- a/services/api/src/resources/environment/environment_redeploy.ts +++ b/services/api/src/resources/environment/environment_redeploy.ts @@ -19,6 +19,10 @@ import { RemoveData, DeployType, AuditType } from '@lagoon/commons/dist/types'; import { AuditLog } from '../audit/types'; +export const environmentPendingChangeTypes = { + ENVVAR: "ENVVAR", +}; + export const getPendingChangesByEnvironmentId: ResolverFn = async( { id @@ -93,7 +97,7 @@ ORDER BY allenvs.envvar_updated DESC; const results = await query(sqlClientPool, sql, [envId, envId, envId, envId]); const pendingChanges = results.map(row => { - return {type:`${row.envvarSource} Environment Variable`, details: `Variable name: ${row.envvarName}`, date: row.envvarUpdated}; + return {type:environmentPendingChangeTypes.ENVVAR, details: `Variable name: ${row.envvarName} (source: ${row.envvarSource} )`, date: row.envvarUpdated}; }); return pendingChanges; diff --git a/services/api/src/typeDefs.js b/services/api/src/typeDefs.js index fceb76cff6..b709f013cc 100644 --- a/services/api/src/typeDefs.js +++ b/services/api/src/typeDefs.js @@ -904,11 +904,15 @@ const typeDefs = gql` } type EnvironmentPendingChanges { - type: String + type: EnvironmentPendingChangeType details: String date: String } + enum EnvironmentPendingChangeType { + ENVVAR + } + type EnvironmentHitsMonth { total: Int }