Skip to content

env import and single secret creation conflict resolution#956

Open
teyim wants to merge 2 commits into
phasehq:mainfrom
teyim:feat--env-import-conflict-resolution
Open

env import and single secret creation conflict resolution#956
teyim wants to merge 2 commits into
phasehq:mainfrom
teyim:feat--env-import-conflict-resolution

Conversation

@teyim

@teyim teyim commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

🔍 Overview

This PR improves duplicate secret-key handling across environment imports and inline secret editing.

Previously, importing .env content containing repeated keys could produce ambiguous results because users could not explicitly choose which value to retain. Duplicate keys created or edited directly in secret rows also lacked clear, actionable feedback. (Related to #946 )

This change introduces a conflict-resolution workflow for imports and inline duplicate-key validation for environment and app secret rows.

💡 Proposed Changes

Import conflict resolution

  • Add a conflict-resolution step to single- and multi-environment import dialogs.
  • Detect repeated keys without collapsing their original occurrences.
  • Prompt users to resolve duplicates containing different values before continuing.
  • Automatically resolve repeated keys whose values are identical.
  • Allow users to:
    • Select an individual value for each conflicting key.
    • Reveal or hide secret values.
    • Keep the first occurrence for all conflicts.
    • Keep the last occurrence for all conflicts.
    • Reset all conflict selections.
  • Display resolution progress and prevent continuing while conflicts remain unresolved.

Inline duplicate-key validation

  • Detect duplicate keys in environment and app secret rows.
  • Highlight conflicting key inputs.
  • Display an actionable message referencing the other conflicting row.
  • Exclude secrets staged for deletion from duplicate detection.
  • Include dynamic and rotating secret keys when checking for conflicts.

Internal improvements

  • Add reusable .env parsing, grouping, and conflict-resolution utilities.
  • Add a shared key-position index for case-insensitive duplicate lookup and accurate row references.
  • Replace duplicated key-position bookkeeping in the environment and app secret views.
  • Preserve ph-no-capture protection for sensitive values and validation content.
  • Use smaller monospaced typography for secret keys and values.

🖼️ Screenshots or Demo

Development.Example.App.testing.Phase.Console.July.mp4

📝 Release Notes

Added an explicit conflict-resolution workflow for duplicate keys found during .env imports. Users can now review conflicting values and select which occurrence to retain before importing.

Duplicate keys entered directly in environment or app secret rows are now highlighted with actionable validation feedback.

There are no breaking changes or migration requirements.

❓ Open Questions

If there are aspects of the changes that you're unsure about or would like feedback on, list them here.

🧪 Testing

Added and updated tests covering:

  • Parsing .env content without collapsing duplicate keys.
  • Grouping duplicate occurrences.
  • Detecting duplicates case-insensitively.
  • Resolving conflicts using individual selections.
  • Selecting the first or last occurrence in bulk.
  • Handling identical duplicate values.
  • Handling empty and multiline values.
  • Excluding secrets staged for deletion.
  • Building reusable key-position indexes.
  • Preserving displayed row numbers for excluded entries.
  • Rendering accessible duplicate-key validation messages.
  • Rendering and interacting with the conflict-resolution component.

🎯 Reviewer Focus

Suggested review order:

  1. frontend/utils/secrets.ts

    • .env parsing and conflict-resolution behavior.
    • Duplicate detection and reusable key-position indexing.
  2. frontend/components/environments/secrets/import/EnvConflictResolution.tsx

    • Conflict selection and bulk actions.
    • Value visibility and accessibility.
  3. Import dialogs

    • SingleEnvImportDialog.tsx
    • MultiEnvImportDialog.tsx
    • Integration of the conflict-resolution step into existing import flows.
  4. Inline secret rows

    • SecretRow.tsx
    • AppSecretRow.tsx
    • Inline duplicate-key feedback and accessibility attributes.
  5. Environment and app secret lists

    • Duplicate detection across regular, rotating, and dynamic secrets.
    • Exclusion of secrets staged for deletion.
  6. Component and utility tests

    • Expected behavior and edge-case coverage.

➕ Additional Context

  • The key-position index preserves visible row numbering even when a secret is excluded from duplicate detection. This ensures validation messages reference the row number users see in the UI.
  • Keys are normalized case-insensitively, so names such as API_KEY and api_key are treated as duplicates.
  • No dependencies, database migrations, GraphQL schema changes, or generated types are required.

✨ How to Test the Changes Locally

Start the development stack and open https://localhost/. Import .env content containing duplicate keys with different values, confirm the conflict-resolution step appears, and verify individual selection, reveal/hide, bulk resolution, reset, and continue behavior. Also create duplicate keys directly in environment and app secret rows to confirm inline validation appears and is removed when a conflicting secret is renamed or staged for deletion.

💚 Did You...

  • Ensure linting passes (code style checks)?
  • Update dependencies and lockfiles (if required)
  • Update migrations (if required)
  • Regenerate graphql schema and types (if required)
  • Verify the app builds locally?
  • Manually test the changes on different browsers/devices?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant