This is the specification of the new SDK Automation customization configuration. Old customization that hardcoded in sdk automation will still work but this new approach is preferred.
SDK Automation is launched with matrix in azure pipeline. For each language configured:
-
Get the PR merge commit and clone the spec repo on the merge commit.
-
Get the PR changed file list. For each changed file, find the nearest readme.md in parent folder. Get list of related readme.md.
-
Filter the list of readme.md with: find the
swagger-to-sdk
section in the readme.md, and see if the specified language is configured for that readme.md. Example ofswagger-to-sdk
in SDK Automation:
```yaml $(swagger-to-sdk)
swagger-to-sdk:
- repo: azure-sdk-for-python
- repo: azure-sdk-for-java
- repo: azure-sdk-for-go
- repo: azure-sdk-for-js
``` <EOL>
If the configured language is not found here, generation for this readme.md will be skipped.
-
Get
specificationRepositoryConfiguration.json
from spec repo default branch. See SpecRepoConfig. Get the repo and branch config in the file. -
Clone mainRepository and checkout mainBranch. If secondaryRepository is specified then checkout secondaryRepository and secondaryBranch instead.
-
Get
swagger_to_sdk_config.json
from cloned SDK repository. The config file path could be customized by configFilePath in spec config. For the definition of the config see SwaggerToSdkConfig. -
Launch initScript defined in SwaggerToSdkConfig. All the script's working directory is root folder of cloned SDK repository.
-
Calculate PR diff and related
readme.md
. If generationCallMode is one-for-all-configs then run one pass for the rest steps, else (one-per-config) loop the rest steps with eachreadme.md
. -
Launch generateScript defined in SwaggerToSdkConfig with generateInput.json. The script should produce generateOutput.json if parseGenerateOutput is true. If dryRun is set to true then first run of generateScript will be used to collect package information , then loop each package info and checkout package related branch and launch generateScript with package related readmeMd and dryRun set to false.
-
Get generated package. If packageFolderFromFileSearch is defined with file search then package folder is detected based on git diff in SDK repository and algorithm described in SwaggerToSdkConfig Schema. Else package folder is from generateOutput.json. For each package loop the rest steps.
-
Launch buildScript to build the package. Collect the artifacts by config artifactPathFromFileSearch. This step could be skipped if it's not defined in SwaggerToSdkConfig and it's covered by generateScript and the result could be found in generateOutput.json.
-
Upload all the package related artifacts to Azure Storage Blob Container. All the artifact for one package is uploaded in one folder. These file could be downloaded on URL prefixed by downloadUrlPrefix defined in InstallInstructionScriptInput. It's redirected by openapiHub by design, and for SDK Automation on public repo the redirect don't need auth, but for SDK Automation in private repo it requires microsoft AAD auth. User could authenticate and download via web page oauth in browser or bearer token auth with
az rest --resource
in command line. -
Launch changelogScript to get changelog and detect breaking change. This step could be skipped if changelog and breaking change could be found in generateOutput.json. If breaking change is found, the spec PR will be labelled with
CI-BreakingChange-<Lang>
. -
Launch installInstructionScript to get install instruction for that package. This step could be skipped if install instruction could be found in generateOutput.json. The lite install instruction will be shown in spec PR comment, the full install instruction will be shown in generated SDK PR.
-
Commit the package related code in SDK repository. Force push to GenerationBranch in integrationRepository. Create or update GenerationPR from GenerationBranch to MainBranch in integrationRepository. If integrationRepository is a fork of mainRepository, its MainBranch should be synced once a day.
Almost the same as opened PR trigger, with different on step 15:
- Commit the package related code in SDK repository. Close GenerationPR and delete GenerationBranch. Force push to IntegrationBranch in integrationRepository. Create or update IntegrationPR from IntegrationBranch to MainBranch in mainRepository. Close the integrationPR if closeIntegrationPR in SwaggerToSdkConfig is set to true.
This is type of file ./specificationRepositoryConfiguration.json
in swagger spec repo.
{
"sdkRepositoryMappings": {
"azure-sdk-for-js": {
"integrationRepository": "AzureSDKAutomation/azure-sdk-for-js",
"mainRepository": "Azure/azure-sdk-for-js"
},
"azure-sdk-for-python": {
"integrationRepository": "AzureSDKAutomation/azure-sdk-for-python",
"mainRepository": "Azure/azure-sdk-for-python",
"mainBranch": "release/v3"
},
"azure-sdk-for-python-track2": {
"integrationRepository": "AzureSDKAutomation/azure-sdk-for-python",
"mainRepository": "Azure/azure-sdk-for-python"
},
"azure-sdk-for-trenton": {
"integrationRepository": "Azure/azure-sdk-for-trenton",
"mainRepository": "Azure/azure-sdk-for-trenton",
"secondaryRepository": "Azure/azure-sdk-for-trenton",
"secondaryBranch": "secondary"
}
},
"overrides": {
"Azure/azure-rest-api-specs-pr": {
"sdkRepositoryMappings": {
"azure-sdk-for-js": {
"integrationRepository": "azure-sdk/azure-sdk-for-js-pr",
"mainRepository": "Azure/azure-sdk-for-js-pr"
},
"azure-sdk-for-python": {
"integrationRepository": "azure-sdk/azure-sdk-for-python-pr",
"mainRepository": "Azure/azure-sdk-for-python-pr",
"mainBranch": "release/v3"
},
"azure-sdk-for-python-track2": {
"integrationRepository": "azure-sdk/azure-sdk-for-python-pr",
"mainRepository": "Azure/azure-sdk-for-python-pr"
}
}
}
}
}
This is type of file ./swagger_to_sdk_config.json
in sdk repo.
The running environment of these scripts would be expected to be Ubuntu 18.04 on Azure Pipeline. This may change in the future. All the running script should be executable.
The working folder of all the scripts is the root folder of sdk repo.
See ./SwaggerToSdkConfigSchema.json
Input file for generate script.
{
"dryRun": false,
"specFolder": "/z/work/azure-rest-api-specs",
"headSha": "fce3400431eff281bddd04bed9727e63765b8da0",
"headRef": "refs/pull/1234/merge",
"repoHttpsUrl": "https://github.com/Azure/azure-rest-api-specs.git",
"trigger": "pull_request",
"changedFiles": [
"specification/cdn/something/cdn.json"
],
"relatedReadmeMdFiles": [
"specification/cdn/something/readme.md"
],
"installInstructionInput": {
"isPublic": false,
"downloadUrlPrefix": "https://openapihub.test.azure-devex-tools.com/api/sdk-dl-pub?p=Azure/1234/azure-sdk-for-net/",
"downloadCommandTemplate": "curl -L \"{URL}\" -o {FILENAME}",
"trigger": "pullRequest"
}
}
See ./GenerateInputSchema.json
Output file for generate script.
{
"packages": [
{
"packageName": "Microsoft.Cdn",
"path": [
"sdk/cdn"
],
"readmeMd": [
"specification/cdn/something/readme.md"
],
"changelog": {
"content": "Feature: something \n Breaking Changes: something\n",
"hasBreakingChange": true
},
"artifacts": [
"sdk/cdn/cdn.nuget",
"sdk/cdn/cdn.snuget"
],
"installInstructions": {
"full": "To install something...",
"lite": "dotnet something"
},
"result": "succeeded"
}
]
}
See ./GenerateOutputSchema.json
Input of install instruction script.
{
"packageName": "Microsoft.Cdn",
"artifacts": [
"sdk/cdn/cdn.nuget",
"sdk/cdn/cdn.snuget"
],
"isPublic": true,
"downloadUrlPrefix": "https://portal.azure-devex-tools.com/api/sdk-dl-pub?p=Azure/azure-rest-api-specs/1234/azure-sdk-for-net/",
"downloadCommandTemplate": "curl -L \"{URL}\" -o {FILENAME}",
"trigger": "pullRequest",
}
See ./InstallInstructionScriptInput.json
Output of install instruction script.
{
"full": "To install something...",
}
See ./InstallInstructionScriptOutput.json
{
// How this generation is triggered.
"$id": "TriggerType",
"type": "string",
"enum": ["pullRequest", "continuousIntegration"]
}
{
"type": "object",
"properties": {
"envs": {
// Environment variable to be set in following scripts.
"additionalProperties": {
"type": "string"
}
}
}
}