Skip to content
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

Added switch to skip sync and generate script call #6305

Merged
merged 10 commits into from
Jun 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions doc/development/powershell.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ This page contains guidelines for developing or updating powershell scripts used
Table of Contents
=================

* [TLDR](#tldr)
* [Structure](#structure)
* [Functionality](#functionality)
* [Style](#style)
* [Testing](#testing)
* [Unit Testing](#unit-testing)
* [Running Pester Tests](#running-pester-tests)
* [Local/Pipeline Functional Testing](#localpipeline-functional-testing)
- [Table of Contents](#table-of-contents)
- [TLDR](#tldr)
- [Structure](#structure)
- [Functionality](#functionality)
- [Style](#style)
- [Testing](#testing)
- [Unit Testing](#unit-testing)
- [Running Pester Tests](#running-pester-tests)
- [Local/Pipeline Functional Testing](#localpipeline-functional-testing)

## TLDR

Expand Down Expand Up @@ -110,13 +111,13 @@ Powershell scripts should be testable, via one or more methods:
Unit tests should be written for all scripts, and should utilize [Pester](https://pester.dev/).

- Tests can be located alongside scripts in a directory called `tests`.
- Example pester test suites: [job matrix tests](https://github.com/Azure/azure-sdk-tools/tree/main/eng/common/scripts/job-matrix/tests), [asset sync tests](https://github.com/Azure/azure-sdk-tools/blob/main/tools/asset-sync/assets.Tests.ps1)
- Example pester test suites: [job matrix tests](https://github.com/Azure/azure-sdk-tools/tree/main/eng/common/scripts/job-matrix/tests), [asset sync tests](https://github.com/Azure/azure-sdk-tools/blob/main/tools/assets-automation/asset-sync/assets.Tests.ps1)
- A CI pipeline should be defined to run scripts unit tests at the very least. See [archetype-sdk-tool-pwsh](https://github.com/Azure/azure-sdk-tools/blob/main/eng/common/pipelines/templates/stages/archetype-sdk-tool-pwsh.yml) for how to do this.
- Script code should always be written so as much of the surface area as possible can be run via unit tests. Move code that calls out to external dependencies into modular functions, and simplify context/data structures passed to functions as much as possible to it can be easily mocked.

#### Running Pester Tests

(stolen from https://github.com/Azure/azure-sdk-tools/blob/main/tools/asset-sync/contributing.md).
(stolen from https://github.com/Azure/azure-sdk-tools/blob/main/tools/assets-automation/asset-sync/contributing.md).

> **First, ensure you have `pester` installed:**
>
Expand Down
28 changes: 17 additions & 11 deletions eng/common/scripts/TypeSpec-Project-Process.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ param (
[Parameter(Position = 1)]
[string] $CommitHash,
[Parameter(Position = 2)]
[string] $RepoUrl
[string] $RepoUrl,
[switch] $SkipSyncAndGenerate
)

. $PSScriptRoot/common.ps1
Expand Down Expand Up @@ -111,7 +112,7 @@ $specRepoRoot = ""
$generateFromLocalTypeSpec = $false
# remote url scenario
# example url of tspconfig.yaml: https://github.com/Azure/azure-rest-api-specs-pr/blob/724ccc4d7ef7655c0b4d5c5ac4a5513f19bbef35/specification/containerservice/Fleet.Management/tspconfig.yaml
if ($TypeSpecProjectDirectory -match '^https://github.com/(?<repo>Azure/azure-rest-api-specs(-pr)?)/blob/(?<commit>[0-9a-f]{40})/(?<path>.*)/tspconfig.yaml$') {
if ($TypeSpecProjectDirectory -match '^https://github.com/(?<repo>[^/]*/azure-rest-api-specs(-pr)?)/blob/(?<commit>[0-9a-f]{40})/(?<path>.*)/tspconfig.yaml$') {
try {
$TypeSpecProjectDirectory = $TypeSpecProjectDirectory -replace "https://github.com/(.*)/(tree|blob)", "https://raw.githubusercontent.com/`$1"
Invoke-WebRequest $TypeSpecProjectDirectory -OutFile $tspConfigPath -MaximumRetryCount 3
Expand Down Expand Up @@ -199,14 +200,19 @@ if ($generateFromLocalTypeSpec) {
$sdkProjectFolder = CreateUpdate-TspLocation $tspConfigYaml $TypeSpecProjectDirectory $CommitHash $repo $sdkRepoRootPath
}

# call TypeSpec-Project-Sync.ps1
$syncScript = Join-Path $PSScriptRoot TypeSpec-Project-Sync.ps1
& $syncScript $sdkProjectFolder $specRepoRoot
if ($LASTEXITCODE) { exit $LASTEXITCODE }

# call TypeSpec-Project-Generate.ps1
$generateScript = Join-Path $PSScriptRoot TypeSpec-Project-Generate.ps1
& $generateScript $sdkProjectFolder
if ($LASTEXITCODE) { exit $LASTEXITCODE }
# checking skip switch
if ($SkipSyncAndGenerate) {
Write-Host "Skip calling TypeSpec-Project-Sync.ps1 and TypeSpec-Project-Generate.ps1."
} else {
# call TypeSpec-Project-Sync.ps1
$syncScript = Join-Path $PSScriptRoot TypeSpec-Project-Sync.ps1
& $syncScript $sdkProjectFolder $specRepoRoot
if ($LASTEXITCODE) { exit $LASTEXITCODE }

# call TypeSpec-Project-Generate.ps1
$generateScript = Join-Path $PSScriptRoot TypeSpec-Project-Generate.ps1
& $generateScript $sdkProjectFolder
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}

return $sdkProjectFolder
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,36 @@ public OpenSourceRequestManager(IConfiguration configuration)
}

public async Task<OpenSourceUserInfo> GetUserInfo(string githubUserId)
{
try
{
var ossClient = new HttpClient();
await SetHeaders(ossClient);
var response = await ossClient.GetAsync($"https://repos.opensource.microsoft.com/api/people/links/github/{githubUserId}");
response.EnsureSuccessStatusCode();
var userDetailsJson = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<OpenSourceUserInfo>(userDetailsJson);
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
_telemetryClient.TrackTrace($"Github username {githubUserId} is not found");
}
catch (Exception ex)
{
_telemetryClient.TrackException(ex);
{
int retryCount = 0;
bool authCheckCompleted = false;
while (!authCheckCompleted && retryCount < 3)
{
try
{
retryCount++;
var ossClient = new HttpClient();
await SetHeaders(ossClient);
var response = await ossClient.GetAsync($"https://repos.opensource.microsoft.com/api/people/links/github/{githubUserId}");
response.EnsureSuccessStatusCode();
var userDetailsJson = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<OpenSourceUserInfo>(userDetailsJson);
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
_telemetryClient.TrackTrace($"GitHub username {githubUserId} is not found");
authCheckCompleted = true;
}
catch (Exception ex)
{
_telemetryClient.TrackException(ex);
}

if(!authCheckCompleted && retryCount < 3)
{
await Task.Delay(2000);
_telemetryClient.TrackTrace($"Retrying to check user authorization for user Id {githubUserId}");
}
}
return null;
}
Expand All @@ -63,7 +76,7 @@ public async Task<bool> IsAuthorizedUser(string githubUserId)
var resp = await GetUserInfo(githubUserId);
if (resp == null)
return false;
// For now we only need to check if user info is availableon MS OSS
// For now we only need to check if user info is available on MS OSS
return true;
}

Expand Down
9 changes: 9 additions & 0 deletions tools/assets-automation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Assets automation tooling

This directory contains tooling pertaining to the _support_ of externalized assets created by the [azure-sdk test-proxy](../test-proxy/Azure.Sdk.Tools.TestProxy/README.md).

| Directory | Description |
|---|---|
| [assets-maintenance-tool](./assets-maintenance-tool/README.md) | CLI tool used to scan, backup, and clean azure-sdk assets across all repositories. |
| [assets-reporting](./assets-reporting/README.md) | CLI tool used to audit current repositories and find status of test-proxy adoption on a per-package basis. Used to generate weekly reporting. |
| [asset-sync](./assets-sync/README.md) | Deprecated initial version of `asset-sync` implementation. The current implementation ended up integrated directly into the `test-proxy` codebase, rather than existing as an external powershell script. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>

<ItemGroup>
<Folder Include="TestResources\basic_output\" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Azure.Sdk.Tools.Assets.MaintenanceTool\Azure.Sdk.Tools.Assets.MaintenanceTool.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="TestResources\basic_output\output.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="TestResources\configurations\sample-repo-configuration.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
global using NUnit.Framework;
using Azure.Sdk.Tools.Assets.MaintenanceTool.Model;
using Azure.Sdk.Tools.Assets.MaintenanceTool.Scan;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;

namespace Azure.Sdk.Tools.Assets.MaintenanceTool.Tests
{
public class CLITests
{
public string TestDirectory { get; protected set; }

[SetUp]
public void Setup()
{
var workingDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

if (!Directory.Exists(workingDirectory))
{
Directory.CreateDirectory(workingDirectory);
}

// copy our static test files there
var source = Path.Combine(Directory.GetCurrentDirectory(), "TestResources");
var target = Path.Combine(workingDirectory, "TestResources");

Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(source, target);

TestDirectory = workingDirectory;
}

[TearDown]
public void TearDown()
{
Directory.Delete(TestDirectory, true);
}

[Test]
[TestCase("scan", "-c", "")]
[TestCase("scan", "--config", "")]
public void TestScanOptions(params string[] args)
{
}

[Test]
[TestCase("scan")]
[TestCase("scan", "--config")]
public void TestInvalidScanOptions(params string[] args)
{
var obj = new object();

var rootCommand = Program.InitializeCommandOptions((DefaultOptions) =>
{
obj = DefaultOptions;
});

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;

namespace Azure.Sdk.Tools.Assets.MaintenanceTool.Tests
{
public class GitTokenSkipAttribute : NUnitAttribute, IApplyToTest
{
public GitTokenSkipAttribute() { }

public void ApplyToTest(Test test)
{
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TF_BUILD")) && string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GIT_TOKEN")))
{
new IgnoreAttribute("Skipping this test. Within a CI run, and GIT_TOKEN is not set.").ApplyToTest(test);
}
}
}
}
Loading