Workflow refactoring and improvements (#273)

* Remove code coverage PR commenting

* Only run markdown-link-check when markdown files are updated

* Declare CI workflow permissions

* Refactor release workflow and declare permissions

* Pin all actions to SHAs

* Run CI manually, on all pushes to main, or if code changes in a PR

* NuGet publishing doesn't need any permissions
This commit is contained in:
Jeff Handley 2025-04-11 12:18:17 -07:00 • committed by GitHub
commit f1cc2d81de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 112 additions and 49 deletions

96
.github/workflows/ci-build-test.yml vendored Normal file
View file

@ -0,0 +1,96 @@
name: Build and Test
on:
# Manual trigger
workflow_dispatch:
# Run CI for all pushes to main
push:
branches: ["main"]
# Run CI for pull requests to all branches, but only if code changed
pull_request:
paths:
- ".github/workflows/ci-*.yml"
- "*.sln"
- "*.props"
- "Makefile"
- "src/**"
- "tests/**"
- "samples/**"
permissions:
contents: read
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
configuration: [Debug, Release]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- name: Clone the repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up .NET
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: |
9.0.x
8.0.x
# NetFX testing on non-Windows requires mono
- name: Setup Mono
if: runner.os == 'Linux'
run: sudo apt-get install -y mono-devel
- name: Set up Node.js
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: '20'
- name: Install dependencies for tests
run: npm install @modelcontextprotocol/server-everything
- name: Install dependencies for tests
run: npm install @modelcontextprotocol/server-memory
- name: Build
run: dotnet build --configuration ${{ matrix.configuration }}
- name: Pack
run: dotnet pack --configuration ${{ matrix.configuration }}
- name: Test
run: >-
dotnet test
--filter '(Execution!=Manual)'
--no-build
--configuration ${{ matrix.configuration }}
--logger "console;verbosity=normal"
--logger "trx"
--logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true"
--blame
--blame-hang-timeout 7m
--blame-crash
--results-directory testresults
--collect "XPlat Code Coverage" -- RunConfiguration.CollectSourceInformation=true
- name: Upload test results artifact
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: testresults-${{ matrix.os }}-${{ matrix.configuration }}
path: testresults/**
publish-coverage:
if: github.actor != 'dependabot[bot]'
needs: build
uses: ./.github/workflows/ci-code-coverage.yml
secrets: inherit

67
.github/workflows/ci-code-coverage.yml vendored Normal file
View file

@ -0,0 +1,67 @@
name: Code Coverage
on:
workflow_call:
permissions:
contents: read
jobs:
publish-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup .NET
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: |
9.0.x
8.0.x
- name: Download test results
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with:
pattern: testresults-*
- name: Combine coverage reports
uses: danielpalme/ReportGenerator-GitHub-Action@5.4.4
with:
reports: "**/*.cobertura.xml"
targetdir: "${{ github.workspace }}/report"
reporttypes: "HtmlSummary;Cobertura;MarkdownSummary;MarkdownSummaryGithub"
verbosity: "Info"
title: "Code Coverage"
tag: "${{ github.run_number }}_${{ github.run_id }}"
customSettings: ""
toolpath: "reportgeneratortool"
- name: Upload combined coverage XML
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coverage
path: ${{ github.workspace }}/report
retention-days: 7
- name: Publish code coverage report
uses: irongut/CodeCoverageSummary@51cc3a756ddcd398d447c044c02cb6aa83fdae95 # v1.3.0
with:
filename: "report/Cobertura.xml"
badge: true
fail_below_min: true
format: markdown
hide_branch_rate: false
hide_complexity: false
indicators: true
output: both
thresholds: "60 80"
- name: Upload combined coverage markdown
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coverage-markdown
path: ${{ github.workspace }}/code-coverage-results.md
retention-days: 7
- name: Coverage on step summary
if: always()
run: cat "${{ github.workspace }}/report/SummaryGithub.md" >> $GITHUB_STEP_SUMMARY

View file

@ -7,9 +7,9 @@ on:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
actions: read
contents: read
pages: write
id-token: write
id-token: write # Required for actions/deploy-pages
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
@ -27,10 +27,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: .NET Setup
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: 9.x
@ -38,10 +38,10 @@ jobs:
run: make generate-docs
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1
with:
path: 'artifacts/_site'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5

View file

@ -1,20 +1,25 @@
name: Check Markdown links
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
push:
branches: [ "main" ]
paths: "**.md"
pull_request:
branches: [ "main" ]
paths: "**.md"
permissions:
contents: read
jobs:
markdown-link-check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@main
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Markup Link Checker (mlc)
uses: becheran/mlc@v0.21.0
uses: becheran/mlc@c925f90a9a25e16e4c4bfa29058f6f9ffa9f0d8c # v0.21.0
with:
# Ignore external links that result in 403 errors during CI. Do not warn for redirects where we want to keep the vanity URL in the markdown or for GitHub links that redirect to the login.
args: --ignore-links "https://www.anthropic.com/*,https://hackerone.com/anthropic-vdp/*" --do-not-warn-for-redirect-to "https://modelcontextprotocol.io/*,https://github.com/login?*" ./

View file

@ -40,14 +40,17 @@ jobs:
runs-on: ${{ matrix.os }}
permissions:
contents: read
steps:
- name: Clone the repo
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up .NET
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: 9.0.x
@ -61,14 +64,17 @@ jobs:
runs-on: windows-latest
needs: build-all-configs
permissions:
contents: read
env:
version_suffix_args: ${{ github.event_name != 'release' && format('--version-suffix "{0}"', inputs.version_suffix_override || format('ci.{0}', github.run_number)) || '' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup .NET
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: |
9.0.x
@ -81,32 +87,29 @@ jobs:
--output "${{ github.workspace }}/artifacts/packages"
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: ${{ !cancelled() }}
with:
name: build-artifacts
path: ${{ github.workspace }}/artifacts
publish-package:
publish-github:
needs: build-package
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup .NET
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: 9.0.x
- name: Download build artifacts
uses: actions/download-artifact@v4
- name: Upload release asset
if: github.event_name == 'release'
run: gh release upload ${{ github.event.release.tag_name }}
${{ github.workspace }}/build-artifacts/packages/*.*nupkg
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- name: Authenticate to GitHub registry
run: dotnet nuget add source
@ -123,9 +126,52 @@ jobs:
--api-key ${{ secrets.GITHUB_TOKEN }}
--skip-duplicate
publish-release:
if: github.event_name == 'release'
needs: build-package
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup .NET
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: 9.0.x
- name: Download build artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- name: Upload release asset
run: gh release upload ${{ github.event.release.tag_name }}
${{ github.workspace }}/build-artifacts/packages/*.*nupkg
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-nuget:
# Only publish to NuGet.org from the modelcontextprotocol/csharp-sdk repository
if: ${{ github.event_name == 'release' && github.repository == 'modelcontextprotocol/csharp-sdk' }}
needs: build-package
runs-on: ubuntu-latest
permissions: { }
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup .NET
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: 9.0.x
- name: Download build artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- name: Publish to NuGet.org (Releases only)
# Only publish to NuGet.org from the modelcontextprotocol/csharp-sdk repository
if: ${{ github.event_name == 'release' && github.repository == 'modelcontextprotocol/csharp-sdk' }}
run: dotnet nuget push
${{github.workspace}}/build-artifacts/packages/*.nupkg
--source https://api.nuget.org/v3/index.json