Skip to content

fix: allow editing .env files for GitOps-managed projects (#1748)#1853

Open
cougz wants to merge 1 commit intogetarcaneapp:mainfrom
cougz:fix/1748-allow-env-edit-gitops-projects
Open

fix: allow editing .env files for GitOps-managed projects (#1748)#1853
cougz wants to merge 1 commit intogetarcaneapp:mainfrom
cougz:fix/1748-allow-env-edit-gitops-projects

Conversation

@cougz
Copy link

@cougz cougz commented Feb 22, 2026

Summary

Fixes #1748 - Allow editing .env files for GitOps-managed projects

Restores original design intent where .env files can be edited in Arcane for environment-specific runtime configuration, even for projects synced from Git.

Related Issue

Fixes #1748

Background

The bug was introduced in PR #1632 (commit 7f05d17) when adding .env sync capability from Git repositories. The developer made .env editor read-only "for consistency" with compose editor, but this violated original design intent established in PR #1089 and PR #1471.

Key facts:

  • UI message explicitly states: "The environment file (.env) can still be edited in Arcane to provide runtime configuration"
  • Backend already accepts .env updates for GitOps projects (PR fix: unable to save env in git synced project #1471)
  • Best practices dictate .env files should be environment-specific (API keys, secrets), not Git-tracked infrastructure

Changes

  • Removed canEditEnv derived variable from project detail page
  • Removed readOnly={!canEditEnv} attributes from all .env CodePanel components (4 locations)
  • Removed test that incorrectly expected read-only env editor for GitOps projects

How Both Scenarios Work After Fix

The backend sync logic already handles both cases correctly:

Scenario 1 (.env in Git): Users CAN edit, but Git sync overwrites changes (Git is source of truth)
Scenario 2 (.env not in Git): Users CAN edit, and changes are preserved (local customization)

Testing

  • Frontend code changes verified
  • All canEditEnv references removed from project page
  • Incorrect test removed from test suite
  • Frontend type checking passes: just lint frontend
  • Manual testing: .env editor is editable for GitOps-managed projects
  • Manual testing: compose.yaml editor remains read-only for GitOps-managed projects (unchanged)
  • Manual testing: Save functionality works correctly

Technical Details

Frontend (frontend/src/routes/(app)/projects/[projectId]/+page.svelte):

  • Removed line 93: let canEditEnv = $derived(!isGitOpsManaged);
  • Removed readOnly={!canEditEnv} from lines ~547, ~642, ~707, ~744 (all .env CodePanel instances)

Tests (tests/spec/project.spec.ts):

  • Removed test "should have env editor in read-only mode when GitOps managed" (lines 414-443)

Verification Steps

To complete testing after merging:

  1. Start dev environment

    ./scripts/development/dev.sh start
  2. Run type checking

    just lint frontend
    # OR
    cd frontend && npm run check
  3. Manual testing

    • Navigate to a GitOps-managed project
    • Go to Configuration tab
    • Verify .env editor is editable (not read-only)
    • Verify compose.yaml editor is still read-only
    • Add an environment variable to .env (e.g., TEST_VAR=test_value)
    • Click Save
    • Verify save succeeds and variable persists
    • Refresh page and verify variable is still present

Disclaimer Greptiles Reviews use AI, make sure to check over its work.

To better help train Greptile on our codebase, if the comment is useful and valid Like the comment, if its not helpful or invalid Dislike

Greptile Summary

This PR restores the original design intent that .env files should be editable in Arcane even for GitOps-managed projects, fixing a regression introduced in PR #1632. The change is well-reasoned and consistent with the existing backend behavior and UI messaging.

Key changes:

  • Removes the canEditEnv = $derived(!isGitOpsManaged) variable from +page.svelte (the only meaningful logic change)
  • Removes readOnly={!canEditEnv} from all four .env CodePanel instances across the classic and tree layout views
  • The save handler already correctly sends envContent to the backend for GitOps projects while skipping namePayload and composePayload (lines 193–198), so the backend integration requires no changes
  • The existing GitOps alert banner already displays the git_managed_env_note message informing users that the .env file can be edited — the UI and code are now consistent
  • The old spec that asserted read-only behavior was removed; a counterpart test asserting editable behavior was not added, leaving a minor test coverage gap

Confidence Score: 4/5

  • Safe to merge — the logic change is minimal and the backend already supports the intended behavior.
  • The fix is a straightforward removal of a derived variable and its prop bindings. The save logic correctly sends env content for GitOps projects already. The UI message already told users the env file was editable. The only concern is missing test coverage for the new intended behavior, but this is minor and does not affect production correctness.
  • No files require special attention beyond the minor test coverage gap in tests/spec/project.spec.ts.

Important Files Changed

Filename Overview
frontend/src/routes/(app)/projects/[projectId]/+page.svelte Removes canEditEnv derived variable and its readOnly bindings from all four .env CodePanel instances, allowing GitOps-managed projects to edit their env files. The save logic already correctly sends envContent to the backend regardless of GitOps status (lines 192–198). The UI already shows a note informing users the env file can be edited. Minor trailing whitespace left at lines 546 and 705 (previously flagged).
tests/spec/project.spec.ts Removes the now-incorrect test that expected the env editor to be read-only for GitOps-managed projects. No replacement test is added to assert the env editor is editable for GitOps projects, leaving a coverage gap for this specific behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User on GitOps Project\nConfiguration Tab] --> B{isGitOpsManaged?}
    B -- Yes --> C[compose.yaml CodePanel\nreadOnly=true\nvia canEditCompose]
    B -- Yes --> D[.env CodePanel\nreadOnly=false\neditable ✅]
    B -- No --> E[compose.yaml CodePanel\nreadOnly=false]
    B -- No --> F[.env CodePanel\nreadOnly=false]
    D --> G[User edits .env\nhasChanges = true]
    G --> H[handleSaveChanges]
    H --> I{isGitOpsManaged?}
    I -- Yes --> J[namePayload = undefined\ncomposePayload = undefined\nenvContent = edited value]
    I -- No --> K[namePayload = name\ncomposePayload = compose\nenvContent = edited value]
    J --> L[projectService.updateProject]
    K --> L
Loading

Last reviewed commit: 35ffb50

…pp#1748)

Restores original design intent where .env files can be edited in Arcane
for environment-specific runtime configuration, even for projects synced from Git.

Changes:
- Removed canEditEnv derived variable that blocked .env editing for GitOps projects
- Removed readOnly={!canEditEnv} from all .env CodePanel components (4 locations)
- Removed test that incorrectly expected read-only env editor
@cougz cougz requested a review from a team February 22, 2026 14:32
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

bind:value={$inputs.envContent.value}
error={$inputs.envContent.error ?? undefined}
readOnly={!canEditEnv}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line contains only a space character - should be removed entirely

Suggested change
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/routes/(app)/projects/[projectId]/+page.svelte
Line: 546

Comment:
Line contains only a space character - should be removed entirely

```suggestion
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +635 to +641
<CodePanel
bind:open={envOpen}
title=".env"
language="env"
bind:value={$inputs.envContent.value}
error={$inputs.envContent.error ?? undefined}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is inconsistent - <CodePanel should have 11 tabs to match other CodePanel instances and its props

Suggested change
<CodePanel
bind:open={envOpen}
title=".env"
language="env"
bind:value={$inputs.envContent.value}
error={$inputs.envContent.error ?? undefined}
/>
<CodePanel
bind:open={envOpen}
title=".env"
language="env"
bind:value={$inputs.envContent.value}
error={$inputs.envContent.error ?? undefined}
/>

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/routes/(app)/projects/[projectId]/+page.svelte
Line: 635-641

Comment:
Indentation is inconsistent - `<CodePanel` should have 11 tabs to match other CodePanel instances and its props

```suggestion
										<CodePanel
											bind:open={envOpen}
											title=".env"
											language="env"
											bind:value={$inputs.envContent.value}
											error={$inputs.envContent.error ?? undefined}
										/>
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

bind:value={$inputs.envContent.value}
error={$inputs.envContent.error ?? undefined}
readOnly={!canEditEnv}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line contains only a space character - should be removed entirely

Suggested change
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/routes/(app)/projects/[projectId]/+page.svelte
Line: 705

Comment:
Line contains only a space character - should be removed entirely

```suggestion
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +736 to +742
<CodePanel
bind:open={envOpen}
title=".env"
language="env"
bind:value={$inputs.envContent.value}
error={$inputs.envContent.error ?? undefined}
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is inconsistent - <CodePanel should have 11 tabs to match other CodePanel instances and its props

Suggested change
<CodePanel
bind:open={envOpen}
title=".env"
language="env"
bind:value={$inputs.envContent.value}
error={$inputs.envContent.error ?? undefined}
/>
<CodePanel
bind:open={envOpen}
title=".env"
language="env"
bind:value={$inputs.envContent.value}
error={$inputs.envContent.error ?? undefined}
/>

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/routes/(app)/projects/[projectId]/+page.svelte
Line: 736-742

Comment:
Indentation is inconsistent - `<CodePanel` should have 11 tabs to match other CodePanel instances and its props

```suggestion
										<CodePanel
											bind:open={envOpen}
											title=".env"
											language="env"
											bind:value={$inputs.envContent.value}
											error={$inputs.envContent.error ?? undefined}
										/>
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

@kmendell
Copy link
Member

Making it read only was my idea, as if its synced editing it would get overridden on the next sync. How would you propose solving that issue?

@StevenMcElligott
Copy link

Making it read only was my idea, as if its synced editing it would get overridden on the next sync. How would you propose solving that issue?

Most people don't sync .env on their git repositories, but if people have .env on their .git then they should be on their own since you can't exclude them from a git pull. Generally people only .env.example or etc and those who want full sync will have it

@cougz
Copy link
Author

cougz commented Feb 22, 2026

Making it read only was my idea, as if its synced editing it would get overridden on the next sync. How would you propose solving that issue?

So there are two Use Cases we need to handle:

  1. Use Case A (.env in Git, user probably wants to sync .env): This always worked, but now it blocks local change so Git remains the source of truth.
  2. Use Case B (.env not in Git, user wants local-only config): This is no longer possible because of the readOnly change.

The backend sync logic (updateProjectForSyncInternal) already handles both cases correctly - this PR just removes the blocking restriction that prevented all GitOps users from editing. Do you see an issue here?

Obviously, we could add a visual indicator in the UI showing that .env is Git-synced or implement a slider, but that's not really required for this PR.

@kmendell
Copy link
Member

I'll try to fix it/build off of this branch to do it. If .env files are in a private git site hosted locally I see no issue with people syncing them, that only becomes a issue when people are pushing env files to public git sites imho.

@github-actions
Copy link

This pull request has merge conflicts. Please resolve the conflicts so the PR can stay up-to-date and reviewed.

@kmendell kmendell closed this Mar 2, 2026
@kmendell kmendell reopened this Mar 2, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 411 to 412
expect(isReadOnly).toBe(true);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for new expected behavior

The test verifying that the env editor is read-only for GitOps-managed projects was removed, but no replacement test was added to verify the new expected behavior — that the .env editor is editable for GitOps-managed projects.

Without this test, a future regression (e.g. accidentally reintroducing readOnly on the env CodePanel) could go undetected. Consider adding a counterpart test like:

test("should have env editor in editable mode when GitOps managed", async ({ page }) => {
  const gitOpsProject = realProjects.find((p) => p.gitOpsManagedBy);
  test.skip(!gitOpsProject, "No GitOps-managed projects found");

  await page.goto(`/projects/${gitOpsProject!.id}`);
  await page.waitForLoadState("networkidle");

  const configTab = page.getByRole("tab", { name: /Configuration|Config/i });
  await configTab.click();
  await page.waitForLoadState("networkidle");

  await page.waitForTimeout(1000);

  const isReadOnly = await page.evaluate(() => {
    const editors = (window as any).monaco?.editor?.getEditors() ?? [];
    const envEditor = editors.find((e: any) => {
      const model = e.getModel();
      return model && model.getLanguageId() === "ini";
    });
    if (envEditor) {
      return envEditor.getOption((window as any).monaco.editor.EditorOption.readOnly);
    }
    return null;
  });

  expect(isReadOnly).toBe(false);
});
Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/spec/project.spec.ts
Line: 411-412

Comment:
**Missing test for new expected behavior**

The test verifying that the env editor is read-only for GitOps-managed projects was removed, but no replacement test was added to verify the new expected behavior — that the `.env` editor **is** editable for GitOps-managed projects.

Without this test, a future regression (e.g. accidentally reintroducing `readOnly` on the env `CodePanel`) could go undetected. Consider adding a counterpart test like:

```ts
test("should have env editor in editable mode when GitOps managed", async ({ page }) => {
  const gitOpsProject = realProjects.find((p) => p.gitOpsManagedBy);
  test.skip(!gitOpsProject, "No GitOps-managed projects found");

  await page.goto(`/projects/${gitOpsProject!.id}`);
  await page.waitForLoadState("networkidle");

  const configTab = page.getByRole("tab", { name: /Configuration|Config/i });
  await configTab.click();
  await page.waitForLoadState("networkidle");

  await page.waitForTimeout(1000);

  const isReadOnly = await page.evaluate(() => {
    const editors = (window as any).monaco?.editor?.getEditors() ?? [];
    const envEditor = editors.find((e: any) => {
      const model = e.getModel();
      return model && model.getLanguageId() === "ini";
    });
    if (envEditor) {
      return envEditor.getOption((window as any).monaco.editor.EditorOption.readOnly);
    }
    return null;
  });

  expect(isReadOnly).toBe(false);
});
```

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐞 Bug: Cannot edit .env file in project synced from Git

3 participants