Skip to content

Commit

Permalink
Management SDK project template and build infrastructure update (Azur…
Browse files Browse the repository at this point in the history
…e#11677)

* 1. Added management SDK client project template, 2. Adjusted Build.Data to support new management SDK projects

* 1. Addressed comments: moved warning to data.prop, updated initial version, remove extra line
2. added empty tags if none specified
3. added flag to copy ci.yml and test-resource.json into parent folder

* Added link to the dotnet template in CONTRIBUTING.md

* Update minimal test-resource ARM template file
  • Loading branch information
allenjzhang authored May 1, 2020
1 parent 04ade0a commit b475df6
Show file tree
Hide file tree
Showing 18 changed files with 469 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ Now you can use the same command on non-windows as above for e.g. on Ubuntu you
Build tools are now downloaded as part of a nuget package under `root\restoredPackages\microsoft.internal.netsdkbuild.mgmt.tools`
If for any reason there is an update to the build tools, you will then need to first delete directory `root\restoredPackages\microsoft.internal.netsdkbuild.mgmt.tools` and re-execute your build command. This will simply get the latest version of build tools.

## TO CREATE NEW LIBRARY USING TEMPLATE

We have created a dotnet template to make creating new management SDK library easier than ever.

See (README file)[(https://github.com/Azure/azure-sdk-for-net/blob/master/eng/templates/README.md)].

# Client Libraries

## TO BUILD:
Expand Down
16 changes: 16 additions & 0 deletions eng/Directory.Build.Data.props
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
</PropertyGroup>

<PropertyGroup>
<IsMgmtClientLibrary Condition="'$(IsMgmtClientLibrary)' == '' and $(MSBuildProjectName.StartsWith('Azure.Management.'))">true</IsMgmtClientLibrary>
<IsTestProject Condition="$(MSBuildProjectName.EndsWith('.Tests'))">true</IsTestProject>
<IsSamplesProject Condition="$(MSBuildProjectName.EndsWith('.Samples'))">true</IsSamplesProject>
<IsTestSupportProject Condition="'$(IsTestProject)' != 'true' and ($(MSBuildProjectDirectory.Contains('/tests/')) or $(MSBuildProjectDirectory.Contains('\tests\')))">true</IsTestSupportProject>
Expand All @@ -48,6 +49,15 @@
<EnableApiCompat Condition="'$(EnableApiCompat)' == '' and '$(IsShippingClientLibrary)' == 'true'">true</EnableApiCompat>
</PropertyGroup>

<!-- TODO. REVIEW -->
<PropertyGroup Condition="'$(IsMgmtClientLibrary)' == 'true'">
<NoWarn>
($NoWarn);
CA1812; <!-- Avoid uninstantiated internal classes. (Result from below including the Azure.Core source) -->
AZC0012; <!-- Single word class names -->
</NoWarn>
</PropertyGroup>

<!-- CodeAnalysis RuleSet -->
<PropertyGroup Condition="'$(IsClientLibrary)' == 'true'">
<CodeAnalysisRuleSet>$(RepoEngPath)\CodeAnalysis.ruleset</CodeAnalysisRuleSet>
Expand Down Expand Up @@ -133,4 +143,10 @@
<!-- Disable doc comments for test projects -->
<DocumentationFile></DocumentationFile>
</PropertyGroup>

<!-- Management Client Library Specific Overrides -->
<PropertyGroup Condition="'$(IsMgmtClientLibrary)' == 'true'">
<EnableApiCompat>false</EnableApiCompat>
</PropertyGroup>

</Project>
30 changes: 29 additions & 1 deletion eng/Directory.Build.Data.targets
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
</ItemGroup>

<!-- Add Package Icon to DataPlane Packages -->
<ItemGroup>
<ItemGroup Condition="'$(IsTestProject)' != 'true'">
<None Include="$(RepoEngPath)/images/pkgicon.png" Pack="true" PackagePath=""/>
<None Condition="Exists('$(MSBuildProjectDirectory)/../CHANGELOG.md')" Include="$(MSBuildProjectDirectory)/../CHANGELOG.md" Pack="true" PackagePath=""/>
<None Condition="Exists('$(MSBuildProjectDirectory)/../README.md')" Include="$(MSBuildProjectDirectory)/../README.md" Pack="true" PackagePath=""/>
Expand Down Expand Up @@ -134,6 +134,34 @@
<ProjectReference Include="@(ProjectsToConvert -> '%(ProjectPath)')" />
</ItemGroup>

<!-- *********** Management Client Library Override section ************* -->
<Import Project="$(RepoRoot)\sdk\core\Azure.Core\src\Azure.Core.props" Condition="'$(IsMgmtClientLibrary)' == 'true' and '$(IsTestProject)' != 'true'"/>
<ItemGroup Condition="'$(IsMgmtClientLibrary)' == 'true' and '$(IsTestProject)' != 'true'">
<PackageReference Include="System.Text.Json" />

<!-- TODO: Review these file references-->
<Compile Include="$(AzureCoreSharedSources)ArrayBufferWriter.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)ClientDiagnostics.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)ContentTypeUtilities.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)DiagnosticScope.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)DiagnosticScopeFactory.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)HttpMessageSanitizer.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)TaskExtensions.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)OperationHelpers.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)AzureResourceProviderNamespaceAttribute.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
</ItemGroup>

<!-- Management Client TEST Project Specific Overrides -->
<Import Project="$(RepoRoot)\sdk\core\Azure.Core\tests\TestFramework.props" Condition="'$(IsMgmtClientLibrary)' == 'true' and '$(IsTestProject)' == 'true'"/>
<ItemGroup Condition="'$(IsMgmtClientLibrary)' == 'true' and '$(IsTestProject)' == 'true'">
<PackageReference Include="Azure.Identity" />
<PackageReference Include="nunit" />
<PackageReference Include="NUnit3TestAdapter" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Moq" />
</ItemGroup>
<!-- *********** END OF Management Client Library Override section ************* -->

<!-- Added layer of checks to make sure we correctly switched to project references -->
<Target Name="VerifyProjectReferencesReferences" AfterTargets="Build">
<ItemGroup>
Expand Down
122 changes: 122 additions & 0 deletions eng/templates/Azure.Management.Template/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "azhang@microsoft.com",
"classifications": [ "ClassLibrary" ],
"identity": "Azure.Management.TemplateProject",
"name": "Azure Management SDK template: client project",
"shortName": "azuremgmt",
"tags": {
"language": "C#",
"type": "project"
},
"sourceName": "Azure.Management.Template",
"preferNameDirectory": true,
"guids": [
"FAE04EC0-301F-11D3-BF4B-00C04F79EFBC",
"F58E71A4-DED3-4714-B107-4E0E899BECEF",
"3E25C0E3-A852-4DCB-B406-66E5565551DC"
],
"sources": [
{
"source": "./",
"target": "./",
"modifiers": [
{
"exclude": [
"content/**/*"
]
}
]
},
{
"source": "./content",
"target": "../",
"condition": "(includeCI)"
}
],
"symbols": {
"provider": {
"type": "parameter",
"datatype":"text",
"isRequired": true,
"description": "The Azure provider name. ie. Microsoft.Network or Microsoft.Compute",
"replaces": "ProviderFullName"
},
"tagVersion": {
"type": "parameter",
"datatype":"text",
"isRequired": false,
"description": "The optional parameter specifies the tag in the README.MD. If empty, the default tag in the README.MD is used.",
"defaultValue": "",
"replaces": "SwaggerVersionTag"
},
"includeCI": {
"type": "parameter",
"datatype": "bool",
"isRequired": false,
"description": "The optional parameter specifies whether generate related pipline ci.yml and test-resources.json in parent folder.",
"defaultValue": "false"
},
"ProviderShortNameLowercase": {
"type": "derived",
"datatype": "text",
"valueSource": "provider",
"valueTransform": "ProviderShortNameLowerForm",
"replaces": "ProviderNameLowercase"
},
"ProviderShortName": {
"type": "derived",
"datatype": "text",
"valueSource": "provider",
"valueTransform": "ProviderShortNameForm",
"replaces": "ProviderShortName",
"fileRename": "ProviderShortName"
},
"TemplateSafeName": {
"type": "generated",
"generator": "regex",
"datatype": "text",
"replaces": "AzureManagementTemplateSafeName",
"parameters": {
"action": "replace",
"source": "name",
"steps": [
{ "regex": "\\.", "replacement": "" }
]
}
},
"tagPrefix": {
"type": "generated",
"generator": "switch",
"replaces": "tagPrefix",
"parameters": {
"evaluator": "MSBUILD",
"datatype": "string",
"cases": [
{
"condition": "('tagVersion' == '')",
"value": ""
},
{
"condition": "('tagVersion' != '')",
"value": "tag:"
}
]
}
}
},
"forms": {
"ProviderShortNameForm": {
"identifier": "replace",
"pattern": "^[mM]icrosoft\\.",
"replacement": ""
},
"ProviderShortNameLowerForm": {
"identifier": "chain",
"steps": [
"ProviderShortNameForm",
"lowerCase"
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Management.Template", "src\Azure.Management.Template.csproj", "{F58E71A4-DED3-4714-B107-4E0E899BECEF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Management.Template.Tests", "tests\Azure.Management.Template.Tests.csproj", "{3E25C0E3-A852-4DCB-B406-66E5565551DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Debug|x64.ActiveCfg = Debug|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Debug|x64.Build.0 = Debug|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Debug|x86.ActiveCfg = Debug|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Debug|x86.Build.0 = Debug|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Release|Any CPU.Build.0 = Release|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Release|x64.ActiveCfg = Release|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Release|x64.Build.0 = Release|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Release|x86.ActiveCfg = Release|Any CPU
{F58E71A4-DED3-4714-B107-4E0E899BECEF}.Release|x86.Build.0 = Release|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Debug|x64.ActiveCfg = Debug|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Debug|x64.Build.0 = Debug|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Debug|x86.ActiveCfg = Debug|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Debug|x86.Build.0 = Debug|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Release|Any CPU.Build.0 = Release|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Release|x64.ActiveCfg = Release|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Release|x64.Build.0 = Release|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Release|x86.ActiveCfg = Release|Any CPU
{3E25C0E3-A852-4DCB-B406-66E5565551DC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
3 changes: 3 additions & 0 deletions eng/templates/Azure.Management.Template/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Release History

- Started changelog to capture release notes.
6 changes: 6 additions & 0 deletions eng/templates/Azure.Management.Template/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
Add any shared properties you want for the projects under this package directory that need to be set before the auto imported Directory.Build.props
-->
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory).., Directory.Build.props))\Directory.Build.props" />
</Project>
100 changes: 100 additions & 0 deletions eng/templates/Azure.Management.Template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# README.md template

Use the guidelines in each section of this template to ensure consistency and readability of your README. The README resides in your package's GitHub repository at the root of its directory within the repo. It's also used as the package distribution page (NuGet, PyPi, npm, etc.) and as a Quickstart on docs.microsoft.com. See [README-EXAMPLE.md](README-EXAMPLE.md) for an example following this template.

* All headings, including the H1, should use **sentence-style capitalization**. Refer to the [Microsoft Style Guide][style-guide-msft] and [Microsoft Cloud Style Guide][style-guide-cloud] for more information.
* Example: `# Azure Batch client library for Python`

# Azure Management ProviderShortName client library for .NET

**Introduction**: The introduction appears directly under the title (H1) of your README.

* **DO NOT** use an "Introduction" or "Overview" heading (H2) for this section.
* First sentence: **Describe the service** briefly. You can usually use the first line of the service's docs landing page for this (Example: [Cosmos DB docs landing page](https://docs.microsoft.com/azure/cosmos-db/)).
* Next, add a **bulleted list** of the **most common tasks** supported by the package or library, prefaced with "Use the client library for [Product Name] to:". Then, provide code snippets for these tasks in the [Examples](#examples) section later in the document. Keep the task list short but include those tasks most developers need to perform with your package.
* Include this single line of links targeting your product's content at the bottom of the introduction, making any adjustments as necessary (for example, NuGet instead of PyPi):

[Source code](https://github.com/Azure/azure-sdk-for-python/tree/master/azure-batch) | [Package (PyPi)](https://pypi.org/project/azure-batch/) | [API reference documentation](https://docs.microsoft.com/python/api/overview/azure/batch?view=azure-python) | [Product documentation](https://docs.microsoft.com/azure/batch/)

> TIP: Your README should be as **brief** as possible but **no more brief** than necessary to get a developer new to Azure, the service, or the package up and running quickly. Keep it brief, but include everything a developer needs to make their first API call successfully.
## Getting started

This section should include everything a developer needs to do to install and create their first client connection *very quickly*.

### Install the package

First, provide instruction for obtaining and installing the package or library. This section might include only a single line of code, like `pip install package-name`, but should enable a developer to successfully install the package from NuGet, pip, npm, Maven, or even cloning a GitHub repository.

Include a **Prerequisites** line after the install command that details any requirements that must be satisfied before a developer can [authenticate](#authenticate-the-client) and test all of the snippets in the [Examples](#examples) section. For example, for Cosmos DB:

**Prerequisites**: You must have an [Azure subscription](https://azure.microsoft.com/free/), [Cosmos DB account](https://docs.microsoft.com/azure/cosmos-db/account-overview) (SQL API), and [Python 3.6+](https://www.python.org/downloads/) to use this package.

### Authenticate the client

If your library requires authentication for use, such as for Azure services, include instructions and example code needed for initializing and authenticating.

For example, include details on obtaining an account key and endpoint URI, setting environment variables for each, and initializing the client object.

## Key concepts

The *Key concepts* section should describe the functionality of the main classes. Point out the most important and useful classes in the package (with links to their reference pages) and explain how those classes work together. Feel free to use bulleted lists, tables, code blocks, or even diagrams for clarity.

## Examples

Include code snippets and short descriptions for each task you listed in the [Introduction](#introduction) (the bulleted list). Briefly explain each operation, but include enough clarity to explain complex or otherwise tricky operations.

If possible, use the same example snippets that your in-code documentation uses. For example, use the snippets in your `examples.py` that Sphinx ingests via its [literalinclude](https://www.sphinx-doc.org/en/1.5/markup/code.html?highlight=code%20examples#includes) directive. The `examples.py` file containing the snippets should reside alongside your package's code, and should be tested in an automated fashion.

Each example in the *Examples* section starts with an H3 that describes the example. At the top of this section, just under the *Examples* H2, add a bulleted list linking to each example H3. Each example should deep-link to the types and/or members used in the example.

* [Create the thing](#create-the-thing)
* [Get the thing](#get-the-thing)
* [List the things](#list-the-things)

### Create the thing

Use the [create_thing](not-valid-link) method to create a Thing reference; this method does not make a network call. To persist the Thing in the service, call [Thing.save](not-valid-link).

```Python
thing = client.create_thing(id, name)
thing.save()
```

### Get the thing

The [get_thing](not-valid-link) method retrieves a Thing from the service. The `id` parameter is the unique ID of the Thing, not its "name" property.

```C# Snippet:GetSecret
var client = new MiniSecretClient(new Uri(endpoint), new DefaultAzureCredential());

SecretBundle secret = client.GetSecret("TestSecret");

Console.WriteLine(secret.Value);
```Python
things = client.list_things()
```

## Troubleshooting

Describe common errors and exceptions, how to "unpack" them if necessary, and include guidance for graceful handling and recovery.

Provide information to help developers avoid throttling or other service-enforced errors they might encounter. For example, provide guidance and examples for using retry or connection policies in the API.

If the package or a related package supports it, include tips for logging or enabling instrumentation to help them debug their code.

## Next steps

* Provide a link to additional code examples, ideally to those sitting alongside the README in the package's `/samples` directory.
* If appropriate, point users to other packages that might be useful.
* If you think there's a good chance that developers might stumble across your package in error (because they're searching for specific functionality and mistakenly think the package provides that functionality), point them to the packages they might be looking for.

## Contributing

This is a template, but your SDK readme should include details on how to contribute code to the repo/package.

<!-- LINKS -->
[style-guide-msft]: https://docs.microsoft.com/style-guide/capitalization
[style-guide-cloud]: https://worldready.cloudapp.net/Styleguide/Read?id=2696&topicid=25357

![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-net%2Fsdk%2Ftemplate%2FAzure.Template%2FREADME.png)
Loading

0 comments on commit b475df6

Please sign in to comment.