Skip to content

Conversation

jjonescz
Copy link
Member

Part of dotnet/aspnetcore#63440.
Limited to file-based apps only to alleviate the concerns raised in #50597 (comment).

@jjonescz jjonescz added the Area-run-file Items related to the "dotnet run <file>" effort label Sep 12, 2025
@jjonescz jjonescz marked this pull request as ready for review September 12, 2025 14:44
@jjonescz jjonescz requested review from a team and Copilot September 12, 2025 14:44
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements implicit UserSecretsId setting for file-based applications to support user secrets functionality. This addresses a limitation where file-based apps couldn't use user secrets without explicit configuration.

  • Automatically sets UserSecretsId as a hash of the entry point file path for file-based programs
  • Adds comprehensive test coverage for user secrets functionality with both explicit and implicit ID scenarios
  • Updates documentation to reflect the new implicit UserSecretsId behavior

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.props Adds MSBuild property to implicitly set UserSecretsId for file-based apps
test/dotnet.Tests/CommandTests/Run/RunFileTests.cs Adds test cases for user secrets functionality with both ID argument and file-based scenarios
documentation/general/dotnet-run-file.md Documents the new implicit UserSecretsId behavior for file-based apps

@jjonescz jjonescz marked this pull request as draft September 12, 2025 15:05
@jjonescz
Copy link
Member Author

@RikkiGibson @333fred for reviews, thanks

@RikkiGibson RikkiGibson self-assigned this Sep 16, 2025
var directives = VirtualProjectBuildingCommand.FindDirectives(sourceFile, reportAllErrors: !_force, DiagnosticBag.ThrowOnFirst());

// Create a project instance for evaluation.
string entryPointFileDirectory = PathUtility.EnsureTrailingSlash(Path.GetDirectoryName(file)!);
Copy link
Member

Choose a reason for hiding this comment

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

Consider making this just a parameter to FindIncludedItems, in order to make things more clear. It feels unnecessary to rely on capture, when the variable is not used in the declaring method itself.

Copy link
Member

Choose a reason for hiding this comment

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

The most straightforward thing might be to delete the declaration here and restore the declaration in FindIncludedItems().

Copy link
Member

Choose a reason for hiding this comment

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

Agreed with Rikki, that this is only referenced via capture is somewhat confusing. I'd personally just pass this as a parameter where needed.

Copy link
Member Author

@jjonescz jjonescz Sep 17, 2025

Choose a reason for hiding this comment

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

The most straightforward thing might be to delete the declaration here and restore the declaration in FindIncludedItems().

Yes, thanks, I extracted this line unintentionally (because it was in the block of code that I wanted to extract).

Copy link
Member

@333fred 333fred Sep 17, 2025

Choose a reason for hiding this comment

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

I don't think the latest commit really addresses the concern, am I missing something? Or were Rikki and I commenting on different things? I assumed Rikki meant the entire projectCollection/projectInstance dual locals; I'm not a fan of how they're only referenced via capture.

Copy link
Member

Choose a reason for hiding this comment

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

I thought about pushing on the capture thing on more than just entryPointFileDirectory but decided I didn’t feel too strongly. However I would generally prefer that locals are not used as “capture only” even if multiple local functions are capturing them.

Copy link
Member Author

@jjonescz jjonescz Sep 18, 2025

Choose a reason for hiding this comment

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

Are you saying we should never use non-static local functions?

I think some capturing makes for a cleaner code, although for code reviews I would recommend using VSCode with C# extension where you can actually hover over the function to see the captured variables.

I also don't like functions with a lot of "weakly" typed arguments (like bools and strings) as it's easy to pass the wrong thing to them. Capturing also helps with this, because you just reference the original thing by name.

Given this is a pre-existing issue (the existing local functions are already capturing variables) and you both signed off, I'm going to merge this, but happy to discuss further and change things in a follow up PR if needed.

}

[Fact]
public void UserSecretsId_Overridden_ViaDirectoryBuildProps()
Copy link
Member

Choose a reason for hiding this comment

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

The following are corner cases, but it may be worthwhile to test them, just so we know the behavior.

  • UserSecretsId is specified via #:property and the value is exactly the same as the one we determined implicitly.
  • UserSecretsId is specified via Directory.Build.props and the value is exactly the same as the one we determined implicitly.

var testInstance = _testAssetsManager.CreateTestDirectory();

string code = $"""
#:package Microsoft.Extensions.Configuration.UserSecrets@*-*
Copy link
Member

@RikkiGibson RikkiGibson Sep 16, 2025

Choose a reason for hiding this comment

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

I am unsure if it is best to use a wildcard version here. For example, it could be disruptive if someone were PRing into a servicing branch, and some interaction with a newer version of the package, was causing the old branch version of this test to fail.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a good point, thanks.

Copy link
Member

@RikkiGibson RikkiGibson left a comment

Choose a reason for hiding this comment

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

LGTM aside from some minor comments.

var directives = VirtualProjectBuildingCommand.FindDirectives(sourceFile, reportAllErrors: !_force, DiagnosticBag.ThrowOnFirst());

// Create a project instance for evaluation.
string entryPointFileDirectory = PathUtility.EnsureTrailingSlash(Path.GetDirectoryName(file)!);
Copy link
Member

Choose a reason for hiding this comment

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

Agreed with Rikki, that this is only referenced via capture is somewhat confusing. I'd personally just pass this as a parameter where needed.

@jjonescz jjonescz merged commit 8f0b635 into dotnet:release/10.0.1xx Sep 18, 2025
27 checks passed
@jjonescz jjonescz deleted the sprint-user-secrets-2 branch September 18, 2025 08:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-run-file Items related to the "dotnet run <file>" effort

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants