Skip to content

Conversation

@KevyVo
Copy link
Contributor

@KevyVo KevyVo commented Dec 20, 2025

Description

This pull request introduces a new command for resolving and displaying the final configuration of environment variables in a Compose project or from defang config set.

Enhanced the ComposeUp workflow to print the config resolution summary after validation, providing users with immediate feedback on how environment variables are resolved.

Example:
Screenshot 2025-12-19 at 9 29 28 PM

TODO: write unit test

Linked Issues

#1481

Checklist

  • I have performed a self-review of my code
  • I have added appropriate tests
  • I have updated the Defang CLI docs and/or README to reflect my changes, if necessary

Summary by CodeRabbit

  • New Features

    • Added config resolve CLI subcommand (alias: final) to show a final configuration summary table with where environment variables come from and their resolved values (masked for sensitive configs).
    • Compose up now prints the config resolution summary after validation.
  • Bug Fixes / Improvements

    • Improved detection of interpolation variables and more deterministic validation of environment/config references.

✏️ Tip: You can customize this high-level summary in your review settings.

@KevyVo KevyVo added this to the Dec2025 milestone Dec 20, 2025
@KevyVo KevyVo self-assigned this Dec 20, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 20, 2025

Walkthrough

Adds a new config resolve CLI command and implements config resolution printing. Refactors config validation to accept a precomputed list of config names, extracts interpolation detection, and prints a summary showing each service env var, its source, and masked values for defang configs.

Changes

Cohort / File(s) Summary
CLI Command Integration
src/cmd/cli/command/commands.go
Adds new config resolve (alias final) subcommand wired into the CLI, which loads a loader/provider, loads the project, requests final config names, and invokes the resolution summary print.
Config resolution feature
src/pkg/cli/compose/configResolution.go
New file: introduces configOutput, Source enum and String(), determineConfigSource() helper, masking constant, and PrintConfigResolutionSummary() to collect, sort, and print env-var source/value summaries (masking defang-config values).
Validation signature & helpers
src/pkg/cli/compose/validation.go
Refactors ValidateProjectConfig() to accept listConfigNames []string instead of a function, extracts DetectInterpolationVariables() to return interpolation names, and updates internal checks to use the provided names slice.
Compose up integration
src/pkg/cli/composeUp.go
Eagerly retrieves config names before validation, updates call sites to pass concrete []string, and adds a call to PrintConfigResolutionSummary() after validation.
Tests adjusted
src/pkg/cli/compose/validation_test.go
Removes makeListConfigNamesFunc(...) helper and updates tests to pass explicit []string lists or precomputed results to ValidateProjectConfig().

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User as CLI
    participant Commands as commands.go
    participant Loader as Loader
    participant Provider as Provider
    participant Project as Compose Project
    participant ComposePkg as compose.PrintConfigResolutionSummary
    CLI->>Commands: run `config resolve`
    Commands->>Loader: load environment & loader
    Loader-->>Commands: loader instance
    Commands->>Provider: create provider with loader
    Provider-->>Commands: provider ready
    Commands->>Provider: LoadProject(ctx)
    Provider-->>Project: project data
    Commands->>Provider: ListConfigNames(ctx)
    Provider-->>Commands: []configNames
    Commands->>ComposePkg: PrintConfigResolutionSummary(project, configNames)
    ComposePkg->>Project: inspect services & envs
    ComposePkg->>ComposePkg: determineConfigSource(...) (masking/interpolation)
    ComposePkg-->>Commands: printed summary / result
    Commands-->>CLI: exit/status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas needing attention:
    • determineConfigSource() logic for interpolation detection and correct masking of defang configs (configMaskedValue)
    • Signature change of ValidateProjectConfig and all call sites (composeUp.go, tests) to ensure no missed callers
    • CLI command flow in commands.go for loader/provider error handling and context propagation

Poem

🐰 I hopped through code to find each hidden key,
I sniffed interpolation, then hid what shouldn't be,
For every service and env I tally and show,
Stars mask the secrets while the sources all glow,
A small rabbit cheer for config clarity! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'env vars resolution summary' accurately describes the main feature added: a new config resolution command and summary functionality that displays how environment variables are sourced across services.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kevin/envResolve

Comment @coderabbitai help to get the list of available commands and usage tips.

@KevyVo KevyVo linked an issue Dec 20, 2025 that may be closed by this pull request
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/pkg/cli/compose/validation.go (1)

475-478: Consider the side effect of printing during validation.

The call to PrintConfigResolutionSummary introduces output during validation, which means any code path calling ValidateProjectConfig will now print this summary. This may be intentional for the new config resolve command, but could result in unexpected output in other contexts.

Consider whether:

  • This is the intended behavior for all validation paths, or
  • The summary should only print for the explicit config resolve command

If the latter, you might want to return the summary data from validation and let callers decide when to print it.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6a1b61 and 2deda33.

📒 Files selected for processing (3)
  • src/cmd/cli/command/commands.go (2 hunks)
  • src/pkg/cli/compose/configResolution.go (1 hunks)
  • src/pkg/cli/compose/validation.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/pkg/cli/compose/validation.go (1)
src/pkg/cli/compose/configResolution.go (1)
  • PrintConfigResolutionSummary (68-99)
src/cmd/cli/command/commands.go (2)
src/protos/io/defang/v1/fabric.pb.go (3)
  • ListConfigsRequest (2734-2739)
  • ListConfigsRequest (2752-2752)
  • ListConfigsRequest (2767-2769)
