documentation/integrations/aspnetcore/build-time-generation.md
This guide shows you how to generate OpenAPI documents during the build process for your ASP.NET Core application. Build-time generation is useful for:
The Microsoft.AspNetCore.OpenApi package provides built-in support for generating OpenAPI documents at build time.
For complete details, see the Microsoft documentation.
Install the required package:
dotnet add package Microsoft.Extensions.ApiDescription.Server
The Microsoft.Extensions.ApiDescription.Server package automatically generates OpenAPI documents during build. By default, the OpenAPI document will be generated in your project's output directory as {ProjectName}.json.
To generate the file as openapi.json, customize the generated file name:
<PropertyGroup>
<OpenApiGenerateDocumentsOptions>--file-name openapi</OpenApiGenerateDocumentsOptions>
</PropertyGroup>
Modify where the OpenAPI file is generated by setting the OpenApiDocumentsDirectory property:
<PropertyGroup>
<!-- Generate in project root directory instead of output directory -->
<OpenApiDocumentsDirectory>.</OpenApiDocumentsDirectory>
</PropertyGroup>
Swashbuckle supports build-time OpenAPI generation using the Swashbuckle CLI tool.
For complete details, see the Swashbuckle documentation.
Create a tool manifest and install the CLI tool:
dotnet new tool-manifest
dotnet tool install Swashbuckle.AspNetCore.Cli
Add the following target to your .csproj file to automatically generate the OpenAPI document during build:
<Target Name="GenerateOpenApiDocument" AfterTargets="Build" Condition="'$(Configuration)'=='Release'">
<Exec Command="dotnet swagger tofile --output ./openapi.json $(OutputPath)$(AssemblyName).dll v1" />
</Target>
After adding this target, the OpenAPI document will be generated automatically when you build your project in Release configuration.
Once you have generated your OpenAPI document at build time, you can easily publish it to the Registry as part of your CI/CD pipeline.
Create a workflow file .github/workflows/publish-openapi.yml:
# .github/workflows/publish-to-scalar-registry.yml
name: Publish OpenAPI to Registry
on:
push:
branches: [main]
jobs:
build-validate-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.x'
- name: Build and Generate OpenAPI
run: |
dotnet build --configuration Release
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
- name: Validate OpenAPI Document
run: |
npx @scalar/cli document validate ./openapi.json
- name: Publish to Registry
run: |
npx @scalar/cli auth login --token ${{ secrets.SCALAR_API_KEY }}
npx @scalar/cli registry publish \
--namespace ${{ vars.SCALAR_NAMESPACE }} \
--slug ${{ vars.SCALAR_SLUG }} \
./openapi.json
env:
SCALAR_API_KEY: ${{ secrets.SCALAR_API_KEY }}
Add this to your .gitlab-ci.yml:
stages:
- build
- validate
- deploy
build:
stage: build
image: mcr.microsoft.com/dotnet/sdk:8.0
script:
- dotnet build --configuration Release
artifacts:
paths:
- ./openapi.json
expire_in: 1 hour
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
validate_openapi:
stage: validate
image: node:20
script:
- npx @scalar/cli document validate ./openapi.json
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
needs:
- build
publish_to_scalar:
stage: deploy
image: node:20
script:
- npx @scalar/cli auth login --token $SCALAR_API_KEY
- npx @scalar/cli registry publish --namespace $SCALAR_NAMESPACE --slug $SCALAR_SLUG ./openapi.json
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
needs:
- build
- validate_openapi