diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml new file mode 100644 index 0000000..6601963 --- /dev/null +++ b/.github/workflows/publish-nuget.yml @@ -0,0 +1,111 @@ +name: Publish NuGet packages + +on: + push: + tags: + - "v*" + +permissions: + contents: read + +jobs: + build-and-publish: + runs-on: ubuntu-latest + environment: release + permissions: + contents: read + id-token: write + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Resolve package version + id: version + shell: bash + run: | + set -euo pipefail + version="${GITHUB_REF_NAME#v}" + if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$ ]]; then + echo "Tag '$GITHUB_REF_NAME' does not produce a valid package version." + exit 1 + fi + echo "version=$version" >> "$GITHUB_OUTPUT" + + - name: Restore + working-directory: MagicSettings + run: dotnet restore MagicSettings.sln + + - name: Build + working-directory: MagicSettings + run: dotnet build MagicSettings.sln --configuration Release --no-restore + + - name: Test + working-directory: MagicSettings + run: dotnet test MagicSettings.sln --configuration Release --no-build --logger "console;verbosity=normal" + + - name: Pack + working-directory: MagicSettings + run: >- + dotnet pack MagicSettings.sln + --configuration Release + --no-build + --output ../artifacts/packages + -p:PackageVersion=${{ steps.version.outputs.version }} + + - name: Validate package output + shell: bash + run: | + set -euo pipefail + version="${{ steps.version.outputs.version }}" + package_dir="artifacts/packages" + + test -f "$package_dir/MagicSettings.$version.nupkg" + test -f "$package_dir/MagicSettings.Server.$version.nupkg" + + if find "$package_dir" -maxdepth 1 -name 'MagicSettings.Share.*.nupkg' | grep -q .; then + echo "MagicSettings.Share must not be published as a standalone package." + exit 1 + fi + + package_count=$(find "$package_dir" -maxdepth 1 -name '*.nupkg' | wc -l) + if [[ "$package_count" -ne 2 ]]; then + echo "Expected exactly two .nupkg files, found $package_count." + find "$package_dir" -maxdepth 1 -type f -print + exit 1 + fi + + for package in \ + "$package_dir/MagicSettings.$version.nupkg" \ + "$package_dir/MagicSettings.Server.$version.nupkg"; do + if ! unzip -l "$package" | grep -q 'lib/net10.0/MagicSettings.Share.dll'; then + echo "$package does not contain lib/net10.0/MagicSettings.Share.dll." + exit 1 + fi + done + + - name: Upload package artifacts + uses: actions/upload-artifact@v4 + with: + name: nuget-packages-${{ steps.version.outputs.version }} + path: artifacts/packages/*.*nupkg + if-no-files-found: error + + - name: NuGet login + id: login + uses: NuGet/login@v1 + with: + user: ${{ secrets.NUGET_USER }} + + - name: Publish packages + shell: bash + run: >- + dotnet nuget push "artifacts/packages/*.nupkg" + --api-key "${{ steps.login.outputs.NUGET_API_KEY }}" + --source https://api.nuget.org/v3/index.json + --skip-duplicate diff --git a/MagicSettings/Directory.Build.props b/MagicSettings/Directory.Build.props index 4bd9c1a..4f01e4b 100644 --- a/MagicSettings/Directory.Build.props +++ b/MagicSettings/Directory.Build.props @@ -8,5 +8,20 @@ true $(NoWarn);1591 true + + magiccodingman + magiccodingman + https://github.com/magiccodingman/MagicSettings + git + Apache-2.0 + README.md + true + true + snupkg + true + + + + diff --git a/MagicSettings/Directory.Build.targets b/MagicSettings/Directory.Build.targets new file mode 100644 index 0000000..3274810 --- /dev/null +++ b/MagicSettings/Directory.Build.targets @@ -0,0 +1,18 @@ + + + $(TargetsForTfmSpecificBuildOutput);IncludeMagicSettingsShareInPackage + + + + + <_MagicSettingsShareAssembly Include="@(ReferenceCopyLocalPaths)" + Condition="'%(ReferenceCopyLocalPaths.Filename)' == 'MagicSettings.Share' and '%(ReferenceCopyLocalPaths.Extension)' == '.dll'" /> + + + + + + diff --git a/MagicSettings/MagicSettings.Server/MagicSettings.Server.csproj b/MagicSettings/MagicSettings.Server/MagicSettings.Server.csproj index a46af5e..5a6f3a8 100644 --- a/MagicSettings/MagicSettings.Server/MagicSettings.Server.csproj +++ b/MagicSettings/MagicSettings.Server/MagicSettings.Server.csproj @@ -1,10 +1,13 @@ + true MagicSettings.Server + MagicSettings Server Storage-agnostic server helpers for MagicSettings enrollment, synchronization, authorization, and proof verification. + configuration;settings;server;dotnet;control-plane - + diff --git a/MagicSettings/MagicSettings.Share/MagicSettings.Share.csproj b/MagicSettings/MagicSettings.Share/MagicSettings.Share.csproj index ecaa002..7ed9612 100644 --- a/MagicSettings/MagicSettings.Share/MagicSettings.Share.csproj +++ b/MagicSettings/MagicSettings.Share/MagicSettings.Share.csproj @@ -1,5 +1,6 @@ + false MagicSettings.Share Shared protocol, schema, and security contracts for MagicSettings clients and control-plane implementations. diff --git a/MagicSettings/MagicSettings/MagicSettings.csproj b/MagicSettings/MagicSettings/MagicSettings.csproj index 336d442..7c2f62c 100644 --- a/MagicSettings/MagicSettings/MagicSettings.csproj +++ b/MagicSettings/MagicSettings/MagicSettings.csproj @@ -1,10 +1,13 @@ + true MagicSettings + MagicSettings Strongly typed configuration with generation, reconciliation, migrations, live overrides, and client-owned control-plane integration. + configuration;settings;appsettings;dotnet;control-plane - +