diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e2b810dc2..8178c671b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -61,6 +61,15 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 # Fetch the full history + # Surfaced early, and before restore/build, so the version to release is visible even if + # something later in this (long) job fails. Cutting a release means creating a GitHub Release + # tagged with whatever this prints; release.yml then verifies the tag agrees with nbgv. + - name: Report computed version + run: | + dotnet tool install --global nbgv + $version = nbgv get-version --project src/StackExchange.Redis --variable NuGetPackageVersion + "### Computed package version: ``$version``" >> $env:GITHUB_STEP_SUMMARY + Write-Output "Computed package version: $version" # Restore is ~80s of the build step on a cold runner, and the package set changes rarely. # # Keep this immediately after checkout, and *before* the WSL/redis steps. The key globs the whole @@ -234,10 +243,3 @@ jobs: name: test-results-windows path: test-results/*.trx retention-days: 14 - # Package and upload to MyGet only on pushes to main/v3, not on PRs - - name: .NET Pack - if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/v3') - run: dotnet pack Build.csproj --no-build -c Release /p:PackageOutputPath=${env:GITHUB_WORKSPACE}\.nupkgs /p:CI=true - - name: Upload to MyGet - if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/v3') - run: dotnet nuget push ${env:GITHUB_WORKSPACE}\.nupkgs\*.nupkg -s https://www.myget.org/F/stackoverflow/api/v2/package -k ${{ secrets.MYGET_API_KEY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..fdfe1b514 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,79 @@ +# Publishes to nuget.org when a GitHub Release is published. +# +# Auth is NuGet Trusted Publishing (OIDC): no long-lived API key is stored anywhere. +# The one-time setup on nuget.org is: username menu -> Trusted Publishing -> add policy with +# Repository Owner: StackExchange / Repository: StackExchange.Redis / Workflow File: release.yml +# Environment: release +# plus a NUGET_USER repository secret holding the nuget.org profile name to publish as. +# +# Versioning note: Nerdbank.GitVersioning computes the version from version.json plus commit +# height - the tag name does not set it. Read the version to tag off the CI run's step summary +# ("Report computed version" in CI.yml) and create the release with that tag; the guard step +# below fails the run on any mismatch rather than publishing a package that disagrees with its +# release. +# +# Deliberately does not run tests: the commit being released already passed CI, and this job's +# only job is to reproduce that build byte-for-byte and push it. Also deliberately runs on Linux, +# not Windows: net461/net472 build fine against their reference assemblies without a Windows +# runtime, and nothing here executes test code. + +name: Release + +on: + release: + types: [published] + # dry run: everything except the tag check and the push, so the pipeline can be + # proven (and the packages inspected, via the run artifact) without cutting a release + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + environment: release + permissions: + id-token: write # for the OIDC exchange with nuget.org + contents: read + + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 # Fetch the full history (for versioning) + - name: Install .NET SDK + uses: actions/setup-dotnet@v5 + with: + dotnet-version: | + 8.0.x + 10.0.x + - name: Verify tag matches computed version + if: github.event_name == 'release' + run: | + dotnet tool install --global nbgv + computed=$(nbgv get-version --project src/StackExchange.Redis --variable NuGetPackageVersion) + tag="${{ github.event.release.tag_name }}" + tag="${tag#v}" + if [ "$computed" != "$tag" ]; then + echo "::error::Tag '$tag' does not match the computed version '$computed'; retag the release commit so the two agree." + exit 1 + fi + echo "Publishing $computed" + - name: Restore dependencies + run: dotnet restore Build.csproj + - name: Build + run: dotnet build Build.csproj --no-restore -c Release /p:CI=true + - name: Pack + run: dotnet pack Build.csproj --no-build -c Release /p:CI=true /p:PackageOutputPath=${{ github.workspace }}/.nupkgs + # The packages survive as a run artifact even if the push fails + - name: Upload packages + uses: actions/upload-artifact@v4 + with: + name: packages + path: .nupkgs/*.nupkg + - name: NuGet login (OIDC to temp API key) + if: github.event_name == 'release' + uses: NuGet/login@v1 + id: login + with: + user: ${{ secrets.NUGET_USER }} + - name: Push to nuget.org + if: github.event_name == 'release' + run: dotnet nuget push .nupkgs/*.nupkg --api-key ${{ steps.login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/README.md b/README.md index 1e7535701..5d2b6cc7e 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,8 @@ For all documentation, [see here](https://seredis.dev/). #### Package Status -MyGet Pre-release feed: https://www.myget.org/gallery/stackoverflow - -| Package | NuGet Stable | NuGet Pre-release | Downloads | MyGet | -| ------- | ------------ | ----------------- | --------- | ----- | -| [StackExchange.Redis](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis](https://img.shields.io/nuget/v/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis](https://img.shields.io/nuget/vpre/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/absoluteLatest) | [![StackExchange.Redis](https://img.shields.io/nuget/dt/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis MyGet](https://img.shields.io/myget/stackoverflow/vpre/StackExchange.Redis.svg)](https://www.myget.org/feed/stackoverflow/package/nuget/StackExchange.Redis) | +| Package | NuGet Stable | NuGet Pre-release | Downloads | +| ------- | ------------ | ----------------- | --------- | +| [StackExchange.Redis](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis](https://img.shields.io/nuget/v/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis](https://img.shields.io/nuget/vpre/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/absoluteLatest) | [![StackExchange.Redis](https://img.shields.io/nuget/dt/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | Release notes at: [GitHub Releases](https://github.com/StackExchange/StackExchange.Redis/releases) (3.0 onwards; [earlier releases](https://seredis.dev/ReleaseNotes)) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 678032414..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,84 +0,0 @@ -image: -- Visual Studio 2019 - -init: - - git config --global core.autocrlf input - -install: -- cmd: >- - choco install dotnet-9.0-sdk - - cd tests\RedisConfigs\3.0.503 - - redis-server.exe --service-install --service-name "redis-6379" "..\Basic\primary-6379-3.0.conf" - - redis-server.exe --service-install --service-name "redis-6380" "..\Basic\replica-6380.conf" - - redis-server.exe --service-install --service-name "redis-6381" "..\Basic\secure-6381.conf" - - redis-server.exe --service-install --service-name "redis-6382" "..\Failover\primary-6382.conf" - - redis-server.exe --service-install --service-name "redis-6383" "..\Failover\replica-6383.conf" - - redis-server.exe --service-install --service-name "redis-7000" "..\Cluster\cluster-7000.conf" --dir "..\Cluster" - - redis-server.exe --service-install --service-name "redis-7001" "..\Cluster\cluster-7001.conf" --dir "..\Cluster" - - redis-server.exe --service-install --service-name "redis-7002" "..\Cluster\cluster-7002.conf" --dir "..\Cluster" - - redis-server.exe --service-install --service-name "redis-7003" "..\Cluster\cluster-7003.conf" --dir "..\Cluster" - - redis-server.exe --service-install --service-name "redis-7004" "..\Cluster\cluster-7004.conf" --dir "..\Cluster" - - redis-server.exe --service-install --service-name "redis-7005" "..\Cluster\cluster-7005.conf" --dir "..\Cluster" - - redis-server.exe --service-install --service-name "redis-7010" "..\Sentinel\redis-7010.conf" - - redis-server.exe --service-install --service-name "redis-7011" "..\Sentinel\redis-7011.conf" - - redis-server.exe --service-install --service-name "redis-26379" "..\Sentinel\sentinel-26379.conf" --sentinel - - redis-server.exe --service-install --service-name "redis-26380" "..\Sentinel\sentinel-26380.conf" --sentinel - - redis-server.exe --service-install --service-name "redis-26381" "..\Sentinel\sentinel-26381.conf" --sentinel - - cd ..\..\.. -- ps: >- - if (Get-Command "Start-Service" -errorAction SilentlyContinue) { - Start-Service redis-* - } - -branches: - only: - - main - -skip_branch_with_pr: true -skip_tags: true -skip_commits: - files: - - '**/*.md' - - docs/* - -environment: - Appveyor: true - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - -nuget: - disable_publish_on_pr: true - -build_script: -- ps: .\build.ps1 -PullRequestNumber "$env:APPVEYOR_PULL_REQUEST_NUMBER" -CreatePackages ($env:OS -eq "Windows_NT") -NetCoreOnlyTests - -test: off -artifacts: -- path: .\.nupkgs\*.nupkg -- path: '**\*.trx' - -deploy: -- provider: NuGet - server: https://www.myget.org/F/stackoverflow/api/v2 - on: - branch: main - api_key: - secure: P/UHxq2DEs0GI1SoDXDesHjRVsSVgdywz5vmsnhFQQY5aJgO3kP+QfhwfhXz19Rw - symbol_server: https://www.myget.org/F/stackoverflow/symbols/api/v2/package \ No newline at end of file diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 500a416dd..6c435d6cb 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -2,9 +2,9 @@ Current package versions: -| NuGet Stable | NuGet Pre-release | MyGet | -| ------------ | ----------------- | ----- | -| [![StackExchange.Redis](https://img.shields.io/nuget/v/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis](https://img.shields.io/nuget/vpre/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis MyGet](https://img.shields.io/myget/stackoverflow/vpre/StackExchange.Redis.svg)](https://www.myget.org/feed/stackoverflow/package/nuget/StackExchange.Redis) | +| NuGet Stable | NuGet Pre-release | +| ------------ | ----------------- | +| [![StackExchange.Redis](https://img.shields.io/nuget/v/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | [![StackExchange.Redis](https://img.shields.io/nuget/vpre/StackExchange.Redis.svg)](https://www.nuget.org/packages/StackExchange.Redis/) | ## 3.0