Skip to content

Commit

Permalink
Merge pull request #1 from microsoft/preview-release
Browse files Browse the repository at this point in the history
Preview release
  • Loading branch information
darrelmiller authored May 30, 2023
2 parents 877c70f + 9ef50fc commit 1ad6a67
Show file tree
Hide file tree
Showing 12 changed files with 765 additions and 33 deletions.
274 changes: 274 additions & 0 deletions .azure-pipelines/ci-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)

trigger:
branches:
include:
- main
pr:
branches:
include:
- main

pool:
name: Azure Pipelines
vmImage: windows-latest

variables:
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
ProductBinPath: '$(Build.SourcesDirectory)\src\lib\bin\$(BuildConfiguration)'


stages:

- stage: build
jobs:
- job: build
steps:

- task: UseDotNet@2
displayName: 'Use .NET 7'
inputs:
version: 7.x

- task: UseDotNet@2
displayName: 'Use .NET 6 (for code signing tasks)'
inputs:
packageType: sdk
version: 6.x

- task: PoliCheck@2
displayName: 'Run PoliCheck "/src"'
inputs:
inputType: CmdLine
cmdLineArgs: '/F:$(Build.SourcesDirectory)/src /T:9 /Sev:"1|2" /PE:2 /O:poli_result_src.xml'

- task: PoliCheck@2
displayName: 'Run PoliCheck "/src/tests"'
inputs:
inputType: CmdLine
cmdLineArgs: '/F:$(Build.SourcesDirectory)/src/tests /T:9 /Sev:"1|2" /PE:2 /O:poli_result_test.xml'

# Install the nuget tool.
- task: NuGetToolInstaller@1
displayName: 'Install Nuget dependency manager'
inputs:
versionSpec: '>=5.2.0'
checkLatest: true

# Build the Product project
- task: DotNetCoreCLI@2
displayName: 'Build APIManifest'
inputs:
projects: '$(Build.SourcesDirectory)\apimanifest.sln'
arguments: '--configuration $(BuildConfiguration) --no-incremental'

# Run the Unit test
- task: DotNetCoreCLI@2
displayName: 'Test Microsoft.OpenApi.ApiManifest'
inputs:
command: test
projects: '$(Build.SourcesDirectory)\apimanifest.sln'
arguments: '--configuration $(BuildConfiguration) --no-build -f net7.0'

# CredScan
- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
displayName: 'Run CredScan - Src'
inputs:
toolMajorVersion: 'V2'
scanFolder: '$(Build.SourcesDirectory)\src'
debugMode: false

- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
displayName: 'Run CredScan - Test'
inputs:
toolMajorVersion: 'V2'
scanFolder: '$(Build.SourcesDirectory)\src\tests'
debugMode: false

- task: AntiMalware@3
displayName: 'Run MpCmdRun.exe - ProductBinPath'
inputs:
FileDirPath: '$(ProductBinPath)'
enabled: false

- task: BinSkim@4
displayName: 'Run BinSkim - Product Binaries'
inputs:
InputType: Basic
AnalyzeTargetGlob: '$(ProductBinPath)\**\Microsoft.OpenApi.ApiManifest.dll'
AnalyzeSymPath: '$(ProductBinPath)'
AnalyzeVerbose: true
AnalyzeHashes: true
AnalyzeEnvironment: true

- task: PublishSecurityAnalysisLogs@3
displayName: 'Publish Security Analysis Logs'
inputs:
ArtifactName: SecurityLogs

- task: PostAnalysis@2
displayName: 'Post Analysis'
inputs:
BinSkim: true
CredScan: true
PoliCheck: true

- task: EsrpCodeSigning@2
displayName: 'ESRP DLL CodeSigning'
inputs:
ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
FolderPath: src
Pattern: '**\*Microsoft.OpenApi.ApiManifest.dll'
UseMinimatch: true
signConfigType: inlineSignParams
inlineOperation: |
[
{
"keyCode": "CP-230012",
"operationSetCode": "SigntoolSign",
"parameters": [
{
"parameterName": "OpusName",
"parameterValue": "Microsoft"
},
{
"parameterName": "OpusInfo",
"parameterValue": "http://www.microsoft.com"
},
{
"parameterName": "FileDigest",
"parameterValue": "/fd \"SHA256\""
},
{
"parameterName": "PageHash",
"parameterValue": "/NPH"
},
{
"parameterName": "TimeStamp",
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
}
],
"toolName": "sign",
"toolVersion": "1.0"
},
{
"keyCode": "CP-230012",
"operationSetCode": "SigntoolVerify",
"parameters": [ ],
"toolName": "sign",
"toolVersion": "1.0"
}
]
SessionTimeout: 20

