Skip to content

Commit 4fb4da1

Browse files
authored
Merge pull request #745 from betalgo/refactor-nuget-workflow-e742c
Refactor GitHub Actions workflows for Betalgo OpenAI and Utilities. C…
2 parents 27c6b85 + ab46121 commit 4fb4da1

File tree

5 files changed

+318
-54
lines changed

5 files changed

+318
-54
lines changed

.github/scripts/publish-nuget.ps1

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[string]$ProjectFilePath,
4+
5+
[string]$PackageName,
6+
7+
[string]$VersionFilePath,
8+
9+
[string]$VersionRegex = '^\s*<Version>(.*)</Version>\s*$',
10+
11+
[string]$VersionStatic,
12+
13+
[bool]$TagCommit = $true,
14+
15+
[string]$TagFormat = 'v*',
16+
17+
[string]$NugetKey,
18+
19+
[string]$NugetSource = 'https://api.nuget.org',
20+
21+
[bool]$IncludeSymbols = $false,
22+
23+
[bool]$NoBuild = $false,
24+
25+
[bool]$PublishToGitHubPackages = $false,
26+
27+
[string]$GitHubPackagesOwner,
28+
29+
[string]$GitHubPackagesApiKey,
30+
31+
[string]$GitHubPackagesSource,
32+
33+
[bool]$GitHubPackagesIncludeSymbols = $false
34+
)
35+
36+
$ErrorActionPreference = 'Stop'
37+
38+
function Set-GithubOutput {
39+
param(
40+
[string]$Name,
41+
[string]$Value
42+
)
43+
44+
if (-not $env:GITHUB_OUTPUT) {
45+
return
46+
}
47+
48+
"$Name=$Value" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
49+
}
50+
51+
function Invoke-CommandChecked {
52+
param(
53+
[string]$Command,
54+
[string[]]$Arguments
55+
)
56+
57+
$logArgs = @()
58+
for ($i = 0; $i -lt $Arguments.Count; $i++) {
59+
$current = $Arguments[$i]
60+
if ($current -in @("--api-key", "-k")) {
61+
$logArgs += $current
62+
if ($i + 1 -lt $Arguments.Count) {
63+
$logArgs += "***"
64+
$i++
65+
}
66+
continue
67+
}
68+
$logArgs += $current
69+
}
70+
71+
$commandDisplay = "$Command $($logArgs -join ' ')"
72+
Write-Host "Executing: $commandDisplay"
73+
$process = Start-Process -FilePath $Command -ArgumentList $Arguments -NoNewWindow -Wait -PassThru
74+
if ($process.ExitCode -ne 0) {
75+
throw "Command '$commandDisplay' failed with exit code $($process.ExitCode)."
76+
}
77+
}
78+
79+
if (-not (Test-Path $ProjectFilePath)) {
80+
throw "Project file not found: $ProjectFilePath"
81+
}
82+
83+
$resolvedProjectPath = (Resolve-Path $ProjectFilePath).ProviderPath
84+
if (-not $PackageName) {
85+
$PackageName = [IO.Path]::GetFileNameWithoutExtension($resolvedProjectPath)
86+
}
87+
88+
$versionFilePath = if ($VersionFilePath) { $VersionFilePath } else { $resolvedProjectPath }
89+
90+
if (-not $VersionStatic) {
91+
if (-not (Test-Path $versionFilePath)) {
92+
throw "Version file not found: $versionFilePath"
93+
}
94+
95+
$fileContent = Get-Content $versionFilePath -Raw
96+
$match = [regex]::Match($fileContent, $VersionRegex)
97+
if (-not $match.Success -or -not $match.Groups[1].Value) {
98+
throw "Unable to extract version information using regex '$VersionRegex' from '$versionFilePath'."
99+
}
100+
$Version = $match.Groups[1].Value.Trim()
101+
} else {
102+
$Version = $VersionStatic
103+
}
104+
105+
Write-Host "Project: $ProjectFilePath"
106+
Write-Host "Package: $PackageName"
107+
Write-Host "Version: $Version"
108+
109+
Set-GithubOutput -Name "package_name" -Value $PackageName
110+
Set-GithubOutput -Name "version" -Value $Version
111+
112+
$packageIdLower = $PackageName.ToLowerInvariant()
113+
$versionsUri = "$NugetSource/v3-flatcontainer/$packageIdLower/index.json"
114+
115+
$existingVersions = @()
116+
try {
117+
$response = Invoke-RestMethod -Method Get -Uri $versionsUri -ErrorAction Stop
118+
if ($response -and $response.versions) {
119+
$existingVersions = $response.versions
120+
}
121+
} catch [System.Net.WebException] {
122+
$response = $_.Exception.Response
123+
if ($response -and $response.StatusCode -eq [System.Net.HttpStatusCode]::NotFound) {
124+
Write-Host "Package not found on feed. Treating as first release."
125+
} else {
126+
throw
127+
}
128+
}
129+
130+
$shouldPublish = -not ($existingVersions -contains $Version)
131+
Set-GithubOutput -Name "should_publish" -Value ($shouldPublish.ToString().ToLowerInvariant())
132+
133+
if (-not $shouldPublish) {
134+
Write-Host "Version $Version already exists on $NugetSource. Skipping publish."
135+
Set-GithubOutput -Name "published" -Value "false"
136+
return
137+
}
138+
139+
if (-not $NugetKey) {
140+
Write-Warning "NUGET_KEY was not provided; skipping publish."
141+
Set-GithubOutput -Name "published" -Value "false"
142+
return
143+
}
144+
145+
$outputDir = Join-Path ([IO.Path]::GetDirectoryName($resolvedProjectPath)) "nupkg"
146+
if (-not (Test-Path $outputDir)) {
147+
New-Item -ItemType Directory -Path $outputDir | Out-Null
148+
}
149+
150+
Get-ChildItem -Path $outputDir -Filter '*.nupkg' -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
151+
Get-ChildItem -Path $outputDir -Filter '*.snupkg' -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
152+
153+
if (-not $NoBuild) {
154+
Invoke-CommandChecked -Command "dotnet" -Arguments @("build", "-c", "Release", $resolvedProjectPath)
155+
}
156+
157+
$packArguments = @("pack", $resolvedProjectPath, "-c", "Release", "-o", $outputDir)
158+
if ($IncludeSymbols) {
159+
$packArguments += @("--include-symbols", "-p:SymbolPackageFormat=snupkg")
160+
}
161+
Invoke-CommandChecked -Command "dotnet" -Arguments $packArguments
162+
163+
$packagePattern = "$PackageName.$Version*.nupkg"
164+
$packageFile = Get-ChildItem -Path $outputDir -Filter $packagePattern -File | Where-Object { $_.Extension -eq '.nupkg' } | Select-Object -First 1
165+
166+
if (-not $packageFile) {
167+
$packageFile = Get-ChildItem -Path $outputDir -Filter '*.nupkg' -File | Select-Object -First 1
168+
}
169+
170+
if (-not $packageFile) {
171+
throw "No package file found in $outputDir."
172+
}
173+
174+
$symbolFile = $null
175+
if ($IncludeSymbols) {
176+
$symbolPattern = "$PackageName.$Version*.snupkg"
177+
$symbolFile = Get-ChildItem -Path $outputDir -Filter $symbolPattern -File | Select-Object -First 1
178+
if (-not $symbolFile) {
179+
$symbolFile = Get-ChildItem -Path $outputDir -Filter '*.snupkg' -File | Select-Object -First 1
180+
}
181+
}
182+
183+
$sourcePushUri = "$NugetSource/v3/index.json"
184+
Invoke-CommandChecked -Command "dotnet" -Arguments @("nuget", "push", $packageFile.FullName, "--source", $sourcePushUri, "--api-key", $NugetKey, "--skip-duplicate", "--no-symbols")
185+
186+
if ($IncludeSymbols -and $symbolFile) {
187+
Invoke-CommandChecked -Command "dotnet" -Arguments @("nuget", "push", $symbolFile.FullName, "--source", $sourcePushUri, "--api-key", $NugetKey, "--skip-duplicate")
188+
}
189+
190+
if ($PublishToGitHubPackages) {
191+
if (-not $GitHubPackagesOwner) {
192+
$GitHubPackagesOwner = $env:GITHUB_REPOSITORY_OWNER
193+
}
194+
195+
if (-not $GitHubPackagesSource -and $GitHubPackagesOwner) {
196+
$GitHubPackagesSource = "https://nuget.pkg.github.com/$GitHubPackagesOwner/index.json"
197+
}
198+
199+
if (-not $GitHubPackagesApiKey) {
200+
Write-Warning "GitHub Packages API key/token not provided; skipping GitHub Packages publish."
201+
} elseif (-not $GitHubPackagesSource) {
202+
Write-Warning "GitHub Packages source could not be determined; skipping GitHub Packages publish."
203+
} else {
204+
Write-Host "Publishing to GitHub Packages source $GitHubPackagesSource"
205+
Invoke-CommandChecked -Command "dotnet" -Arguments @("nuget", "push", $packageFile.FullName, "--source", $GitHubPackagesSource, "--api-key", $GitHubPackagesApiKey, "--skip-duplicate", "--no-symbols")
206+
if ($GitHubPackagesIncludeSymbols -and $symbolFile) {
207+
Invoke-CommandChecked -Command "dotnet" -Arguments @("nuget", "push", $symbolFile.FullName, "--source", $GitHubPackagesSource, "--api-key", $GitHubPackagesApiKey, "--skip-duplicate")
208+
}
209+
Set-GithubOutput -Name "github_packages_source" -Value $GitHubPackagesSource
210+
}
211+
}
212+
213+
Set-GithubOutput -Name "published" -Value "true"
214+
Set-GithubOutput -Name "package_path" -Value $packageFile.FullName
215+
if ($symbolFile) {
216+
Set-GithubOutput -Name "symbols_package_path" -Value $symbolFile.FullName
217+
}
218+
219+
if ($TagCommit) {
220+
$tagName = $TagFormat.Replace("*", $Version)
221+
Invoke-CommandChecked -Command "git" -Arguments @("config", "user.name", "github-actions")
222+
Invoke-CommandChecked -Command "git" -Arguments @("config", "user.email", "actions@github.com")
223+
Invoke-CommandChecked -Command "git" -Arguments @("tag", $tagName)
224+
Invoke-CommandChecked -Command "git" -Arguments @("push", "origin", $tagName)
225+
Set-GithubOutput -Name "tag" -Value $tagName
226+
}
227+

