Refactor storage managers and centralize logic #10
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish NuGet packages | |
| # Packs and publishes KitStack.* packages to nuget.org when a tag like v1.2.3 is pushed. | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| concurrency: | |
| group: publish-nuget-${{ github.ref_name }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| env: | |
| PACK_OUTPUT: ./nupkg | |
| jobs: | |
| build-pack-publish: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Cache NuGet packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Setup .NET SDK | |
| uses: actions/setup-dotnet@v3 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Restore | |
| run: dotnet restore | |
| - name: Build (produce portable PDBs) | |
| # Build all projects so pack --no-build can consume the exact outputs. | |
| run: dotnet build -c Release -p:DebugType=portable -p:DebugSymbols=true --no-restore | |
| - name: Extract version from tag | |
| id: vars | |
| run: | | |
| TAG="${GITHUB_REF##*/}" | |
| # Allow tags like v1.2.3 or 1.2.3 | |
| RAW="${TAG#v}" | |
| echo "version=${RAW}" >> $GITHUB_OUTPUT | |
| - name: Pack dependencies (nupkg + snupkg) | |
| run: | | |
| set -euo pipefail | |
| VERSION=${{ steps.vars.outputs.version }} | |
| mkdir -p $PACK_OUTPUT | |
| echo "Packing KitStack.Abstractions v$VERSION" | |
| dotnet pack src/KitStack.Abstractions/KitStack.Abstractions.csproj \ | |
| -c Release -o $PACK_OUTPUT --no-build \ | |
| /p:Version=$VERSION /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg | |
| echo "Packing KitStack.Storage.Local v$VERSION" | |
| dotnet pack src/KitStack.Storage.Local/KitStack.Storage.Local.csproj \ | |
| -c Release -o $PACK_OUTPUT --no-build \ | |
| /p:Version=$VERSION /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg | |
| echo "Packing KitStack.Storage.S3 v$VERSION" | |
| dotnet pack src/KitStack.Storage.S3/KitStack.Storage.S3.csproj \ | |
| -c Release -o $PACK_OUTPUT --no-build \ | |
| /p:Version=$VERSION /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg | |
| echo "Packing KitStack.Storage.Sftp v$VERSION" | |
| dotnet pack src/KitStack.Storage.Sftp/KitStack.Storage.Sftp.csproj \ | |
| -c Release -o $PACK_OUTPUT --no-build \ | |
| /p:Version=$VERSION /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg | |
| echo "Packing KitStack.Fakes v$VERSION" | |
| dotnet pack src/KitStack.Fakes/KitStack.Fakes.csproj \ | |
| -c Release -o $PACK_OUTPUT --no-build \ | |
| /p:Version=$VERSION /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg | |
| - name: Pack KitStack.AspNetCore (nupkg + snupkg) | |
| run: | | |
| set -euo pipefail | |
| VERSION=${{ steps.vars.outputs.version }} | |
| mkdir -p $PACK_OUTPUT | |
| echo "Packing KitStack.AspNetCore v$VERSION" | |
| dotnet pack src/KitStack.AspNetCore/KitStack.AspNetCore.csproj \ | |
| -c Release -o $PACK_OUTPUT --no-build \ | |
| /p:Version=$VERSION /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg | |
| - name: List produced packages | |
| run: ls -la $PACK_OUTPUT || true | |
| - name: Validate nupkg/snupkg pairs (basic DLL <-> PDB match) | |
| run: | | |
| set -euo pipefail | |
| PACK_DIR=$PACK_OUTPUT | |
| echo "Validating nupkg/snupkg pairs in $PACK_DIR" | |
| # For each nupkg, check if a corresponding snupkg exists and ensure that every DLL base-name in nupkg has a matching PDB in snupkg | |
| for n in "$PACK_DIR"/*.nupkg; do | |
| [ -f "$n" ] || continue | |
| base=$(basename "$n" .nupkg) | |
| sn="$PACK_DIR/$base.snupkg" | |
| if [ -f "$sn" ]; then | |
| echo "Validating $base.nupkg <-> $base.snupkg" | |
| # list dll base-names in nupkg under lib/ | |
| dlls=$(unzip -l "$n" | awk '{print $4}' | grep -E '^lib/.*\.dll$' | xargs -n1 basename | sed 's/\.dll$//' | sort -u || true) | |
| # list pdb base-names in snupkg | |
| pdbs=$(unzip -l "$sn" | awk '{print $4}' | grep -E '\.pdb$' | xargs -n1 basename | sed 's/\.pdb$//' | sort -u || true) | |
| missing="" | |
| for d in $dlls; do | |
| if ! echo "$pdbs" | grep -qx "$d"; then | |
| missing="$missing $d" | |
| fi | |
| done | |
| if [ -n "$missing" ]; then | |
| echo "ERROR: symbol mismatch for $base: PDBs missing for:$missing" | |
| echo "Contents of $n:" | |
| unzip -l "$n" | |
| echo "Contents of $sn:" | |
| unzip -l "$sn" | |
| exit 1 | |
| else | |
| echo "OK: $base contains matching DLLs and PDBs." | |
| fi | |
| else | |
| echo "No symbol package produced for $base (skipping symbol validation)." | |
| fi | |
| done | |
| - name: Publish to NuGet (push all nupkg + snupkg) | |
| env: | |
| NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${NUGET_API_KEY:-}" ]; then | |
| echo "NUGET_API_KEY secret is not set. Skipping publish." | |
| exit 78 | |
| fi | |
| echo "Pushing packages in $PACK_OUTPUT to nuget.org" | |
| for pkg in $PACK_OUTPUT/*.nupkg; do | |
| # skip legacy .symbols.nupkg if present | |
| if [[ "$pkg" == *".symbols.nupkg" ]]; then | |
| continue | |
| fi | |
| echo "Pushing $pkg" | |
| dotnet nuget push "$pkg" -k "$NUGET_API_KEY" -s https://api.nuget.org/v3/index.json --skip-duplicate | |
| done | |
| # push any snupkg symbol packages | |
| for sym in $PACK_OUTPUT/*.snupkg; do | |
| [ -f "$sym" ] || continue | |
| echo "Pushing symbol package $sym" | |
| dotnet nuget push "$sym" -k "$NUGET_API_KEY" -s https://api.nuget.org/v3/index.json --skip-duplicate | |
| done | |
| - name: Upload built packages as workflow artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: kitstack-packages-${{ github.ref_name }} | |
| path: ${{ env.PACK_OUTPUT }} |