summaryrefslogtreecommitdiff
path: root/Scripts/GenerateClients.ps1
blob: 6c9c2f2b0b5cc097b663c47844e1f0e21fda1097 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# Use the Microsoft provided `Get-OpenApiDocument.ps1` to start the Azure function
# and extract the swagger.json. Finally, invoke NSwag on the exported swagger.json
# to generate a C# and TypeScript client.

# Configurations
# Azure Functions Core Tools config
$funcToolsUrl = "https://github.com/Azure/azure-functions-core-tools/releases/download/4.0.5455/Azure.Functions.Cli.win-x64.4.0.5455.zip"
$funcToolsSha512 = "7b75f5b2e35990434eafd4b56e125d3e78dd79a524e47c556cab11f21d250901e59a9f37dd8dd6220d27e52ef89d6e0ebdf4444a450f4cbb5b6ff36776af96e9"

# Azure Functions OpenAPI helper script config
$openApiSwaggerScriptUrl = "https://raw.githubusercontent.com/Azure/azure-functions-openapi-extension/238a039c257e033a6049586410da4666412cd875/actions/Get-OpenApiDocument.ps1"
$openApiSwaggerScriptSha512 = "d3361ab279a5050db5ccc3697b8126c527691faca6490bc2b983c7719d3fea7b9225720d0496627ef46ae350010d5dc2415b09dac42b14cf3828cfea662f5cb6"

