-
Notifications
You must be signed in to change notification settings - Fork 1.1k
First-run workload experience #34322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…stallWorkloads method during first run. This may be temporary. Cleaned up unused usings in various files. Cleaned up various stray spaces and extra carriage returns. Other various minor edits.
…CI can set it to true to no longer run the workload update.
…running in CI and if the first command called is a workload command. Added start/end text for running the workload command within first-run. Minor cleanup.
# Conflicts: # src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs # src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs
…ommand. Removed unused usings.
@@ -15,6 +15,7 @@ | |||
|
|||
namespace Microsoft.DotNet.Cli.NuGetPackageDownloader | |||
{ | |||
// TODO: Never name a class the same name as the namespace. Update either for easier type resolution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this TODO for (foreshadowing) future cleanup purposes.
private static bool ShouldVerifySignatures(ParseResult parseResult) => | ||
ShouldVerifySignatures(parseResult.GetValue(WorkloadInstallCommandParser.SkipSignCheckOption)); | ||
|
||
public static bool ShouldVerifySignatures(bool skipSignCheck = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method needed to be public for workload integrity check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it currently not possible to cancel the integrity check at all? Or if you try to cancel, does it cancel the whole command instead of just the integrity check (which seems OK to me)?
if (installedWorkloads.Any()) | ||
{ | ||
reporter.WriteLine(LocalizableStrings.WorkloadIntegrityCheck); | ||
CliTransaction.RunNew(context => installer.InstallWorkloads(installedWorkloads, sdkFeatureBand, context)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it may be better to first check if there are any missing workload packs, and only if that's the case try to install them. The difference would be that we could print a message saying that workload packs are missing and that they are being installed. This may be important for msi-based installs, as when it tries to install the workload packs it should pop up an elevation prompt, and a clearer message might help people understand what it's for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to keep the changes simplistic since I wasn't sure if we'd be changing anything else related to workload installs. So, install workloads currently does this kind of check:
The check is within the transaction context. Not sure if that is necessary?? Like, we could just pre-filter the packs before creating the context. Looks like it is only done for message purposes. I didn't want to change this stuff too much as testing the first-run scenario is really time consuming.
If we want to change the messaging, should there really be different messaging between this new process and that of workload update
/workload install
? Testing the CLI command is fairly straight-forward compared to what this PR is fixing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe doing a separate endeavor (different PR) to clean up the workload logging would be appropriate. I've already pointed out in one of the workload meeting chats about how when workloads are already up-to-date, we output 3 lines per pack, which seems a bit noisy.
I'll make a separate issue for this work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created issue to handle this work: #34417
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reducing the spew for updates would be great, but for the first run check, I think it's best if we print out nothing if everything is up to date, not even a "Checking the state of installed workloads..." message. Then if there are updates needed, we could print something like "Installing updated workload packs".
To do so, we could add a HasMissingWorkloadPacks
method to IInstaller
, and do a bit of refactoring to the installer implementations so that they share code between the new method and the InstallWorkloads
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that effort would go into the #34417 issue since it requires extracting out the logic for handling workload installation/messaging as to not be within the command logic directly. Right now, everything is tightly coupled to the concept of running as a CLI command.
That kind of 'tailored' experience could be unit tested when it is refactored, but I'm not planning on refactoring workload installation logic to simply update the text displayed for the initial implementation of this feature. Upon refactoring, we could add some tests within GivenADotnetFirstTimeUseConfigurer.cs
and GivenADotnetFirstTimeUseConfigurerWithStateSetup.cs
to account for the appropriate messaging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be ok with a separate cleanup PR since it will likely need to touch code that's unrelated to the first run experience and possibly have some test fallout as well.
Cancelling cancels the entire command (including the workload integrity check). It just immediately stops doing anything. Here, I cancel as soon as it starts trying to install the workload pack. I'll be creating an issue for supporting cancellation in our use of S.CL in the codebase. For this PR however, as soon as the command is cancelled, it will not reattempt to run the workload integrity check again since the first-run sentinel file exists, which is the desired behavior. Edit: Created this issue for cancellation support. |
… fails, call 'dotnet workload update' to get the proper error message.
…orks around the issue of the log file being locked for the integrity check.
…ment provider for the FlagsCombinationAndAction test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's probably feasible to write some automated tests for this. It may not be the simplest thing, but could be better than having to test everything manually.
In the automated tests we could probably test WorkloadIntegrityChecker directly, instead of also worrying about the first use sentinel. It would need to support passing in mocked versions of the various classes it uses. Other workload commands such as WorkloadUpdateCommand
and the corresponding GivenDotnetWorkloadUpdate
tests show how this can be done.
<value>Checking the state of installed workloads...</value> | ||
</data> | ||
<data name="WorkloadIntegrityCheckError" xml:space="preserve"> | ||
<value>An issue was encountered when verifying workloads. For more information, run "dotnet workload update".</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure dotnet workload update
is the right guidance here to get the error message. For example, if a download failed during the workload integrity check due to network issues, then when you ran dotnet workload update
you might not get the same error.
I'm not sure exactly what we should say here though. Any ideas @baronfel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certainly there will be scenarios in which dotnet workload update
won't show the exact same issue encountered in first-run. However, the point of the first-run check is to validate that the workloads are in a good state. If it fails, it shouldn't impede a user's command. If they see this message in the first command they run and the first command is, say, dotnet build
and their build fails, it gives them another avenue to investigate. dotnet workload update
could fix their scenario, potentially. This first-run check is just a band-aid knee-pad to help avoid potential pain for the user.
One idea is to have error codes for the CLI that go to articles about potential reasons for the errors and possible workarounds. Not sure if we have that many CLI-specific problems were we need that kind of error system, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove the "when" or replace with "while". The string reads odd to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And can you lock the dotnet workload update
string? You can inlcude a comment in the resx, like {Locked="dotnet workload update"}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed the when
and added the formatted {Locked}
comment to the resource.
if (installedWorkloads.Any()) | ||
{ | ||
reporter.WriteLine(LocalizableStrings.WorkloadIntegrityCheck); | ||
CliTransaction.RunNew(context => installer.InstallWorkloads(installedWorkloads, sdkFeatureBand, context)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reducing the spew for updates would be great, but for the first run check, I think it's best if we print out nothing if everything is up to date, not even a "Checking the state of installed workloads..." message. Then if there are updates needed, we could print something like "Installing updated workload packs".
To do so, we could add a HasMissingWorkloadPacks
method to IInstaller
, and do a bit of refactoring to the installer implementations so that they share code between the new method and the InstallWorkloads
method.
…running in CI or not. Then, if the environment variable is provided, it is honored prior to falling back to the default.
I talked with Marc and one approach that seems reasonable is to update the test scenarios we provide to our vendor for workloads to include a test for this first-run functionality. When I was manually testing, one of the main scenarios was for MSI-based installs which we don't have unit tests for currently. I looked into both The intent of the The other call that is made in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, question though, do we need to retarget against release/8.0.1xx?
…rly indicate the locked text for localization.
…ntVariableNames as static strings.
Talked to Marc and he said to also put it into 8.0.1xx. We're trying to see if we can get that backport action working. |
/backport to release/8.0.1xx |
Started backporting to release/8.0.1xx: https://github.com/dotnet/sdk/actions/runs/5883877917 |
@MiYanni backporting to release/8.0.1xx failed, the patch most likely resulted in conflicts: $ git am --3way --ignore-whitespace --keep-non-patch changes.patch
Applying: Added WorkloadIntegrityChecker to use as a sidecar for running the InstallWorkloads method during first run. This may be temporary. Cleaned up unused usings in various files. Cleaned up various stray spaces and extra carriage returns. Other various minor edits.
Using index info to reconstruct a base tree...
M src/Cli/Microsoft.DotNet.Configurer/DotnetFirstTimeUseConfigurer.cs
M src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs
M src/Cli/dotnet/Program.cs
M src/Cli/dotnet/commands/InstallingWorkloadCommand.cs
M src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs
M src/Cli/dotnet/commands/dotnet-workload/clean/WorkloadCleanCommand.cs
M src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs
M src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs
M src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs
M src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallerFactory.cs
M src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs
M src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs
M src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs
M src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs
M src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs
M src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenADotnetFirstTimeUseConfigurerWIthStateSetup.cs
Falling back to patching base and 3-way merge...
Auto-merging src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenADotnetFirstTimeUseConfigurerWIthStateSetup.cs
CONFLICT (content): Merge conflict in src/Tests/Microsoft.DotNet.Configurer.UnitTests/GivenADotnetFirstTimeUseConfigurerWIthStateSetup.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs
CONFLICT (content): Merge conflict in src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs
CONFLICT (content): Merge conflict in src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs
CONFLICT (content): Merge conflict in src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallerFactory.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs
CONFLICT (content): Merge conflict in src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/clean/WorkloadCleanCommand.cs
Auto-merging src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandBase.cs
Auto-merging src/Cli/dotnet/commands/InstallingWorkloadCommand.cs
CONFLICT (content): Merge conflict in src/Cli/dotnet/commands/InstallingWorkloadCommand.cs
Auto-merging src/Cli/dotnet/Program.cs
Auto-merging src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs
Auto-merging src/Cli/Microsoft.DotNet.Configurer/DotnetFirstTimeUseConfigurer.cs
CONFLICT (content): Merge conflict in src/Cli/Microsoft.DotNet.Configurer/DotnetFirstTimeUseConfigurer.cs
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Added WorkloadIntegrityChecker to use as a sidecar for running the InstallWorkloads method during first run. This may be temporary. Cleaned up unused usings in various files. Cleaned up various stray spaces and extra carriage returns. Other various minor edits.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128 Please backport manually! |
@MiYanni an error occurred while backporting to release/8.0.1xx, please check the run log for details! Error: git am failed, most likely due to a merge conflict. |
Fixes: #31872
Summary
There are certain situations where the user of the CLI might have updated the SDK version which brings in updated workload manifests within the same feature band. The user had workloads installed previously. However, they won't have the updated packages for the workloads that apply to the new manifests.
This PR makes it so that when the first-run experience for an SDK version activates, it (conditionally) runs the process for checking the state of the installed workloads, similar to the process done for the
workload update
command. For the purposes of this feature, I've called it "workload integrity check" since (conceptually) makes sure you're in a 'good' state with the workloads desired.Key Aspects
.dotnetFirstUseSentinel
for the proper SDK version is not present on-disk..dotnetFirstUseSentinel
is created prior to running the workload integrity check. This means that if, for any reason, the workload check doesn't work or run, it won't try to do it again.dotnet workload update
if they want the actual error details.DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK
.This is set tofalse
by default. If set totrue
, the workload integrity check will be skipped.true
(meaning, skip the check) if running in CI. Otherwise,false
is the default.If the first-run command is a workload command, the workload integrity check is skipped. This avoids an open file conflict with the workload log file.Testing Notes
workload
command is properly skipping the workload integrity check.Example Output
Other