.github/workflows/BuildAndDeployBetalgoOpenAI.yml

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@ on:
55
branches: [ master ]
66

77
jobs:
8-
build:
8+
sdk:
9+
10+
permissions:
11+
contents: write
12+
packages: write
913

1014
runs-on: windows-latest
1115

1216
steps:
13-
- uses: actions/checkout@v2
17+
- uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
1420
- name: Setup .NET
15-
uses: actions/setup-dotnet@v1
21+
uses: actions/setup-dotnet@v4
1622
with:
1723
dotnet-version: 9.0.x
1824
- name: Clean
@@ -24,19 +30,85 @@ jobs:
2430
- name: Test
2531
run: dotnet test --no-build --verbosity normal
2632

27-
- name: publish OpenAI
28-
id: publish_nuget_OpenAI
29-
uses: alirezanet/publish-nuget@v3.1.0
33+
- name: Publish OpenAI
34+
shell: pwsh
35+
env:
36+
NUGET_KEY: ${{ secrets.NUGET_KEY }}
37+
GH_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
GH_OWNER: ${{ github.repository_owner }}
39+
run: |
40+
.\.github\scripts\publish-nuget.ps1 `
41+
-ProjectFilePath "OpenAI.SDK\Betalgo.Ranul.OpenAI.csproj" `
42+
-PackageName "Betalgo.Ranul.OpenAI" `
43+
-NugetKey $env:NUGET_KEY `
44+
-IncludeSymbols $true `
45+
-TagCommit $true `
46+
-TagFormat "v*" `
47+
-PublishToGitHubPackages $true `
48+
-GitHubPackagesOwner $env:GH_OWNER `
49+
-GitHubPackagesApiKey $env:GH_PACKAGES_TOKEN `
50+
-GitHubPackagesIncludeSymbols $false
51+
- name: Publish Contracts
52+
shell: pwsh
53+
env:
54+
NUGET_KEY: ${{ secrets.NUGET_KEY }}
55+
GH_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56+
GH_OWNER: ${{ github.repository_owner }}
57+
run: |
58+
.\.github\scripts\publish-nuget.ps1 `
59+
-ProjectFilePath "Betalgo.Ranul.OpenAI.Contracts\Betalgo.Ranul.OpenAI.Contracts.csproj" `
60+
-PackageName "Betalgo.Ranul.OpenAI.Contracts" `
61+
-NugetKey $env:NUGET_KEY `
62+
-IncludeSymbols $true `
63+
-TagCommit $true `
64+
-TagFormat "v*" `
65+
-PublishToGitHubPackages $true `
66+
-GitHubPackagesOwner $env:GH_OWNER `
67+
-GitHubPackagesApiKey $env:GH_PACKAGES_TOKEN `
68+
-GitHubPackagesIncludeSymbols $false
69+
70+
utilities:
71+
needs: sdk
72+
73+
permissions:
74+
contents: write
75+
packages: write
76+
77+
runs-on: windows-latest
78+
79+
steps:
80+
- uses: actions/checkout@v4
3081
with:
31-
PROJECT_FILE_PATH: OpenAI.SDK\Betalgo.Ranul.OpenAI.csproj
32-
NUGET_KEY: ${{secrets.NUGET_KEY}}
33-
INCLUDE_SYMBOLS: true
34-
PACKAGE_NAME: Betalgo.Ranul.OpenAI
35-
- name: publish Contracts
36-
id: publish_nuget_Contracts
37-
uses: alirezanet/publish-nuget@v3.1.0
82+
fetch-depth: 0
83+
84+
- name: Setup .NET
85+
uses: actions/setup-dotnet@v4
3886
with:
39-
PROJECT_FILE_PATH: Betalgo.Ranul.OpenAI.Contracts\Betalgo.Ranul.OpenAI.Contracts.csproj
40-
NUGET_KEY: ${{secrets.NUGET_KEY}}
41-
INCLUDE_SYMBOLS: true
42-
PACKAGE_NAME: Betalgo.Ranul.OpenAI.Contracts
87+
dotnet-version: 9.0.x
88+
- name: Clean
89+
run: dotnet clean
90+
- name: Restore dependencies
91+
run: dotnet restore
92+
- name: Build
93+
run: dotnet build --no-restore
94+
- name: Test
95+
run: dotnet test --no-build --verbosity normal
96+
97+
- name: Publish OpenAI Utilities
98+
shell: pwsh
99+
env:
100+
NUGET_KEY: ${{ secrets.NUGET_KEY_UTILITIES }}
101+
GH_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }}
102+
GH_OWNER: ${{ github.repository_owner }}
103+
run: |
104+
.\.github\scripts\publish-nuget.ps1 `
105+
-ProjectFilePath "OpenAI.Utilities\Betalgo.OpenAI.Utilities.csproj" `
106+
-PackageName "Betalgo.OpenAI.Utilities" `
107+
-NugetKey $env:NUGET_KEY `
108+
-IncludeSymbols $true `
109+
-TagCommit $true `
110+
-TagFormat "v*" `
111+
-PublishToGitHubPackages $true `
112+
-GitHubPackagesOwner $env:GH_OWNER `
113+
-GitHubPackagesApiKey $env:GH_PACKAGES_TOKEN `
114+
-GitHubPackagesIncludeSymbols $false

.github/workflows/BuildAndDeployBetalgoOpenAIUtilities.yml

Lines changed: 0 additions & 37 deletions
This file was deleted.

Betalgo.Ranul.OpenAI.Contracts/Enums/AssistantMessageRole.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ public sealed class Converter : JsonConverter<AssistantMessageRole>
3434

3535

3636

37+

0 commit comments

Comments
 (0)