Skip to content

Commit

Permalink
Migrate typespec validation (#31033)
Browse files Browse the repository at this point in the history
* test breaking change mlc in js (#3451)

* `

* `

* Revert "`"

This reverts commit c26fc6a.

* Update specificationRepositoryConfiguration.json (#3457)

* Update specificationRepositoryConfiguration.json (#3459)

* Update specificationRepositoryConfiguration.json (#3462)

Revert python repo branch change as it was deleted.

* Update specificationRepositoryConfiguration.json (#3463)

* Migrate typespec-validation.yml to GH Actions

* path, fetch depth

* Introduce error

* Test a feature that AI says will collapse logs (doubtful it'll work)

* Revert "Test a feature that AI says will collapse logs (doubtful it'll work)"

This reverts commit 04aed83.

* Log $LASTEXITCODE

* Invalid syntax

* Use error logging, remove continue-on-error because that is different behavior in GitHub Actions compared to ignoreLASTEXITCODE

* Errors also get annotations in GitHub Actions

* String replacement

* Revert Logging-Functions.ps1

* Test composite action

* File location

* Invocation

* Add typespec-validation-all.yml

* Migrate typespec-validation-all.yml

* Revert main.tsp invalid spec

* fetch-depth: 2

* Long paths

* checkout@v4

* Remove pipelines

* *.yml -> *.yaml

* Do not change specificationRepositoryConfiguration.json

* Job names (for checks)

* Add Skip/Take logic and matrix

* Syntax

* Rename

* Remove "shell"

* Try defaults.run.shell (unlikely to work)

* bash

* Name for actions/setup-node@v4 does not appear in the logs. Remove.

* Use sharding semantics

* Shard

* Review feedback

* Review feedback

* +1

* Revert "Shard"... Display is confusing because it starts at 0 and doesn't reach total-shards. Math is not allowed in expressions.

This reverts commit 035bec7.

* Shard only if TotalShards > 0

* Remove description (schema validaiton does not pass, let's see what GH Actions says)

* The `description` property is not absolutely required by GH Actions at this time but adding back in because schema requires it.

* Add array functions and tests

* Move Copy-ApiVersion.Tests.ps1 out of folder (adjust paths so they are accurate)

* Add trailing newline

* Add trailing newline

* Update .github/workflows/typespec-validation.yaml

Co-authored-by: Mike Harder <mharder@microsoft.com>

* Review feedback

* Update eng/scripts/TypeSpec-Validation.ps1

Co-authored-by: Mike Harder <mharder@microsoft.com>

---------

Co-authored-by: Wanpeng Li <wanl@microsoft.com>
Co-authored-by: Peng Jiahui <46921893+Alancere@users.noreply.github.com>
Co-authored-by: Yuchao Yan <yuchaoyan@microsoft.com>
Co-authored-by: Ray Chen <raychen@microsoft.com>
Co-authored-by: Mike Harder <mharder@microsoft.com>
  • Loading branch information
6 people authored Oct 25, 2024
1 parent e6094e6 commit 31d2f2a
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 71 deletions.
22 changes: 22 additions & 0 deletions .github/actions/setup-node-npm-ci/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Setup Node 20 and run `npm ci`
description: Uses specified Node version and runs npm commands to set up the environment for REST API CI

inputs:
node-version:
description: 'Node version to use'
default: 20.x

runs:
using: "composite"

steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}

- run: npm ci
shell: bash

- run: npm ls -a
shell: bash
continue-on-error: true
69 changes: 69 additions & 0 deletions .github/workflows/typespec-validation-all.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: TypeSpec Validation All

on:
push:
branches:
- main
- RPSaaSMaster
- typespec-next

pull_request:
branches:
- main
- RPSaaSMaster
- typespec-next
paths:
- .gitattributes
- .prettierrc.json
- package-lock.json
- package.json
- tsconfig.json
- eng/**
- specification/suppressions.yaml
- specification/common-types/**

# Workflow and workflow dependencies
- .github/workflows/typespec-validation-all.yaml
- .github/actions/setup-node-npm-ci/**

schedule:
# Run 4x/day
- cron: '0 0,6,12,18 * * * '

jobs:
typespec-validation-all:
name: TypeSpec Validation All
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
# shards must start at 0 and increment by 1
shard: [0, 1, 2]
# total-shards must be an accurate count of the number of shards
total-shards: [3]

runs-on: ${{ matrix.os }}

steps:
- name: Enable git long paths
if: runner.os == 'Windows'
run: git config --global core.longpaths true

- uses: actions/checkout@v4
with:
fetch-depth: 2

- name: Setup Node 20 and run `npm ci`
uses: ./.github/actions/setup-node-npm-ci

- name: Validate All Specs
run: |
./eng/scripts/TypeSpec-Validation.ps1 `
-Shard ${{ matrix.shard }} `
-TotalShards ${{ matrix.total-shards }} `
-CheckAll `
-GitClean `
-Verbose
# Effectively the same as ignoreLASTEXITCODE: true in Azure DevOps
exit 0
shell: pwsh
24 changes: 24 additions & 0 deletions .github/workflows/typespec-validation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Typespec Validation

on: pull_request

jobs:
typespec-validation:
name: Typespec Validation
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2

- name: Setup Node 20 and run `npm ci`
uses: ./.github/actions/setup-node-npm-ci

- name: Validate Impacted Specs
run: |
./eng/scripts/TypeSpec-Validation.ps1 -GitClean -Verbose
# Effectively the same as ignoreLASTEXITCODE: true in Azure DevOps
exit 0
shell: pwsh
47 changes: 0 additions & 47 deletions eng/pipelines/typespec-validation-all.yml

This file was deleted.

16 changes: 0 additions & 16 deletions eng/pipelines/typespec-validation.yml

This file was deleted.

18 changes: 18 additions & 0 deletions eng/scripts/Array-Functions.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function ShardArray($array, $shard, $totalShards) {
if ($totalShards -lt 2) {
return $array
}

if ($shard -ge $totalShards) {
throw "Shard index ($shard) must be less than total shards ($totalShards)"
}

if ($totalShards -gt $array.Length) {
throw "Cannot shard array into more pieces than there are elements"
}

$shardSize = [math]::Ceiling($array.Length / $totalShards)
$start = $shard * $shardSize
$end = [math]::Min($start + $shardSize, $array.Length)
return $array[$start..($end - 1)]
}
77 changes: 77 additions & 0 deletions eng/scripts/Tests/Array-Functions.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
BeforeAll {
. "$PSScriptRoot\..\Array-Functions.ps1"
}

# 0..78 makes an array of 79 (prime number) items

Describe "ShardArray" {
Context "Input Validation" {
It "throws when sharding into more pieces than there are elements" {
$array = 0..78
$shard = 0
$totalShards = 150

{ ShardArray $array $shard $totalShards } | Should -Throw
}

It "returns the full array when given <totalShards> shards" -ForEach @(
@{ totalShards = 1 },
@{ totalShards = 0 },
@{ totalShards = -1 },
@{ totalShards = -2 }
) {
$array = 0..78
$shard = 0

$result = ShardArray $array $shard $totalShards

$result | Should -Be $array
}

It "throws when the shard index is greater than the total shards" {
$array = 0..78
$shard = 10
$totalShards = 3

{ ShardArray $array $shard $totalShards } | Should -Throw
}

It "does not throw when totalShards equals the array length" {
$array = 0..78
$shard = 0
$totalShards = 79

{ ShardArray $array $shard $totalShards } | Should -Not -Throw
}

}

Context "Shards arrays" -ForEach @(
@{ array = 0..78; totalShards = 1 },
@{ array = 0..78; totalShards = 2 },
@{ array = 0..11; totalShards = 3 },
@{ array = 0..10; totalShards = 4 },
@{ array = 0..78; totalShards = 79 }
) {
It "returns all of the values in order when sharding (Total Shards: <totalShards>) " {
$shards = New-Object object[] $totalShards
for ($i = 0; $i -lt $totalShards; $i++) {
# Assigning directly avoids flattening the array.
$shards[$i] = ShardArray $array $i $totalShards
}

# Flatten the array for comparison
$actual = $shards | ForEach-Object { $_ }

$actual | Should -Be $array
}

It "returns arrays of expected valid size (Total Shards: <totalShards>)" {
$maxLength = [math]::Ceiling($array.Length / $totalShards)
for ($i = 0; $i -lt $totalShards; $i++) {
$shard = ShardArray $array $i $totalShards
$shard.Length | Should -BeLessOrEqual $maxLength
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Import-Module Pester

BeforeAll {
. "$PSScriptRoot\..\..\Copy-ApiVersion-Functions.ps1"
. "$PSScriptRoot\..\Copy-ApiVersion-Functions.ps1"
}

Describe "Copy-ApiVersion regex tests" {
Expand All @@ -11,25 +11,25 @@ Describe "Copy-ApiVersion regex tests" {
version = "2024-01-01-preview"
provider = "Microsoft.AgFoodPlatform"
versionStatus = "preview"
specsDir = '..\..\..\..\..\specification\agrifood\resource-manager\Microsoft.AgFoodPlatform\preview\2023-06-01-preview'
specsDir = '..\..\..\..\specification\agrifood\resource-manager\Microsoft.AgFoodPlatform\preview\2023-06-01-preview'
},
@{
version = "2024-01-01"
provider = "Microsoft.Compute\ComputeRP"
versionStatus = "stable"
specsDir = '..\..\..\..\..\specification\compute\resource-manager\Microsoft.Compute\ComputeRP\stable\2023-09-01'
specsDir = '..\..\..\..\specification\compute\resource-manager\Microsoft.Compute\ComputeRP\stable\2023-09-01'
},
@{
version = "7.6-preview.1"
provider = "Microsoft.KeyVault"
versionStatus = "preview"
specsDir = '..\..\..\..\..\specification\keyvault\data-plane\Microsoft.KeyVault\preview\7.6-preview.1'
specsDir = '..\..\..\..\specification\keyvault\data-plane\Microsoft.KeyVault\preview\7.6-preview.1'
},
@{
version = "7.5"
provider = "Microsoft.Compute\ComputeRP"
versionStatus = "stable"
specsDir = '..\..\..\..\..\specification\keyvault\data-plane\Microsoft.KeyVault\stable\7.5'
specsDir = '..\..\..\..\specification\keyvault\data-plane\Microsoft.KeyVault\stable\7.5'
}
) {
param($version, $provider, $versionStatus, $specsDir)
Expand All @@ -48,12 +48,12 @@ Describe "Copy-ApiVersion regex tests" {
# TODO: This is fragile. The tests stop working when a service team updates their readme.md. We should instead take fixed copies or something.
It "Default version gets updated" -TestCases @(
@{
inputReadme = '..\..\..\..\..\specification\compute\resource-manager\readme.md'
inputReadme = '..\..\..\..\specification\compute\resource-manager\readme.md'
apiVersion = "2024-01-01"
versionStatus = "stable"
},
@{
inputReadme = '..\..\..\..\..\specification\keyvault\data-plane\readme.md'
inputReadme = '..\..\..\..\specification\keyvault\data-plane\readme.md'
apiVersion = "7.6-preview.1"
versionStatus = "preview"
}
Expand Down
21 changes: 20 additions & 1 deletion eng/scripts/TypeSpec-Validation.ps1
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
[CmdletBinding()]
param (
[switch]$CheckAll = $false,
[int]$Shard = 0,
[int]$TotalShards = 1,
[switch]$GitClean = $false,
[switch]$DryRun = $false,
[string]$BaseCommitish = "HEAD^",
[string]$TargetCommitish = "HEAD"
)

if ($TotalShards -gt 0 -and $Shard -ge $TotalShards) {
throw "Shard ($Shard) must be less than TotalShards ($TotalShards)"
}

. $PSScriptRoot/Logging-Functions.ps1
. $PSScriptRoot/Suppressions-Functions.ps1
. $PSScriptRoot/Array-Functions.ps1

$typespecFolders, $checkedAll = &"$PSScriptRoot/Get-TypeSpec-Folders.ps1" `
-BaseCommitish:$BaseCommitish `
-TargetCommitish:$TargetCommitish `
-CheckAll:$CheckAll

$typespecFolders, $checkedAll = &"$PSScriptRoot/Get-TypeSpec-Folders.ps1" -BaseCommitish:$BaseCommitish -TargetCommitish:$TargetCommitish -CheckAll:$CheckAll
if ($TotalShards -gt 1 -and $TotalShards -le $typespecFolders.Count) {
$typespecFolders = shardArray $typespecFolders $Shard $TotalShards
}

Write-Host "Checking $($typespecFolders.Count) TypeSpec folders:"
foreach ($typespecFolder in $typespecFolders) {
Write-Host " $typespecFolder"
}

$typespecFoldersWithFailures = @()
if ($typespecFolders) {
Expand Down

0 comments on commit 31d2f2a

Please sign in to comment.