# arguments are not parsed in DotNetCoreCLI@2 task for `pack` command, that's why we have a custom pack command here
- pwsh: dotnet pack $env:BUILD_SOURCESDIRECTORY/src/lib/apimanifest.csproj /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg --no-build --output $env:BUILD_ARTIFACTSTAGINGDIRECTORY --configuration $env:BUILD_CONFIGURATION
env:
BUILD_CONFIGURATION: $(BuildConfiguration)
displayName: Dotnet pack

- task: PowerShell@2
displayName: 'Validate project version has been incremented'
condition: and(contains(variables['build.sourceBranch'], 'refs/heads/main'), succeeded())
inputs:
targetType: 'filePath'
filePath: $(System.DefaultWorkingDirectory)\scripts\ValidateProjectVersionUpdated.ps1
arguments: '-projectPath "$(Build.SourcesDirectory)/src/lib/apimanifest.csproj" -packageName "Microsoft.OpenApi.ApiManifest"'
pwsh: true

- task: EsrpCodeSigning@2
displayName: 'ESRP CodeSigning Nuget Packages'
inputs:
ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
FolderPath: '$(Build.ArtifactStagingDirectory)'
UseMinimatch: true
Pattern: '*.nupkg'
signConfigType: inlineSignParams
inlineOperation: |
[
{
"keyCode": "CP-401405",
"operationSetCode": "NuGetSign",
"parameters": [ ],
"toolName": "sign",
"toolVersion": "1.0"
},
{
"keyCode": "CP-401405",
"operationSetCode": "NuGetVerify",
"parameters": [ ],
"toolName": "sign",
"toolVersion": "1.0"
}
]
SessionTimeout: 20

- task: CopyFiles@2
displayName: 'Copy release scripts to artifact staging directory'
condition: and(contains(variables['build.sourceBranch'], 'refs/heads/main'), succeeded())
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: 'scripts\**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'

- task: PublishPipelineArtifact@1
displayName: 'Upload Artifact: Nugets'
inputs:
artifactName: Nugets
targetPath: $(Build.ArtifactStagingDirectory)

- stage: deploy
condition: and(contains(variables['build.sourceBranch'], 'refs/heads/main'), succeeded())
dependsOn: build
jobs:
- deployment: deploy_openapi_apimanifest
dependsOn: []
environment: nuget-org
strategy:
runOnce:
deploy:
pool:
vmImage: ubuntu-latest
steps:
# Install the nuget tool.
- task: NuGetToolInstaller@0
displayName: 'Use NuGet >=5.2.0'
inputs:
versionSpec: '>=5.2.0'
checkLatest: true
- task: DownloadPipelineArtifact@2
displayName: Download nupkg from artifacts
inputs:
artifact: Nugets
source: current
- task: PowerShell@2
displayName: 'Extract release information to pipeline'
inputs:
targetType: 'filePath'
filePath: $(Pipeline.Workspace)\Nugets\scripts\GetNugetPackageVersion.ps1
pwsh: true
arguments: '-packageDirPath "$(Pipeline.Workspace)/Nugets/"'
- task: NuGetCommand@2
displayName: 'NuGet push'
inputs:
command: push
packagesToPush: '$(Pipeline.Workspace)/Nugets/Microsoft.OpenApi.ApiManifest.nupkg'
nuGetFeedType: external
publishFeedCredentials: 'Kiota Nuget Connection'
- task: GitHubRelease@1
displayName: 'GitHub release (create)'
inputs:
gitHubConnection: 'Kiota_Release'
target: $(Build.SourceVersion)
tagSource: userSpecifiedTag
tag: 'v$(VERSION_STRING)'
title: '$(VERSION_STRING)'
releaseNotesSource: inline
assets: '!**/**'
changeLogType: issueBased
isPreRelease : '$(IS_PRE_RELEASE)'
addChangeLog : true
55 changes: 29 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,35 @@ An "api manifest" is a way to store the dependencies that an application has on
You can create an API manifest in code:

