diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..0abb1c5
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,78 @@
+name: Build
+run-name: >-
+ ${{ github.event_name == 'pull_request' && format('Checking that #{0} builds', github.event.pull_request.number)
+ || format('Building {0}', github.ref_name) }}
+
+# Trunk-based: main is the only long-lived branch. Every pull request and every push to main builds the
+# whole solution (the library and all Examples) and packs the library, but nothing is published here:
+# this is a public NuGet package, and NuGet versions are permanent, so a release is a deliberate act -
+# publishing a GitHub Release v{semver}, which runs publish.yml. There is no test suite, so a clean build
+# and pack is the check that gates the merge (the required status check is this job's name, `build`).
+on:
+ pull_request:
+ branches: [main]
+ push:
+ branches: [main]
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ name: build
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ concurrency:
+ # A newer push to the same pull request cancels the older build; builds of main never cancel each other.
+ group: build-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.run_id }}
+ cancel-in-progress: true
+ steps:
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ persist-credentials: false
+
+ - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
+ with:
+ global-json-file: global.json
+
+ # The csproj turns high and critical NuGet advisories (NU1903/NU1904), direct or transitive, into
+ # errors, so a vulnerable dependency fails this step rather than reaching a release.
+ - name: Restore
+ run: dotnet restore ConvertApi.sln
+
+ - name: Build the library and the examples
+ run: dotnet build ConvertApi.sln -c Release --no-restore -p:ContinuousIntegrationBuild=true
+
+ # A pre-release version that sorts below any real release and names the run, so a package
+ # downloaded from this run can be tried out but never mistaken for a published one.
+ - name: Pack
+ id: pack
+ env:
+ RUN: ${{ github.run_number }}
+ SHORT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
+ run: |
+ set -euo pipefail
+ VERSION="0.0.0-ci.$RUN.g${SHORT_SHA:0:7}"
+ dotnet pack ConvertApi/ConvertApi.csproj -c Release --no-build -o out \
+ -p:Version="$VERSION" -p:ContinuousIntegrationBuild=true
+ test -f "out/ConvertApi.$VERSION.nupkg"
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: ConvertApi-${{ steps.pack.outputs.version }}
+ path: out/
+ retention-days: 14
+ if-no-files-found: error
+
+ - name: Summary
+ env:
+ VERSION: ${{ steps.pack.outputs.version }}
+ run: |
+ {
+ echo "| | |"
+ echo "|---|---|"
+ echo "| Package | \`ConvertApi $VERSION\` (artifact only, not published) |"
+ echo "| Dependencies | $(unzip -p "out/ConvertApi.$VERSION.nupkg" ConvertApi.nuspec | grep -o 'dependency id="[^"]*" version="[^"]*"' | sort -u | sed 's/dependency id="\([^"]*\)" version="\([^"]*\)"/\1 \2/' | paste -sd ',' - | sed 's/,/, /g') |"
+ } >> "$GITHUB_STEP_SUMMARY"
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..44c40b4
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,209 @@
+name: Publish
+run-name: Publishing ConvertApi ${{ github.event.release.tag_name }} to nuget.org
+
+# A release is a GitHub Release, never a merge. Merging to main only builds (build.yml); publishing the
+# Release v{semver} runs this file, which packs that tag's commit with the tag's version and pushes it to
+# nuget.org. NuGet versions are public and permanent - a pushed version can be unlisted but never
+# replaced - so nothing here retries, overwrites or skips a duplicate.
+#
+# gh release create v3.1.19 --target main --generate-notes -> ConvertApi 3.1.19
+# gh release create v3.2.0-preview.1 --target main --prerelease ... -> ConvertApi 3.2.0-preview.1
+#
+# A stable version must be a commit on main. A pre-release may be any commit, so a branch can be tried
+# out as a preview package before it is merged.
+on:
+ release:
+ types: [published]
+
+permissions:
+ contents: read
+
+env:
+ # Only this account may publish a Release that reaches nuget.org. GitHub cannot express this as a
+ # permission on the Team plan, so it is checked here; the real controls are the v* tag ruleset (only
+ # repository admins create v* tags) and the nuget environment, which accepts only v* tags.
+ PUBLISHER: tomasr78
+ PACKAGE_ID: ConvertApi
+
+jobs:
+ publish:
+ name: publish
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+ environment:
+ name: nuget
+ url: https://www.nuget.org/packages/ConvertApi/${{ steps.tag.outputs.version }}
+ concurrency:
+ group: publish-nuget
+ cancel-in-progress: false
+ permissions:
+ contents: read
+ # Only for nuget.org Trusted Publishing (NuGet/login below), which trades this run's OIDC token for
+ # a short-lived API key. Unused while the repository still publishes with the NUGET_API_KEY secret.
+ id-token: write
+ steps:
+ - name: Check who published the release
+ run: |
+ # A re-run keeps GITHUB_ACTOR as the original user; GITHUB_TRIGGERING_ACTOR is whoever pressed
+ # "Re-run", so both must be the publisher or anyone with write access could replay a release.
+ if [ "$GITHUB_ACTOR" != "$PUBLISHER" ] || [ "${GITHUB_TRIGGERING_ACTOR:-$GITHUB_ACTOR}" != "$PUBLISHER" ]; then
+ echo "::error::Only $PUBLISHER may publish to nuget.org - this release was published by $GITHUB_ACTOR and run by ${GITHUB_TRIGGERING_ACTOR:-$GITHUB_ACTOR}."
+ exit 1
+ fi
+ echo "Published by $GITHUB_ACTOR"
+
+ # The release event runs this file from the tag, so the workflow and the code come from the same commit.
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ fetch-depth: 0
+ persist-credentials: false
+
+ - name: Check the tag and the version
+ id: tag
+ env:
+ TAG: ${{ github.event.release.tag_name }}
+ PRERELEASE: ${{ github.event.release.prerelease }}
+ run: |
+ set -euo pipefail
+ # SemVer 2.0 without build metadata (nuget.org ignores "+..." and it would only confuse).
+ SEMVER='^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$'
+ if ! [[ "$TAG" =~ $SEMVER ]]; then
+ echo "::error::Tag '$TAG' is not v{major}.{minor}.{patch} or v{major}.{minor}.{patch}-{pre-release}, e.g. v3.1.19 or v3.2.0-preview.1"
+ exit 1
+ fi
+ if [ "$GITHUB_REF" != "refs/tags/$TAG" ]; then
+ echo "::error::The run is on $GITHUB_REF, not on the release tag refs/tags/$TAG"
+ exit 1
+ fi
+ VERSION="${TAG#v}"
+ SHA=$(git rev-parse "refs/tags/$TAG^{commit}")
+ if [ "$(git rev-parse HEAD)" != "$SHA" ]; then
+ echo "::error::Checked out $(git rev-parse HEAD), but $TAG points at $SHA"
+ exit 1
+ fi
+
+ # The GitHub "pre-release" tick and the version must agree, so a preview cannot become the
+ # package's latest stable version by a forgotten tick, and a stable version cannot hide as a pre-release.
+ if [[ "$VERSION" == *-* ]]; then
+ if [ "$PRERELEASE" != true ]; then
+ echo "::error::$TAG is a pre-release version, so the GitHub Release must be marked as a pre-release (gh release create --prerelease)"
+ exit 1
+ fi
+ else
+ if [ "$PRERELEASE" = true ]; then
+ echo "::error::$TAG is a stable version, but the GitHub Release is marked as a pre-release. Use a pre-release version such as ${TAG}-preview.1, or untick pre-release."
+ exit 1
+ fi
+ if ! git merge-base --is-ancestor "$SHA" origin/main; then
+ echo "::error::$TAG ($SHA) is not on main. Stable versions are released from main only; release a branch as a pre-release instead."
+ exit 1
+ fi
+ fi
+
+ # nuget.org lists every version ever pushed, unlisted ones included, in lower case.
+ INDEX=$(curl -fsS --retry 3 "https://api.nuget.org/v3-flatcontainer/${PACKAGE_ID,,}/index.json")
+ if jq -e --arg v "${VERSION,,}" '.versions | index($v)' <<<"$INDEX" >/dev/null; then
+ echo "::error::$PACKAGE_ID $VERSION already exists on nuget.org and can never be pushed again. Release the next version instead."
+ exit 1
+ fi
+ if [[ "$VERSION" != *-* ]]; then
+ LATEST=$(jq -r '[.versions[] | select(contains("-") | not)] | last // empty' <<<"$INDEX")
+ if [ -n "$LATEST" ] && [ "$(printf '%s\n%s\n' "$LATEST" "$VERSION" | sort -V | tail -n1)" != "$VERSION" ]; then
+ echo "::warning::$VERSION is lower than the latest stable $LATEST, so it will not become the version that new installs get."
+ fi
+ fi
+
+ {
+ echo "version=$VERSION"
+ echo "sha=$SHA"
+ } >> "$GITHUB_OUTPUT"
+ echo "Publishing $PACKAGE_ID $VERSION from $SHA"
+
+ - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
+ with:
+ global-json-file: global.json
+
+ # The csproj fails the restore on any high or critical advisory in the dependency graph, so a
+ # vulnerable dependency cannot be published.
+ - name: Restore
+ run: dotnet restore ConvertApi/ConvertApi.csproj
+
+ - name: Build and pack
+ env:
+ VERSION: ${{ steps.tag.outputs.version }}
+ run: |
+ set -euo pipefail
+ dotnet build ConvertApi/ConvertApi.csproj -c Release --no-restore \
+ -p:Version="$VERSION" -p:ContinuousIntegrationBuild=true
+ dotnet pack ConvertApi/ConvertApi.csproj -c Release --no-build -o out \
+ -p:Version="$VERSION" -p:ContinuousIntegrationBuild=true
+ ls -l out
+
+ - name: Check the package
+ env:
+ VERSION: ${{ steps.tag.outputs.version }}
+ SHA: ${{ steps.tag.outputs.sha }}
+ run: |
+ set -euo pipefail
+ PKG="out/$PACKAGE_ID.$VERSION.nupkg"
+ test -f "$PKG" && test -f "out/$PACKAGE_ID.$VERSION.snupkg"
+ NUSPEC=$(unzip -p "$PKG" "$PACKAGE_ID.nuspec")
+ grep -q "$VERSION" <<<"$NUSPEC" || { echo "::error::$PKG does not carry version $VERSION"; exit 1; }
+ grep -q "commit=\"$SHA\"" <<<"$NUSPEC" || { echo "::error::$PKG does not record commit $SHA"; exit 1; }
+ echo "$NUSPEC" | grep -E '<(id|version|repository|dependency) '
+
+ # Trusted Publishing: once a nuget.org policy for this repository, publish.yml and the nuget
+ # environment exists, setting the repository variable NUGET_USER (the nuget.org profile name that
+ # owns the policy) switches publishing to a short-lived key, and NUGET_API_KEY can be deleted.
+ - name: Log in to nuget.org (Trusted Publishing)
+ id: login
+ if: vars.NUGET_USER != ''
+ uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0
+ with:
+ user: ${{ vars.NUGET_USER }}
+
+ # No --skip-duplicate: a version that already exists must fail loudly, never pass as published.
+ # The .snupkg next to the .nupkg is pushed to the symbol server by the same command.
+ - name: Push to nuget.org
+ env:
+ VERSION: ${{ steps.tag.outputs.version }}
+ NUGET_API_KEY: ${{ steps.login.outputs.NUGET_API_KEY || secrets.NUGET_API_KEY }}
+ run: |
+ set -euo pipefail
+ if [ -z "$NUGET_API_KEY" ]; then
+ echo "::error::No nuget.org key: set up Trusted Publishing (NUGET_USER) or the NUGET_API_KEY secret"
+ exit 1
+ fi
+ dotnet nuget push "out/$PACKAGE_ID.$VERSION.nupkg" \
+ --api-key "$NUGET_API_KEY" --source https://api.nuget.org/v3/index.json
+
+ # nuget.org validates and indexes a push before anyone can restore it, usually within minutes. A slow
+ # index is not a failed release, so this only warns.
+ - name: Wait for nuget.org to serve the package
+ env:
+ VERSION: ${{ steps.tag.outputs.version }}
+ run: |
+ set -uo pipefail
+ for _ in $(seq 1 40); do
+ if curl -fsS "https://api.nuget.org/v3-flatcontainer/${PACKAGE_ID,,}/index.json" \
+ | jq -e --arg v "${VERSION,,}" '.versions | index($v)' >/dev/null; then
+ echo "$PACKAGE_ID $VERSION is available on nuget.org"
+ exit 0
+ fi
+ sleep 30
+ done
+ echo "::warning::$PACKAGE_ID $VERSION was pushed but nuget.org has not served it after 20 minutes. Check https://www.nuget.org/packages/$PACKAGE_ID/$VERSION"
+
+ - name: Summary
+ env:
+ VERSION: ${{ steps.tag.outputs.version }}
+ SHA: ${{ steps.tag.outputs.sha }}
+ AUTH: ${{ steps.login.outcome == 'success' && 'Trusted Publishing' || 'NUGET_API_KEY secret' }}
+ run: |
+ {
+ echo "| | |"
+ echo "|---|---|"
+ echo "| Package | [\`$PACKAGE_ID $VERSION\`](https://www.nuget.org/packages/$PACKAGE_ID/$VERSION) |"
+ echo "| Commit | \`$SHA\` |"
+ echo "| Published with | $AUTH |"
+ } >> "$GITHUB_STEP_SUMMARY"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index d5dc367..0000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Release to NuGet
-
-on:
- push:
- tags:
- - 'v*'
-
-jobs:
- build:
- runs-on: ubuntu-latest
- timeout-minutes: 5
- steps:
- - name: Checkout
- uses: actions/checkout@master
- with:
- ref: ${{ github.ref }}
- - name: Setup .NET SDK
- uses: actions/setup-dotnet@v1
- - name: Build
- run: dotnet build ConvertApi -c Release
- - name: Pack nugets
- run: dotnet pack ConvertApi -c Release --no-build --property:PackageOutputPath=.
- - name: Push to NuGet
- run: dotnet nuget push "./ConvertApi/*.nupkg" --api-key ${{secrets.NUGET_API_KEY}} --source https://api.nuget.org/v3/index.json --skip-duplicate
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a43473..4291536 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
+## [3.1.19] — 2026-10-16
+
+### Security
+- Bump `Microsoft.OpenApi.Readers` 1.6.23 → 1.6.31, fixing the high-severity YAML alias-expansion
+ denial of service [GHSA-7pxr-59rr-hqj2](https://github.com/advisories/GHSA-7pxr-59rr-hqj2)
+ (patched in 1.6.30). No API change: the converter catalog returns the same converters and tags.
+
+### Changed
+- Releases are now cut from a GitHub Release `v{version}`; the package version comes from the tag.
+ The build now fails on any high or critical advisory in the dependency graph.
+- Package metadata: repository URL points to `convertapi-library-dotnet`, the description no longer
+ names specific .NET versions, release notes link to GitHub Releases, and a symbol package (`.snupkg`)
+ is published alongside.
+
## [3.1.15-dev] — 2026-05-14
### Added
diff --git a/ConvertApi/ConvertApi.csproj b/ConvertApi/ConvertApi.csproj
index bcc2116..c39aa35 100644
--- a/ConvertApi/ConvertApi.csproj
+++ b/ConvertApi/ConvertApi.csproj
@@ -1,15 +1,16 @@
- true
- 3.1.18
+
+ 0.0.0-local
ConvertApi
ConvertApi
https://www.convertapi.com
- https://github.com/ConvertAPI/convertapi-dotnet
- GIT
+ https://github.com/ConvertAPI/convertapi-library-dotnet
+ git
file-converter document-converter office-to-pdf office2pdf docx-to-pdf docx2pdf xlsx-to-pdf xlsx2pdf pptx-to-pdf ppt2pdf pdf-merge pdf-split pdf-compress pdf-watermark prdf-extract pdf2extract pdf-protect pdfa ocr redact html-to-pdf web-to-pdf image-to-pdf jpg-to-pdf png-to-pdf email-to-pdf eml-to-pdf msg-to-pdf convertapi pdf docx xlsx pptx office converter csharp dotnet sdk
- 2012-2025 ConvertApi
+ 2012-2026 ConvertApi
https://www.convertapi.com/terms
https://www.convertapi.com/favicon/android-chrome-192x192.png
README.md
@@ -17,17 +18,21 @@
ConvertApi
ConvertApi
ConvertApiDotNet
- 3.1.18.0
- 3.1.18.0
- Development snapshot (-dev prerelease). Changelog will evolve during the development cycle.
+ https://github.com/ConvertAPI/convertapi-library-dotnet/releases
netstandard2.0;netcoreapp3.1
- 3.1.18
- ConvertAPI for .NET — one call to turn Office files into PDF or back again (DOCX ⇄ PDF, XLSX ⇄ PDF, PPTX ⇄ PDF). Convert HTML, images, ebooks, email, zip; merge, split, watermark, compress, OCR, redact, protect or repair PDF. Async, cross-platform, .NET Standard 2.0+ / .NET Core 5-9
+ ConvertAPI for .NET — one call to turn Office files into PDF or back again (DOCX ⇄ PDF, XLSX ⇄ PDF, PPTX ⇄ PDF). Convert HTML, images, ebooks, email, zip; merge, split, watermark, compress, OCR, redact, protect or repair PDF. Async and cross-platform: targets .NET Standard 2.0, so it runs on .NET Framework 4.6.2+ and every modern .NET.
+ true
+ snupkg
+
+ true
+ all
+ $(WarningsAsErrors);NU1903;NU1904
-
+
diff --git a/ConvertApi/docs/README.md b/ConvertApi/docs/README.md
index 0fa1ab0..d3286d2 100644
--- a/ConvertApi/docs/README.md
+++ b/ConvertApi/docs/README.md
@@ -462,7 +462,7 @@ int conversionsConsumed = user.ConversionsConsumed;
### More examples
-You can find more advanced examples in the [examples](https://github.com/ConvertAPI/convertapi-dotnet/tree/master/Examples) folder.
+You can find more advanced examples in the [examples](https://github.com/ConvertAPI/convertapi-library-dotnet/tree/main/Examples) folder.
#### Converting your first file, complete example:
@@ -492,4 +492,4 @@ catch (ConvertApiException e)
Please leave all comments, bugs, requests, and issues on the Issues page. We'll respond to your request ASAP!
### License
-The ConvertAPI .NET Library is licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php "Read more about the MIT license form") license. Refere to the [LICENSE](https://github.com/ConvertAPI/convertapi-dotnet/blob/master/LICENSE) file for more information.
+The ConvertAPI .NET Library is licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php "Read more about the MIT license form") license. Refere to the [LICENSE](https://github.com/ConvertAPI/convertapi-library-dotnet/blob/main/LICENSE) file for more information.
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index dabdc70..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic
-ARG NUGET_KEY
-WORKDIR /src
-COPY . .
-RUN dotnet build ConvertApi
-RUN dotnet pack --output . ConvertApi
-RUN dotnet nuget push ConvertApi.*.nupkg --api-key="$NUGET_KEY" --source="https://api.nuget.org/v3/index.json" --skip-duplicate
\ No newline at end of file
diff --git a/README.md b/README.md
index 2854cb1..06f3d77 100644
--- a/README.md
+++ b/README.md
@@ -455,7 +455,7 @@ int conversionsConsumed = user.ConversionsConsumed;
### More examples
-You can find more advanced examples in the [examples](https://github.com/ConvertAPI/convertapi-dotnet/tree/master/Examples) folder.
+You can find more advanced examples in the [examples](https://github.com/ConvertAPI/convertapi-library-dotnet/tree/main/Examples) folder.
#### Converting your first file, complete example:
@@ -485,4 +485,4 @@ catch (ConvertApiException e)
Please leave all comments, bugs, requests, and issues on the Issues page. We'll respond to your request ASAP!
### License
-The ConvertAPI .NET Library is licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php "Read more about the MIT license form") license. Refere to the [LICENSE](https://github.com/ConvertAPI/convertapi-dotnet/blob/master/LICENSE) file for more information.
+The ConvertAPI .NET Library is licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php "Read more about the MIT license form") license. Refere to the [LICENSE](https://github.com/ConvertAPI/convertapi-library-dotnet/blob/main/LICENSE) file for more information.
diff --git a/RELEASING.md b/RELEASING.md
new file mode 100644
index 0000000..e73c592
--- /dev/null
+++ b/RELEASING.md
@@ -0,0 +1,33 @@
+# Releasing
+
+`main` is the only long-lived branch. Changes reach it through pull requests, merge commits only, and
+every pull request and push to `main` must pass the `build` check (`.github/workflows/build.yml`: restore,
+build the library and every example, pack). Merging publishes nothing.
+
+A release is a **GitHub Release** whose tag is the version, published by `tomasr78`:
+
+```bash
+gh release create v3.1.19 --repo ConvertAPI/convertapi-library-dotnet --target main --title v3.1.19 --generate-notes
+```
+
+That runs `.github/workflows/publish.yml` in the `nuget` environment, which:
+
+1. refuses a Release published or re-run by anyone else;
+2. checks the tag is SemVer (`v3.1.19`, `v3.2.0-preview.1`), that the GitHub pre-release tick matches
+ the version, that a stable version is a commit on `main`, and that nuget.org has never had that version;
+3. builds and packs that commit with `-p:Version={tag without v}`, failing on any high or critical
+ advisory in the dependency graph;
+4. pushes `ConvertApi.{version}.nupkg` and its `.snupkg` to nuget.org and waits until nuget.org serves it.
+
+**Pre-releases** work the same way and may come from any branch:
+
+```bash
+gh release create v3.2.0-preview.1 --repo ConvertAPI/convertapi-library-dotnet --target my-branch --prerelease --title v3.2.0-preview.1 --notes "Preview of ..."
+```
+
+nuget.org versions are permanent. A bad version can only be unlisted (and, if needed, deprecated) on
+nuget.org, then fixed by releasing the next version. Never delete and re-create a release tag.
+
+The version in `ConvertApi.csproj` is a `0.0.0-local` placeholder; pull request builds pack
+`0.0.0-ci.{run}.g{sha}` as a downloadable artifact so a change can be tried before it is released.
+Update `CHANGELOG.md` in the pull request that changes behaviour.
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..3dbe096
--- /dev/null
+++ b/global.json
@@ -0,0 +1,7 @@
+{
+ "sdk": {
+ "version": "10.0.400",
+ "rollForward": "latestPatch",
+ "allowPrerelease": false
+ }
+}