src/pkg/cli/compose/configResolution.go (1)
  • PrintConfigResolutionSummary (68-99)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (go)
🔇 Additional comments (9)
src/cmd/cli/command/commands.go (2)

301-302: LGTM! Command registration is correct.

The new config resolve subcommand is properly registered with the parent configCmd, following the established pattern for other config subcommands.


975-1001: API usage verified. The provider.ListConfig method correctly accepts *defangv1.ListConfigsRequest and returns *defangv1.Secrets with a Names field, as used on line 999.

src/pkg/cli/compose/validation.go (2)

438-450: LGTM! Clean extraction of interpolation variables.

The function correctly extracts variable names from the interpolation regex matches. The implementation is reusable and follows good practices.


461-462: LGTM! Proper use of the new helper function.

The call to DetectInterpolationVariables is safe (after the nil check on line 457) and improves code maintainability by eliminating duplicate logic.

src/pkg/cli/compose/configResolution.go (5)

9-14: LGTM! Well-structured output type.

The configOutput struct is properly defined with appropriate JSON tags and omitempty for optional fields.


16-37: LGTM! Proper enum implementation with Stringer interface.

The Source enum and its String() method are well-implemented, following Go best practices. The fallback to SourceUnknown ensures safety for unexpected values.


41-64: LGTM! Sound logic for determining config source.

The function correctly identifies the source of environment variables and applies masking for sensitive defang config values. The handling of nil values and interpolation references is appropriate.


66-66: LGTM! Appropriate masking constant.

The masked value provides a clear indication that sensitive information is hidden.


68-99: Verify the Project type definition is not a concern.

The Project type is properly defined in an external compose package (likely github.com/compose-spec/compose-go/types or equivalent from Docker CLI) and includes the Services field used by this function. No additional verification or changes are needed.

@KevyVo KevyVo marked this pull request as draft December 20, 2025 05:28
@KevyVo KevyVo marked this pull request as ready for review December 20, 2025 05:53
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/pkg/cli/composeUp.go (1)

73-78: Consider adding context separation for better UX.

The config resolution summary is correctly printed after successful validation. However, consider adding a blank line before the summary for better visual separation in the terminal output, especially if other messages are printed before it.

🔎 Optional: Add visual separation
 		}
 
 		// Print config resolution summary
+		term.Println() // Add blank line for visual separation
 		err = compose.PrintConfigResolutionSummary(*project, listConfigNames)
 		if err != nil {
 			return nil, project, err
 		}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2deda33 and 1bf4bb0.

📒 Files selected for processing (4)
  • src/cmd/cli/command/commands.go (3 hunks)
  • src/pkg/cli/compose/validation.go (2 hunks)
  • src/pkg/cli/compose/validation_test.go (5 hunks)
  • src/pkg/cli/composeUp.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pkg/cli/compose/validation.go
🧰 Additional context used
🧬 Code graph analysis (3)
src/cmd/cli/command/commands.go (3)
src/pkg/cli/compose/validation.go (1)
  • ValidateProjectConfig (452-486)
src/protos/io/defang/v1/fabric.pb.go (3)
  • ListConfigsRequest (2734-2739)
  • ListConfigsRequest (2752-2752)
  • ListConfigsRequest (2767-2769)
src/pkg/cli/compose/configResolution.go (1)
  • PrintConfigResolutionSummary (68-99)
src/pkg/cli/composeUp.go (2)
src/pkg/cli/compose/validation.go (1)
  • ValidateProjectConfig (452-486)
src/pkg/cli/compose/configResolution.go (1)
  • PrintConfigResolutionSummary (68-99)
src/pkg/cli/compose/validation_test.go (1)
src/pkg/cli/compose/validation.go (1)
  • ValidateProjectConfig (452-486)
🔇 Additional comments (6)
src/pkg/cli/compose/validation_test.go (2)

59-67: LGTM! Refactoring aligns with updated validation signature.

The change from lazy function-based config name provision to eager fetching is correct. Error handling is appropriate, and the refactored code properly passes the config names slice to ValidateProjectConfig.


102-102: LGTM! Test cases properly updated for new signature.

All test invocations of ValidateProjectConfig correctly pass explicit []string slices, matching the updated function signature. The test scenarios (empty configs, missing configs, valid configs) remain logically consistent.

Also applies to: 117-117, 140-140, 152-152

src/cmd/cli/command/commands.go (3)

301-302: LGTM! Command properly wired into CLI structure.

The configResolveCmd is correctly added as a subcommand to configCmd.


973-999: LGTM! New command implementation follows established patterns.

The config resolve command is well-structured and follows the same pattern as other commands in this file. It properly:

  • Requires authentication
  • Loads the project and provider
  • Fetches config names from the provider
  • Prints the resolution summary

The error handling is appropriate at each step.


747-747: LGTM! Updated to match new validation signature.

The call to ValidateProjectConfig is correctly updated to pass an empty slice []string{}, which makes sense in this context—the function is collecting unset environment variables by intentionally validating against no configs.

src/pkg/cli/composeUp.go (1)

64-71: LGTM! Proper refactoring to eager config name fetching.

The change correctly:

  • Eagerly fetches config names before validation
  • Handles errors immediately with early return
  • Passes the concrete slice to ValidateProjectConfig
  • Wraps validation errors in ComposeError for proper error classification

@KevyVo KevyVo marked this pull request as draft December 20, 2025 05:57
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.

Print env vars resolution summary at the start of a deployment

2 participants