Skip to content
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
37 changes: 31 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ jobs:
run: dotnet tool restore

- name: Restore
run: dotnet restore ManagedCode.LlmTck.slnx
run: dotnet restore ManagedCode.LlmTestServer.slnx

- name: Format
run: dotnet format ManagedCode.LlmTck.slnx --verify-no-changes --no-restore
run: dotnet format ManagedCode.LlmTestServer.slnx --verify-no-changes --no-restore

- name: Build
run: dotnet build ManagedCode.LlmTck.slnx --configuration Release --no-restore
run: dotnet build ManagedCode.LlmTestServer.slnx --configuration Release --no-restore

- name: Test
run: bash scripts/coverage.sh
Expand All @@ -43,9 +43,6 @@ jobs:
- name: Verify installed NuGet consumer
run: python3 scripts/verify-package.py

- name: Verify release recovery
run: python3 scripts/test-release.py

- name: Upload verification evidence
if: always()
uses: actions/upload-artifact@v7.0.1
Expand All @@ -60,3 +57,31 @@ jobs:
with:
name: packages
path: artifacts/packages/*.nupkg

container-smoke:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7.0.0

- name: Setup .NET
uses: actions/setup-dotnet@v5.4.0
with:
dotnet-version: 10.0.x

- name: Publish SDK container to local daemon without registry push
run: >-
dotnet publish samples/ManagedCode.LlmTestServer.Service/ManagedCode.LlmTestServer.Service.csproj
--configuration Release --runtime linux-x64 --self-contained false
/t:PublishContainer -p:ContainerImageTag=ci -p:ContainerRuntimeIdentifier=linux-x64
-p:UseAppHost=false

- name: Verify actual container HTTP behavior
run: python3 scripts/verify-container.py --image managedcode/llm-test-server:ci

- name: Upload container verification evidence
if: always()
uses: actions/upload-artifact@v7.0.1
with:
name: container-verification
path: artifacts/container-verification
77 changes: 77 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Website

on:
pull_request:
branches: [main]
paths: ['site/**', '.github/workflows/pages.yml']
push:
branches: [main]
paths: ['site/**', '.github/workflows/pages.yml']
workflow_run:
workflows: [Release]
types: [completed]
branches: [main]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: pages-${{ github.ref }}
cancel-in-progress: false

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.0
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- uses: actions/setup-node@v7.1.0
with:
node-version: 24
cache: npm
cache-dependency-path: site/package-lock.json
- name: Install site tooling
run: npm ci --prefix site
- name: Validate HTML, CSS and JavaScript
run: npm run lint --prefix site
- name: Build static preview
run: npm run build --prefix site

deploy:
if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main'
needs: validate
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v7.0.0
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
# Select GitHub Actions as the repository Pages source before the first deployment.
- name: Require the verified release before publishing the landing page
env:
GH_TOKEN: ${{ github.token }}
run: |
version=$(python3 -c 'import xml.etree.ElementTree as e; print(e.parse("Directory.Build.props").findtext(".//Version"))')
gh release view "v$version" --json assets --jq '.assets[].name' | grep -qx 'nuget-published.txt'
- name: Configure GitHub Pages
id: pages
uses: actions/configure-pages@v6.0.0
- name: Build for canonical Pages URL
env:
PAGES_BASE_URL: ${{ steps.pages.outputs.base_url }}
run: python3 site/build.py --base-url "$PAGES_BASE_URL"
- name: Upload static website
uses: actions/upload-pages-artifact@v5.0.0
with:
path: site/dist
- name: Deploy website
id: deployment
uses: actions/deploy-pages@v5.0.1
76 changes: 60 additions & 16 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ concurrency:

jobs:
pack:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
Expand Down Expand Up @@ -53,15 +54,15 @@ jobs:

- name: Restore
if: ${{ steps.release.outputs.should_release == 'true' }}
run: dotnet restore ManagedCode.LlmTck.slnx
run: dotnet restore ManagedCode.LlmTestServer.slnx

- name: Format
if: ${{ steps.release.outputs.should_release == 'true' }}
run: dotnet format ManagedCode.LlmTck.slnx --verify-no-changes --no-restore
run: dotnet format ManagedCode.LlmTestServer.slnx --verify-no-changes --no-restore

- name: Build
if: ${{ steps.release.outputs.should_release == 'true' }}
run: dotnet build ManagedCode.LlmTck.slnx --configuration Release --no-restore
run: dotnet build ManagedCode.LlmTestServer.slnx --configuration Release --no-restore

- name: Test
if: ${{ steps.release.outputs.should_release == 'true' }}
Expand All @@ -75,10 +76,6 @@ jobs:
if: ${{ steps.release.outputs.should_release == 'true' }}
run: python3 scripts/verify-package.py

- name: Verify release recovery
if: ${{ steps.release.outputs.should_release == 'true' }}
run: python3 scripts/test-release.py

- name: Upload verification evidence
if: always()
uses: actions/upload-artifact@v7.0.1
Expand All @@ -88,21 +85,68 @@ jobs:
artifacts/coverage
artifacts/package-consumer

- name: Publish container image
- name: Publish and verify standalone SDK container locally
if: ${{ steps.release.outputs.should_release == 'true' }}
env:
IMAGE_TAG: ${{ steps.release.outputs.version }}
run: |
dotnet publish samples/ManagedCode.LlmTestServer.Service/ManagedCode.LlmTestServer.Service.csproj \
--configuration Release --runtime linux-x64 --self-contained false \
/t:PublishContainer -p:ContainerRuntimeIdentifier=linux-x64 \
-p:ContainerImageTag="$IMAGE_TAG" -p:UseAppHost=false
python3 scripts/verify-container.py --image "managedcode/llm-test-server:$IMAGE_TAG"

- name: Publish versioned multi-platform SDK container
if: ${{ steps.release.outputs.should_release == 'true' }}
env:
IMAGE_TAG: ${{ steps.release.outputs.version }}
GHCR_TOKEN: ${{ github.token }}
run: |
echo "${{ github.token }}" | docker login ghcr.io -u "$GITHUB_ACTOR" --password-stdin
docker build \
-f samples/ManagedCode.LlmTck.Service/Dockerfile \
-t "ghcr.io/managedcode/llm-tck:$IMAGE_TAG" \
.
docker push "ghcr.io/managedcode/llm-tck:$IMAGE_TAG"

- name: Publish packages and finalize release
printf '%s' "$GHCR_TOKEN" | docker login ghcr.io -u "$GITHUB_ACTOR" --password-stdin
dotnet publish samples/ManagedCode.LlmTestServer.Service/ManagedCode.LlmTestServer.Service.csproj \
--configuration Release --self-contained false /t:PublishContainer \
-p:ContainerRegistry=ghcr.io -p:ContainerImageTag="$IMAGE_TAG" \
-p:UseAppHost=false

- name: Verify anonymous public pull and actual container behavior
if: ${{ steps.release.outputs.should_release == 'true' }}
env:
IMAGE_TAG: ${{ steps.release.outputs.version }}
run: |
python3 scripts/verify-container.py \
--image "ghcr.io/managedcode/llm-test-server:$IMAGE_TAG" --anonymous-pull \
--require-platform linux/amd64 --require-platform linux/arm64 || {
echo "::error::Public container delivery failed. In the managedcode organization package settings for llm-test-server, set package visibility to Public, then rerun this release for the same version. packages:write and public repository visibility alone do not make a GHCR image public."
exit 1
}

- name: Upload container verification evidence
if: always()
uses: actions/upload-artifact@v7.0.1
with:
name: release-container-verification
path: artifacts/container-verification

- name: Publish packages and create release
if: ${{ steps.release.outputs.should_release == 'true' }}
env:
GH_TOKEN: ${{ github.token }}
TAG_NAME: ${{ steps.release.outputs.tag }}
run: bash scripts/release.sh publish

- name: Verify actual GitHub and NuGet publication
if: ${{ steps.release.outputs.should_release == 'true' }}
env:
GH_TOKEN: ${{ github.token }}
run: python3 scripts/verify-release.py

- name: Verify public installed NuGet consumer
if: ${{ steps.release.outputs.should_release == 'true' }}
run: python3 scripts/verify-package.py --public-feed

- name: Mark verified delivery complete
if: ${{ steps.release.outputs.should_release == 'true' }}
env:
GH_TOKEN: ${{ github.token }}
TAG_NAME: ${{ steps.release.outputs.tag }}
run: bash scripts/release.sh finalize
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ coverage.cobertura.xml
*.suo
*.swp
*.tmp

# Launch production materials remain local until owner approval.
/marketing/
.playwright-cli
Loading
Loading