diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 04bdfb2..9265164 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,6 +20,9 @@ jobs:
with:
dotnet-version: '8.0.x'
+ - name: Verify release configuration
+ run: ./scripts/verify-release-config.sh
+
- name: Restore dependencies
run: dotnet restore
diff --git a/.github/workflows/publish-release-from-tag.yml b/.github/workflows/publish-release-from-tag.yml
index c2bd992..c90fc71 100644
--- a/.github/workflows/publish-release-from-tag.yml
+++ b/.github/workflows/publish-release-from-tag.yml
@@ -118,6 +118,12 @@ jobs:
-p:PackageVersion="$VERSION" \
-p:Version="$VERSION" \
--output ./artifacts
+ dotnet pack src/Braintrust.Sdk.AzureOpenAI/Braintrust.Sdk.AzureOpenAI.csproj \
+ --configuration Release \
+ --no-build \
+ -p:PackageVersion="$VERSION" \
+ -p:Version="$VERSION" \
+ --output ./artifacts
- name: Find built artifacts
id: find-artifacts
@@ -133,6 +139,8 @@ jobs:
ANTHROPIC_SNUPKG=$(find ./artifacts -name "Braintrust.Sdk.Anthropic.${VERSION}.snupkg" | head -1)
AGENTFRAMEWORK_NUPKG=$(find ./artifacts -name "Braintrust.Sdk.AgentFramework.${VERSION}.nupkg" | head -1)
AGENTFRAMEWORK_SNUPKG=$(find ./artifacts -name "Braintrust.Sdk.AgentFramework.${VERSION}.snupkg" | head -1)
+ AZUREOPENAI_NUPKG=$(find ./artifacts -name "Braintrust.Sdk.AzureOpenAI.${VERSION}.nupkg" | head -1)
+ AZUREOPENAI_SNUPKG=$(find ./artifacts -name "Braintrust.Sdk.AzureOpenAI.${VERSION}.snupkg" | head -1)
echo "nupkg=$NUPKG" >> $GITHUB_OUTPUT
if [[ -n "$SNUPKG" ]]; then
@@ -150,6 +158,10 @@ jobs:
if [[ -n "$AGENTFRAMEWORK_SNUPKG" ]]; then
echo "agentframework_snupkg=$AGENTFRAMEWORK_SNUPKG" >> $GITHUB_OUTPUT
fi
+ echo "azureopenai_nupkg=$AZUREOPENAI_NUPKG" >> $GITHUB_OUTPUT
+ if [[ -n "$AZUREOPENAI_SNUPKG" ]]; then
+ echo "azureopenai_snupkg=$AZUREOPENAI_SNUPKG" >> $GITHUB_OUTPUT
+ fi
echo "Found artifacts:"
echo " NuGet package: $NUPKG"
@@ -168,6 +180,10 @@ jobs:
if [[ -n "$AGENTFRAMEWORK_SNUPKG" ]]; then
echo " AgentFramework symbols package: $AGENTFRAMEWORK_SNUPKG"
fi
+ echo " AzureOpenAI NuGet package: $AZUREOPENAI_NUPKG"
+ if [[ -n "$AZUREOPENAI_SNUPKG" ]]; then
+ echo " AzureOpenAI symbols package: $AZUREOPENAI_SNUPKG"
+ fi
- name: Create GitHub Release
run: |
@@ -187,7 +203,9 @@ jobs:
"${{ steps.find-artifacts.outputs.anthropic_nupkg }}" \
"${{ steps.find-artifacts.outputs.anthropic_snupkg }}" \
"${{ steps.find-artifacts.outputs.agentframework_nupkg }}" \
- "${{ steps.find-artifacts.outputs.agentframework_snupkg }}"; do
+ "${{ steps.find-artifacts.outputs.agentframework_snupkg }}" \
+ "${{ steps.find-artifacts.outputs.azureopenai_nupkg }}" \
+ "${{ steps.find-artifacts.outputs.azureopenai_snupkg }}"; do
if [[ -n "$artifact" && -f "$artifact" ]]; then
gh release upload "$TAG" "$artifact"
fi
@@ -207,7 +225,8 @@ jobs:
"${{ steps.find-artifacts.outputs.nupkg }}" \
"${{ steps.find-artifacts.outputs.openai_nupkg }}" \
"${{ steps.find-artifacts.outputs.anthropic_nupkg }}" \
- "${{ steps.find-artifacts.outputs.agentframework_nupkg }}"; do
+ "${{ steps.find-artifacts.outputs.agentframework_nupkg }}" \
+ "${{ steps.find-artifacts.outputs.azureopenai_nupkg }}"; do
if [[ -z "$NUPKG" || ! -f "$NUPKG" ]]; then
echo "Error: NuGet package not found: $NUPKG"
exit 1
@@ -229,3 +248,4 @@ jobs:
echo " https://www.nuget.org/packages/Braintrust.Sdk.OpenAI/$VERSION"
echo " https://www.nuget.org/packages/Braintrust.Sdk.Anthropic/$VERSION"
echo " https://www.nuget.org/packages/Braintrust.Sdk.AgentFramework/$VERSION"
+ echo " https://www.nuget.org/packages/Braintrust.Sdk.AzureOpenAI/$VERSION"
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 8909c79..c256c7f 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -74,8 +74,10 @@
-
-
+
+
$(BraintrustSdkVersion)
$(BraintrustSdkVersion)
@@ -93,8 +95,9 @@
-
-
+
+
diff --git a/scripts/verify-release-config.sh b/scripts/verify-release-config.sh
new file mode 100755
index 0000000..c869015
--- /dev/null
+++ b/scripts/verify-release-config.sh
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+# Verifies that every packable project under src/ is properly registered in the
+# release workflow so that new packages cannot silently be omitted from releases.
+#
+# This script is run as part of CI. If it fails, it means a new project was added
+# to src/ but was not added to the release workflow.
+
+set -euo pipefail
+
+REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+RELEASE_WORKFLOW="$REPO_ROOT/.github/workflows/publish-release-from-tag.yml"
+SOLUTION_FILE="$REPO_ROOT/Braintrust.Sdk.sln"
+
+errors=0
+
+# Discover all packable src/ projects.
+# A project is packable unless it explicitly sets false.
+packable_projects=()
+for csproj in "$REPO_ROOT"/src/*/*.csproj; do
+ if grep -q 'false' "$csproj" 2>/dev/null; then
+ continue
+ fi
+ project_name="$(basename "$(dirname "$csproj")")"
+ packable_projects+=("$project_name")
+done
+
+if [[ ${#packable_projects[@]} -eq 0 ]]; then
+ echo "ERROR: No packable projects found under src/. Something is wrong."
+ exit 1
+fi
+
+echo "Found ${#packable_projects[@]} packable project(s) under src/:"
+for p in "${packable_projects[@]}"; do
+ echo " - $p"
+done
+echo ""
+
+# --- Check 1: Release workflow contains a 'dotnet pack' line for each project ---
+echo "Checking release workflow: $RELEASE_WORKFLOW"
+for project_name in "${packable_projects[@]}"; do
+ csproj_path="src/${project_name}/${project_name}.csproj"
+ if ! grep -q "$csproj_path" "$RELEASE_WORKFLOW"; then
+ echo "ERROR: $csproj_path is not referenced in the release workflow."
+ echo " Add a 'dotnet pack' command for it in $RELEASE_WORKFLOW"
+ errors=$((errors + 1))
+ else
+ echo " OK: $project_name found in release workflow"
+ fi
+done
+echo ""
+
+# --- Check 2: Each project is in the solution file ---
+echo "Checking solution file: $SOLUTION_FILE"
+for project_name in "${packable_projects[@]}"; do
+ if ! grep -q "$project_name" "$SOLUTION_FILE"; then
+ echo "ERROR: $project_name is not included in the solution file."
+ errors=$((errors + 1))
+ else
+ echo " OK: $project_name found in solution file"
+ fi
+done
+echo ""
+
+# --- Check 3: Verify the release workflow's NuGet publish step references each package ---
+# We look for the artifact output variable names in the publish step.
+# Each package should have a find command and a push reference.
+echo "Checking NuGet publish references in release workflow..."
+for project_name in "${packable_projects[@]}"; do
+ # The find-artifacts step should search for this package's .nupkg
+ if ! grep -q "${project_name}.*\.nupkg" "$RELEASE_WORKFLOW"; then
+ echo "ERROR: No artifact lookup for ${project_name} .nupkg in release workflow."
+ echo " Add it to the 'Find built artifacts' step."
+ errors=$((errors + 1))
+ else
+ echo " OK: ${project_name} .nupkg artifact lookup found"
+ fi
+done
+echo ""
+
+# --- Summary ---
+if [[ $errors -gt 0 ]]; then
+ echo "FAILED: Found $errors error(s). New src/ projects must be added to:"
+ echo " 1. The solution file (Braintrust.Sdk.sln)"
+ echo " 2. The release workflow (.github/workflows/publish-release-from-tag.yml):"
+ echo " - 'Pack NuGet packages' step (dotnet pack)"
+ echo " - 'Find built artifacts' step"
+ echo " - 'Create GitHub Release' step (upload)"
+ echo " - 'Publish to NuGet.org' step (dotnet nuget push)"
+ echo " - 'Wait for NuGet.org indexing' step (status URLs)"
+ exit 1
+else
+ echo "All $((${#packable_projects[@]})) packable projects are properly configured for release."
+fi