Build-Time Generation

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:

  • Creating OpenAPI documents that are committed to source control
  • Publishing OpenAPI documents to the Scalar Registry

Microsoft.AspNetCore.OpenApi

The Microsoft.AspNetCore.OpenApi package provides built-in support for generating OpenAPI documents at build time.

For complete details, see the Microsoft documentation.

Installation

Install the required package:

dotnet add package Microsoft.Extensions.ApiDescription.Server

Enable Build-Time Generation

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.

Change Output File Name

To generate the file as openapi.json, customize the generated file name:

<PropertyGroup>
  <OpenApiGenerateDocumentsOptions>--file-name openapi</OpenApiGenerateDocumentsOptions>
</PropertyGroup>

Change Output Directory

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.AspNetCore.SwaggerGen

Swashbuckle supports build-time OpenAPI generation using the Swashbuckle CLI tool.

For complete details, see the Swashbuckle documentation.

Installation

Create a tool manifest and install the CLI tool:

dotnet new tool-manifest
dotnet tool install Swashbuckle.AspNetCore.Cli

Enable Build-Time Generation

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" 
        ContinueOnError="false" 
        IgnoreExitCode="false" />
  <Message Text="OpenAPI document generated: ./openapi.json" Importance="high" />
</Target>

After adding this target, the OpenAPI document will be generated automatically when you build your project in Release configuration.

Publishing to Scalar Registry

Once you have generated your OpenAPI document at build time, you can easily publish it to the Scalar Registry as part of your CI/CD pipeline.

Using GitHub Actions

Create a workflow file .github/workflows/publish-openapi.yml:

name: Publish OpenAPI to Scalar Registry

on:
  push:
    branches: [main]

jobs:
  build-validate-publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - 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@v4
        with:
          node-version: 20

      - name: Validate OpenAPI Document
        run: |
          npx @scalar/cli document validate ./openapi.json

      - name: Publish to Scalar Registry
        run: |
          npx @scalar/cli auth login --token ${{ secrets.SCALAR_TOKEN }}
          npx @scalar/cli registry publish \
            --namespace ${{ vars.SCALAR_NAMESPACE }} \
            --slug ${{ vars.SCALAR_SLUG }} \
            ./openapi.json
        env:
          SCALAR_TOKEN: ${{ secrets.SCALAR_TOKEN }}

Using GitLab CI

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_TOKEN
    - 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

For more details on publishing to the registry, see our Scalar Registry Guide.