```csharp
var apiManifest = new ApiManifestDocument();
apiManifest.Publisher = new Publisher();
apiManifest.Publisher.Name = "Microsoft";
apiManifest.Publisher.ContactEmail = "example@example.org";
apiManifest.ApiDependencies.Add(new ApiDependency()
{
ApiDescripionUrl = "https://example.org",
Auth = new Auth()
{
ClientId = "1234",
Permissions = new() {
{"application", new() {"read"}},
{"delegated", new() {"read", "write"}}
}
},
Requests = new List<Request>() {
new() {
Method = "GET",
UriTemplate = "/api/v1/endpoint"
},
new () {
Method = "POST",
UriTemplate = "/api/v1/endpoint"
}
}
});
var apiManifest = new ApiManifestDocument() {
Publisher = new() {
Name = "Microsoft",
ContactEmail = "example@example.org"
},
ApiDependencies = new() {
{ "example", new()
{
ApiDescripionUrl = "https://example.org",
Auth = new()
{
ClientIdentifier = "1234",
Access = new() {
new () { Type= "application", Content = new JsonObject() {
{ "scopes", new JsonArray() {"User.Read.All"} }}
} ,
new () { Type= "delegated", Content = new JsonObject() {
{ "scopes", new JsonArray() {"User.Read", "Mail.Read"} }}
}
}
},
Requests = new() {
new() { Method = "GET", UriTemplate = "/api/v1/endpoint" },
new () { Method = "POST", UriTemplate = "/api/v1/endpoint"}
}
}
}
}
};
```

or you can read it from a stream
Expand Down
17 changes: 13 additions & 4 deletions src/lib/ApiDependency.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,29 @@ namespace Microsoft.OpenApi.ApiManifest;
public class ApiDependency
{
public string? ApiDescripionUrl { get; set; }
public string? BaseUrl { get; set; }
public string? ApiDescripionVersion { get; set; }
public Auth? Auth { get; set; }
public List<Request> Requests { get; set; } = new List<Request>();
public Extensions? Extensions { get; set; }

private const string ApiDescriptionUrlProperty = "apiDescripionUrl";
private const string ApiDescriptionVersionProperty = "apiDescripionVersion";
private const string AuthProperty = "auth";
private const string RequestsProperty = "requests";
private const string BaseUrlProperty = "baseUrl";
private const string ExtensionsProperty = "extensions";

// Write method
public void Write(Utf8JsonWriter writer)
{
writer.WriteStartObject();

if (!String.IsNullOrWhiteSpace(ApiDescripionUrl)) writer.WriteString(ApiDescriptionUrlProperty, ApiDescripionUrl);
if (!String.IsNullOrWhiteSpace(ApiDescripionVersion)) writer.WriteString(ApiDescriptionVersionProperty, ApiDescripionVersion);

if (Auth != null) {
writer.WritePropertyName(AuthProperty);
Auth?.Write(writer);
}
if (!String.IsNullOrWhiteSpace(BaseUrl)) writer.WriteString(BaseUrlProperty, BaseUrl);

if (Requests.Count > 0) {
writer.WritePropertyName(RequestsProperty);
Expand All @@ -35,15 +38,21 @@ public void Write(Utf8JsonWriter writer)
writer.WriteEndArray();
}

if (Extensions != null) {
writer.WritePropertyName(ExtensionsProperty);
Extensions?.Write(writer);
}

writer.WriteEndObject();
}
// Fixed fieldmap for ApiDependency
private static FixedFieldMap<ApiDependency> handlers = new()
{
{ ApiDescriptionUrlProperty, (o,v) => {o.ApiDescripionUrl = v.GetString(); } },
{ ApiDescriptionVersionProperty, (o,v) => {o.ApiDescripionVersion = v.GetString(); } },
{ AuthProperty, (o,v) => {o.Auth = Auth.Load(v); } },
{ RequestsProperty, (o,v) => {o.Requests = ParsingHelpers.GetList(v, Request.Load); } },
{ BaseUrlProperty, (o,v) => {o.BaseUrl = v.GetString(); } },
{ ExtensionsProperty, (o,v) => {o.Extensions = Extensions.Load(v); } }
};

// Load Method
Expand Down
Loading

0 comments on commit 1ad6a67

Please sign in to comment.