# NSwag config
$nswagZipUrl = "https://github.com/RicoSuter/NSwag/releases/download/v14.0.1/NSwag.zip"
$nswagSha512 = "8ab9001c1ad0382300bc3e8507789129d9e5f1887c5eb9dcdeb99d27cfb80f3881f22e7ce41cb51be36127e4cf727dcf8b47d7f364f3228c0ec395c98c891441"
$nswagBinary = "Net70\dotnet-nswag.exe"
$defaultNSwagPath = Join-Path (Join-Path ([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::ProgramFilesX86)) "Rico Suter\NSwagStudio\") $nswagBinary

# Define the input and output paths
$rootProject = Split-Path -Path $PSScriptRoot -Parent
$generatedPath = Join-Path $rootProject "generated"
$inputSwaggerJson = Join-Path $generatedPath "swagger.json"
$functionAppPath = "bin\Debug\net7.0"

# Function to create a temporary directory
function New-TemporaryDirectory {
    $tempFolder = [System.IO.Path]::GetTempFileName()
    Remove-Item $tempFolder
    return New-Item -Path $tempFolder -ItemType Directory
}

# Function to download and verify a file
function Download-AndVerifyFile {
    param ($url, $destination, $expectedSha512)
    Invoke-WebRequest -Uri $url -OutFile $destination
    $computedHash = Get-FileSha512Hash $destination
    if ($computedHash -ne $expectedSha512.ToLower()) {
        throw "Checksum verification failed. The downloaded file may be corrupted or tampered with. Received: $computedHash Expected: $expectedSha512"
    }
}

# Function to calculate SHA512 hash of a file
function Get-FileSha512Hash {
    param ($filePath)
    $fileStream = [System.IO.File]::OpenRead($filePath)
    $sha512 = [System.Security.Cryptography.SHA512]::Create()
    $computedHash = [BitConverter]::ToString($sha512.ComputeHash($fileStream)).Replace("-", "").ToLower()
    $fileStream.Close()
    return $computedHash
}

# Function to extract a ZIP file
function Extract-ZipFile {
    param ($zipPath, $destination)
    Expand-Archive -Path $zipPath -DestinationPath $destination
}

# Function to download and setup Azure Functions Core Tools
function Setup-AzureFunctionsCoreTools {
    param ($tempFolder)
    $tempFunctionFolder = Join-Path $tempFolder "coretools"
    New-Item -Path $tempFunctionFolder -ItemType Directory | Out-Null
    $zipPath = Join-Path $tempFunctionFolder "AzureFunctionsCli.zip"
    Download-AndVerifyFile -url $funcToolsUrl -destination $zipPath -expectedSha512 $funcToolsSha512
    Extract-ZipFile -zipPath $zipPath -destination $tempFunctionFolder
    $env:Path += ";$tempFunctionFolder"
}

# Function to download and setup NSwag
function Setup-NSwag {
    param ($tempFolder, $nswagBinary, $nswagZipUrl, $nswagSha512)
    $tempNSwagFolder = Join-Path $tempFolder "nswag"
    New-Item -Path $tempNSwagFolder -ItemType Directory | Out-Null
    $zipPath = Join-Path $tempNSwagFolder "NSwag.zip"
    Download-AndVerifyFile -url $nswagZipUrl -destination $zipPath -expectedSha512 $nswagSha512
    Extract-ZipFile -zipPath $zipPath -destination $tempNSwagFolder
    $nswagLocation = Join-Path $tempNSwagFolder $nswagBinary
    return $nswagLocation
}

# Function to run NSwag
function Run-NSwag {
    param ($nswagExe, $nswagConfigFile, $generatedPath, $inputSwaggerJson)

    # Check if the NSwag executable exists
    if (-not (Test-Path $nswagExe)) {
        throw "NSwag executable not found at path: $nswagExe"
    }

    # Ensure the .nswag file exists
    if (-not (Test-Path $nswagConfigFile)) {
        throw ".nswag configuration file not found at path: $nswagConfigFile"
    }

    &$nswagExe run $nswagConfigFile /variables:GeneratedPath="$generatedPath",InputSwaggerJson="$inputSwaggerJson"
}

# Main script starts here

# Create a temporary folder
$tempFolder = New-TemporaryDirectory

# Use try-finally to ensure cleanup
try {
    # Remove existing generated files
    Remove-Item $generatedPath -Recurse -Force -ErrorAction "SilentlyContinue"

    # Check if Azure Functions Core Tools is installed
    $azureFuncTools = Get-Command func -ErrorAction SilentlyContinue

    if ($null -eq $azureFuncTools) {
        Write-Output "Setting up Azure Function Core Tools"
        Setup-AzureFunctionsCoreTools -tempFolder $tempFolder.FullName
    }

    # Run the function and extract the swagger.json
    $scriptPath = Join-Path $tempFolder "Get-OpenApiDocument.ps1"
    Write-Output "Running $scriptPath"
    Download-AndVerifyFile -url $openApiSwaggerScriptUrl -destination $scriptPath -expectedSha512 $openApiSwaggerScriptSha512
    $env:GITHUB_WORKSPACE=$rootProject
    & $scriptPath -FunctionAppPath $functionAppPath

    # Ensure the .nswag file exists
    if (-not (Test-Path $inputSwaggerJson)) {
        throw "swagger.json file not found at path: $inputSwaggerJson"
    } else {
        Write-Output "swagger.json generated"
    }

    $nswagExe = $defaultNSwagPath

    if (-not (Test-Path $nswagExe)) {
        $nswagExe = (Setup-NSwag -tempFolder $tempFolder.FullName -nswagBinary $nswagBinary -nswagZipUrl $nswagZipUrl -nswagSha512 $nswagSha512)
    }

    # Define the path to the .nswag file
    $nswagConfigFile = Join-Path $PSScriptRoot "nswag.json"

    # Run NSwag with the .nswag configuration file
    Write-Output "Launching NSwag at $nswagExe"
    Run-NSwag -nswagExe $nswagExe -nswagConfigFile $nswagConfigFile -generatedPath $generatedPath -inputSwaggerJson $inputSwaggerJson

    # Output success message
    Write-Host "NSwag execution completed successfully."
} catch {
    # Output error message
    Write-Error "An error occurred: $_"
} finally {
    # Clean up the temporary folder
    Remove-Item $tempFolder -Recurse -Force
}