feat: handle multiple env vars, add/update multiple, delete multiple#4093
Open
dan2k3k4 wants to merge 8 commits into
Open
feat: handle multiple env vars, add/update multiple, delete multiple#4093dan2k3k4 wants to merge 8 commits into
dan2k3k4 wants to merge 8 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds batch GraphQL mutations to upsert and delete multiple environment variables in a single call, scoped to exactly one target (organization, project, or project+environment). It extends the API with a structured per-entry result model and adds Ansible-based integration tests to exercise the new behavior.
Changes:
- Added GraphQL schema for
EnvVariableBatchResult/EnvVariableBatchEntryResultplus new batch mutations and inputs. - Implemented batch resolver logic with shared target/permission/restriction checks and per-entry error handling.
- Introduced a configurable batch size limit (
BATCH_ENV_VARS_LIMIT) and added test playbooks/templates for batch add/delete.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
services/api/src/typeDefs.js |
Adds new batch result types, inputs, and two new mutations to the GraphQL schema. |
services/api/src/util/config.ts |
Adds envVarsConfig.batchLimit driven by BATCH_ENV_VARS_LIMIT. |
services/api/src/resources/env-variables/resolvers.ts |
Implements batch target resolution, batch size enforcement, and the two new batch resolvers with audit logging. |
services/api/src/resolvers.js |
Wires the new batch resolvers into the GraphQL Mutation map. |
tests/tasks/api/batch-add-project-variables.{gql,yaml} |
Adds Ansible task + GraphQL template to test batch upsert at project scope. |
tests/tasks/api/batch-delete-project-variables.{gql,yaml} |
Adds Ansible task + GraphQL template to test batch delete at project scope. |
tests/tests/api/batch-project-variables.yaml |
Adds a wrapper playbook to run the batch add + batch delete test flow. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
97e0342 to
c76f97b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4092
Summary
Adds two new GraphQL mutations on the API service for batch environment variable operations, scoped to a single organization, project, or environment per call:
addOrUpdateEnvVariablesByName— create or update many variablesdeleteEnvVariablesByName— delete many variables (idempotent)Both return a structured
EnvVariableBatchResultso callers can observe per-entry outcomes when a batch partially fails. See #4092 for the full API rationale, schema, error model, and acceptance criteria.API surface
Behavior
Targeting — exactly one of: organization-only, project-only, or project + environment. Any other combination is rejected.
Two-tier error model
results, sibling entries continue): empty/blankname, deprecatedinternal_container_registryscope, DB constraint errors.Delete is idempotent — a name that does not exist for the target reports
success: true. This lets sync workflows declare "these N should not exist" without first querying.Permission and project-restriction checks run once per call for the shared target, reusing the existing Keycloak scopes (
env_var:project:add,env_var:environment:add:{type},organization:addEnvVar, and the corresponding:deletescopes) — no new scopes were added.Atomicity — per-entry try/catch in a loop, no DB transaction. Pre-flight validation makes mid-batch failures unlikely; when they happen, the result tells the caller exactly which entries persisted. Modeled on the existing
processAddFactspattern.Audit log — one
userActivityLoggerentry per call summarizing the batch (envVarType, target name, count, successCount, failureCount, names list), not one per entry.Batch size limit — default 20 entries, overridable via the
BATCH_ENV_VARS_LIMITenv var on the API service (consistent with other env-driven config inservices/api/src/util/config.ts). Oversize batches are rejected as a whole-batch error so the client knows to chunk. A TODO is left in the resolver noting that automatic server-side chunking could be added if usage warrants it.Files changed
services/api/src/typeDefs.jsservices/api/src/util/config.tsenvVarsConfig.batchLimitservices/api/src/resources/env-variables/resolvers.tsresolveEnvVarBatchTarget,upsertEnvVarRowForTarget,deleteEnvVarRowByNameForTarget,enforceBatchSizehelpers and the two new resolversservices/api/src/resolvers.jstests/tasks/api/batch-add-project-variables.{gql,yaml}tests/tasks/api/batch-delete-project-variables.{gql,yaml}tests/tests/api/batch-project-variables.yamlThe existing singular
addOrUpdateEnvVariableByName/deleteEnvVariableByNameresolvers are untouched — this change is purely additive. No DB migration. No new Keycloak scopes.Example
{ "input": { "project": "my-project", "environment": "main", "variables": [ { "name": "API_TOKEN", "value": "...", "scope": "RUNTIME" }, { "name": "BUILD_FLAG", "value": "1", "scope": "BUILD" }, { "name": "FEATURE_X", "value": "on", "scope": "GLOBAL" } ] } }Verification
yarn workspace api run build— passes (TypeScript clean).yarn workspace api run test— same 4 pre-existing snapshot/redis failures asmain(notification, environment, advancedtasktoolbox, sshKey); no new failures introduced.make api-developmentfor iterating on GraphQL changes without spinning up the full stack — used to verify mutations against the API.Acceptance criteria (from #4092)
addOrUpdateEnvVariablesByNameaccepts org / project / environment-scoped batches and returns anEnvVariableBatchResult.deleteEnvVariablesByNameaccepts the same scoping and returns anEnvVariableBatchResult; deleting a non-existent name reportssuccess: true.resultsand do not abort sibling entries.BATCH_ENV_VARS_LIMIT.