Skip to content

Commit af7cf59

Browse files
dingmeng-xuemsJinLeiVeryEarlymsJinLeimsJinLei
authored
Merge internal/Az.Tools.Predictor (#13546)
* psd1 & psm1 of Az.Installer with a demo cmdlet (#12698) * Internal/az.installer (#12817) * add util functions * add install-azmodule * add log to cmdlets * move verbose messages to debug * move under tools\ * polish warning message * move install-azmodule to exports * export install-azmodule * rename to az.tools.installer * Internal/az.installer (#12860) * add util functions * add install-azmodule * add log to cmdlets * move verbose messages to debug * move under tools\ * polish warning message * move install-azmodule to exports * export install-azmodule * rename to az.tools.installer * add uninstall-AzModule * Cmdlet Update-AzModule (#12832) * Update-AzModule * Address to PM requirements 1. Remove prefix Az. when input module name 2. update calculate from most recently installed respositories of different modules 3. reorder the sequence of module udpate and uninstall 4. other bug fix * Add telemetry * Support telemetry * Move Get-AzModuleUpdateList to internal (#12865) * add telemetry to Uninstall-AzModule cmdlet * bugfix: module name was not handled properly * Add environment variable to disable telemetry * parallel executing Install/Uninstall module * update code after review * improve performance * Fix Update-AzModule issues * bug fix * remove unused util * remove az.accounts when allow preview * Fix issue when no module to udpate * Add sign pipeline * skip confirmation when remove-job * remove debug info * fix parameter reference * Initial checking in AzPredictor (#12847) - It contains an implementation of ICommandPredictor that provides predictions to PSReadLine. - It also talks to the service endpoints to get the predictions. - It reads from the profile settings about the service endpoint. - There are some tests cases. * filter installedmodules before uninstall * bugfix for uninstall * Add synopsis and example to exported cmdlets * add default parameter set for uninstall-azmodule * add input validatin * remove unnecessary warning message * Build and package module under artifacts folder * Improve Az.Tool.Predictor (#12922) * Set up the dependencies on the PSReadline 2.1.0 * Initialize the env when the module is imported. - Add a script AzPredictor.ps1 to set the psreadline prediction view and source. - The script is run when the module is imported. * Fix a bug when loading settings from user profile. - The settings from user profile may not exist. In this case we should just ignore it and use the default one. * Fix issues in getting settings and send requests. - Fix the way to get the Azure PowerShell settings regarding collecting telemetry. - Avoid sending multiple requests while there is one running. * Use the NuGet pacakges from nuget.org. - Remove the local feed for those NuGet packages. * Rename namespace/assemblies/module name * Collect telemetry where we get the prediction. * Make some classes internal. * Add dependencies on Az module - This avoid the issue that our module loads Microsoft.Azure.PowerShell.Common dlls and Az tries to load it too. * Remove ps1 file that sets psreadline options. - We should instruct the users to set the options by themselves. * Remove psreadline module since it's not released. * Fix the merge issue * Add Az as external dependency * Add pipeline 'sign-tool-predictor' * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * net.webclient.downloadfile * refine command * clean build * Update sign-tool-predictor.yml for Azure Pipelines * Improve the build of Az.Tools.Predictor (#12974) * Change the build for Az.Tools.Predictor - Do a 'dotnet publish' instead of 'dotnet build' when the configuration is release. - When the configuration is release, replace the output folder with the ones from publish folder. The output folder is where the package retrieve the contents from. This will have the module and all the dependencies in the package. - The package target only runs when the configuration is release. - Add a target Test to run the unit tests. - Update the build command in azure pipeline to build with configuration release. * Specify the sub-folder artifact for each tool. - The build process involves deleting the artifact folders. And each tool shares the same artifact folder. This may be an issue if we build them in parralel because the build process of a tool will delete the folder while another tool is being built. - We'll use sub-folder for each tool in the artifact folder. Co-authored-by: Beisi Zhou <[email protected]> * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Override powershellcorecommandPrefix * join_path * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Install Az * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Sign dll * Remove dll sign * Predict parameter values in the suggestion (#12984) * Get the parameter value from the history. * Add a mock ps console for testing purpose. - The mock ps console will echo back most of the commands. So that we don't need to really execute the Az command on Azure to test the prediction. * improve telemetry (#13025) * Correlate the telemetry event we send. - We have these telemetry entry points when we provide suggestion, when a suggestion is accepted, and when the user executes some command. We add a SuggestionId to the telemetry events so that we can correlate those three events. Doing that we know what suggestions are provided, accepted, and executed. * Collect and correlate our telemetry event. - With this change, we have these telemetry events; * RequestPrediction * GetSuggestion * AcceptSuggestion * CommandHistory - The events can be correlated by the session id and correlate id that are associate with the events. * Fix the request body. * Rename the prediction source. * Collect telemetry when an error occurs. * Remove some PII field * Collect user input in GetSuggestion event. * Use a common telemetry event prefix. * Remove the .gitignore that shouldn't be added. * Clean up the code. * return multiple suggestion (#13098) * Return multiple suggestions. - Add a setting to configure at most how many suggestions to return. - We'll go through the command/parameters one by one and to construct the suggestion. We may return multiple suggestions for the same command but with different parameter sets; * Use camel casing in the setting fields. - Looks like other json file in $HOME/.azure use camel case or PascalCase. None use snake case. * Fix a logic error. - We'll use the command list for suggestion while the prediction list isn't available. * Stop finding suggestion when the count is met. * Improve the MockPSConsole. * Cache the last two commands from the history. * Reduce the dependencies on Azure powershell common. (#13113) - That assembly and its dependencies causes a conflict if we load this module and Az.Accounts module. Though we can work around by sepcifying Az as a dependencies on this module, that'll cause long loading time. - The reason of loading that assembly is to get the setting about Azure PowerShell data collection. We can copy part of the code to load that file, so that we don't need that assembly as the dependency. * Add a missing file. (#13234) * Fix duplicate text (#13326) * Improve the debugging experience. - GetSuggestion gets cancelled during debugging because it times out. So we use an environment variable to control whether to allow cancellation from psreadline. - Use another macro to control if print message for telemetry. * Fix a bug that the command line is repeated in the suggestion. - When we parse the command line and there is an incomplete parameter list, we repeat the command line in the suggestion. - The cause is that we parse the command line and get the wrong parameter set from the user input * Update how we send request and collect telemetry (#13327) * Fix the query * Reduce the number of requests to the service. - We request the prediction for the command history. When the command history isn't changed, we don't need to request the prediction again. * Not to collect the parameter value in the telemetry. * Bug fixes and performance improvement (#13410) * Reduce extra cost to the perf issue. * Remove the aggregation on the parameter set. * Fix an issue * Fix some comments. * Improve the telemetry and http request (#13354) * Collect user id and mac address. - We hash the user account id and the mac address, and collect those in the telemetry. These are used to find how many users are using this mdoule. - We also send the hashed user account id in the http request header. This is used to enable throttling by user account. * Rename * Collect more data for diagnostic purpose. * Fix typo * Remove getting Az modules versions. * Update module infomation (#13328) * Set the description and dependencies for the module. * Update the project file and module manifest. * Update manifest and csproj * Fix typo * Move PSReadLine to ExternalModuleDependencies. - PSReadLine is in beta and there are issues in setting RequiredModules with a beta one. So move it as an ExternalModuleDependencies. * Update package script to support requiredmodule (#13424) * Add variety to Az.Predictor result list (#13420) * add variety to predictions list * add variety to predictions list * Update description for release * Add PublishLocation to build.proj of Az.Tools.Installer Co-authored-by: Jin Lei <[email protected]> Co-authored-by: Yabo Hu <[email protected]> Co-authored-by: msJinLei <[email protected]> Co-authored-by: msJinLei <[email protected]> Co-authored-by: kceiw <[email protected]> Co-authored-by: Beisi Zhou <[email protected]> Co-authored-by: Beisi Zhou <[email protected]> Co-authored-by: yemohyle <[email protected]>
1 parent 7a94d31 commit af7cf59

38 files changed

+3285
-4
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
pr: none
2+
trigger: none
3+
pool:
4+
vmImage: 'windows-2019'
5+
6+
steps:
7+
- task: PowerShell@2
8+
displayName: Install PS 7.1.0-preview.7
9+
inputs:
10+
targetType: 'inline'
11+
script: |
12+
$url = "https://github.com/PowerShell/PowerShell/releases/download/v7.1.0-preview.7/PowerShell-7.1.0-preview.7-win-x64.zip"
13+
$output = Join-Path -Path $(Pipeline.Workspace) -ChildPath "./PowerShell-7.1.0-preview.7-win-x64.zip"
14+
(New-Object System.Net.WebClient).DownloadFile($url, $output)
15+
$pwshPath= Join-Path -Path $(Pipeline.Workspace) -ChildPath "./PowerShell-7.1.0-preview.7/"
16+
Expand-Archive -Path $output -DestinationPath $pwshPath
17+
$pwshFullPath = Convert-Path $pwshPath
18+
Write-Host $pwshFullPath
19+
20+
- task: PowerShell@2
21+
displayName: 'Install platyPS, PowerShellGet, Az 3.0.0'
22+
inputs:
23+
targetType: inline
24+
script: |
25+
$pwshPath= Join-Path -Path $(Pipeline.Workspace) -ChildPath "./PowerShell-7.1.0-preview.7/pwsh.exe"
26+
$command = "`$PSVersionTable `
27+
Install-Module platyPS -Force -Confirm:`$false -Scope CurrentUser `
28+
Install-Module PowerShellGet -Force -Confirm:`$false -Scope CurrentUser -SkipPublisherCheck `
29+
Install-Module Az -Repository PSGallery -RequiredVersion 3.0.0 -Confirm:`$false -Scope CurrentUser -AllowClobber -Force"
30+
Invoke-Command -ScriptBlock { param ($pwshPath, $command) & $pwshPath -Command $command } -ArgumentList $pwshPath, $command
31+
32+
- task: UseDotNet@2
33+
displayName: 'Use .NET Core sdk'
34+
inputs:
35+
packageType: sdk
36+
version: 5.0.100-rc.1.20452.10
37+
38+
- task: DotNetCoreCLI@2
39+
displayName: 'Build'
40+
inputs:
41+
command: custom
42+
custom: msbuild
43+
arguments: 'tools\Az.Tools.Predictor\build.proj /target:"Clean;Build" /p:Configuration=Release'
44+
45+
- task: EsrpCodeSigning@1
46+
displayName: 'Signing'
47+
inputs:
48+
ConnectedServiceName: $(signServiceConnection)
49+
FolderPath: artifacts
50+
Pattern: |
51+
Tools/**/*.ps1
52+
Tools/**/*.psd1
53+
Tools/**/*.psm1
54+
Tools/**/*.ps1xml
55+
UseMinimatch: true
56+
signConfigType: inlineSignParams
57+
inlineOperation: |
58+
[
59+
{
60+
"KeyCode": "CP-230012",
61+
"OperationCode": "SigntoolSign",
62+
"Parameters": {
63+
"OpusName": "Microsoft",
64+
"OpusInfo": "http://www.microsoft.com",
65+
"FileDigest": "/fd \"SHA256\"",
66+
"PageHash": "/NPH",
67+
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
68+
},
69+
"ToolName": "sign",
70+
"ToolVersion": "1.0"
71+
},
72+
{
73+
"KeyCode": "CP-230012",
74+
"OperationCode": "SigntoolVerify",
75+
"Parameters": {},
76+
"ToolName": "sign",
77+
"ToolVersion": "1.0"
78+
}
79+
]
80+
81+
- task: DotNetCoreCLI@2
82+
displayName: Package
83+
inputs:
84+
command: custom
85+
custom: msbuild
86+
arguments: 'tools\Az.Tools.Predictor\build.proj /target:"Package" /p:Configuration=Release /p:PowerShellCoreCommandPrefix="$(Pipeline.Workspace)\\PowerShell-7.1.0-preview.7\\pwsh.exe -NonInteractive -NoLogo -NoProfile -Command" '
87+
88+
- task: PublishPipelineArtifact@0
89+
displayName: 'Save artifacts'
90+
inputs:
91+
artifactName: artifacts
92+
targetPath: artifacts
93+
condition: succeededOrFailed()

tools/Az.Tools.Installer/build.proj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@
2929

3030
<Target Name="Package">
3131
<Message Text="Package $(ModuleName)" />
32-
<Exec Command="$(PowerShellCoreCommandPrefix) &quot;$(RepoTools)\PublishToolsModule.ps1 -RepositoryLocation $(ArtifactFolder) -ModuleName $(ModuleName)&quot;" />
32+
<Exec Command="$(PowerShellCoreCommandPrefix) &quot;$(RepoTools)\PublishToolsModule.ps1 -RepositoryLocation $(ArtifactFolder) -PublishLocation $(ArtifactFolder) -ModuleName $(ModuleName)&quot;" />
3333
</Target>
34-
</Project>
34+
</Project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net5.0</TargetFramework>
5+
<AssemblyName>Microsoft.Azure.PowerShell.Tools.AzPredictor.Test</AssemblyName>
6+
<RootNamespace>Microsoft.Azure.PowerShell.Tools.AzPredictor.Test</RootNamespace>
7+
<IsPackable>false</IsPackable>
8+
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
9+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
10+
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
11+
<RepoArtifacts>$(MSBuildThisFileDirectory)</RepoArtifacts>
12+
<OutputPath>$(RepoArtifacts)..\..\..\artifacts\Tools\Az.Tools.Predictor.Test\</OutputPath>
13+
<DocumentationFile>$(OutputPath)\Microsoft.Azure.PowerShell.AzPredictor.Tools.Test.xml</DocumentationFile>
14+
</PropertyGroup>
15+
16+
<ItemGroup>
17+
<PackageReference Include="System.Management.Automation" Version="7.1.0-preview.7" />
18+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
19+
<PackageReference Include="xunit" Version="2.4.1" />
20+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
21+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
22+
<PrivateAssets>all</PrivateAssets>
23+
</PackageReference>
24+
<PackageReference Include="coverlet.collector" Version="1.3.0">
25+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
26+
<PrivateAssets>all</PrivateAssets>
27+
</PackageReference>
28+
<ProjectReference Include="..\Az.Tools.Predictor\Az.Tools.Predictor.csproj" />
29+
</ItemGroup>
30+
31+
<ItemGroup>
32+
<None Include="Data\CommandsModel.zip" CopyToOutputDirectory="PreserveNewest" />
33+
<None Include="Data\PredictionsModel.zip" CopyToOutputDirectory="PreserveNewest" />
34+
</ItemGroup>
35+
36+
</Project>
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.Azure.PowerShell.Tools.AzPredictor.Test.Mocks;
16+
using System.Linq;
17+
using System.Management.Automation.Subsystem;
18+
using System.Threading;
19+
using Xunit;
20+
21+
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Test
22+
{
23+
/// <summary>
24+
/// Tests for <see cref="AzPredictorService"/>
25+
/// </summary>
26+
[Collection("Model collection")]
27+
public class AzPredictorServiceTests
28+
{
29+
private readonly ModelFixture _fixture;
30+
private readonly AzPredictorService _service;
31+
private readonly Predictor _suggestionsPredictor;
32+
private readonly Predictor _commandsPredictor;
33+
34+
/// <summary>
35+
/// Constructs a new instance of <see cref="AzPredictorServiceTests"/>
36+
/// </summary>
37+
/// <param name="fixture"></param>
38+
public AzPredictorServiceTests(ModelFixture fixture)
39+
{
40+
this._fixture = fixture;
41+
var startHistory = $"{AzPredictorConstants.CommandPlaceholder}{AzPredictorConstants.CommandConcatenator}{AzPredictorConstants.CommandPlaceholder}";
42+
this._suggestionsPredictor = new Predictor(this._fixture.PredictionCollection[startHistory], null);
43+
this._commandsPredictor = new Predictor(this._fixture.CommandCollection, null);
44+
45+
this._service = new MockAzPredictorService(startHistory, this._fixture.PredictionCollection[startHistory], this._fixture.CommandCollection);
46+
}
47+
48+
49+
/// <summary>
50+
/// Verifies that the prediction comes from the suggestions list, not the command list.
51+
/// </summary>
52+
[Theory]
53+
[InlineData("CONNECT-AZACCOUNT")]
54+
[InlineData("set-azstorageaccount ")]
55+
[InlineData("Get-AzResourceG")]
56+
[InlineData("Get-AzStorageAcco")]
57+
[InlineData("Get-AzKeyVault -VaultName")]
58+
[InlineData("GET-AZSTORAGEACCOUNTKEY -NAME ")]
59+
[InlineData("new-azresourcegroup -name hello")]
60+
[InlineData("Get-AzContext -Name")]
61+
[InlineData("Get-AzContext -ErrorAction")]
62+
public void VerifyUsingSuggestion(string userInput)
63+
{
64+
var predictionContext = PredictionContext.Create(userInput);
65+
var expected = this._suggestionsPredictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
66+
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, CancellationToken.None);
67+
Assert.NotEmpty(actual);
68+
Assert.NotNull(actual.First().Item1);
69+
Assert.Equal(expected.First().Key, actual.First().Item1);
70+
Assert.Equal(PredictionSource.CurrentCommand, actual.First().Item3);
71+
}
72+
73+
/// <summary>
74+
/// Verifies that when no prediction is in the suggestion list, we'll use the command list.
75+
/// </summary>
76+
[Theory]
77+
[InlineData("Get-AzResource -Name hello -Pre")]
78+
[InlineData("Get-AzADServicePrincipal -ApplicationObject")]
79+
public void VerifyUsingCommand(string userInput)
80+
{
81+
var predictionContext = PredictionContext.Create(userInput);
82+
var expected = this._commandsPredictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
83+
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, CancellationToken.None);
84+
Assert.NotEmpty(actual);
85+
Assert.NotNull(actual.First().Item1);
86+
Assert.Equal(expected.First().Key, actual.First().Item1);
87+
Assert.Equal(PredictionSource.StaticCommands, actual.First().Item3);
88+
}
89+
90+
/// <summary>
91+
/// Verify that no prediction for the user input, meaning it's not in the prediction list or the command list.
92+
/// </summary>
93+
[Theory]
94+
[InlineData(AzPredictorConstants.CommandPlaceholder)]
95+
[InlineData("git status")]
96+
[InlineData("Get-ChildItem")]
97+
[InlineData("new-azresourcegroup -NoExistingParam")]
98+
[InlineData("get-azaccount ")]
99+
[InlineData("Get-AzContext Name")]
100+
[InlineData("NEW-AZCONTEXT")]
101+
public void VerifyNoPrediction(string userInput)
102+
{
103+
var predictionContext = PredictionContext.Create(userInput);
104+
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, CancellationToken.None);
105+
Assert.Empty(actual);
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)