🧹 Simplify repository structure by consolidating deployment directories #84
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: .NET Build and Test | |
| permissions: | |
| contents: write | |
| checks: write | |
| pull-requests: write | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| tags: [ 'v*' ] # Trigger on version tags | |
| pull_request: | |
| branches: [ main, develop ] | |
| env: | |
| DOTNET_VERSION: '9.0.x' | |
| DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true | |
| DOTNET_NOLOGO: true | |
| DOTNET_CLI_TELEMETRY_OPTOUT: true | |
| CI: true | |
| jobs: | |
| # Check if we should skip build for markdown-only changes | |
| check-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should-skip: ${{ steps.skip-check.outputs.should-skip }} | |
| paths-result: ${{ steps.skip-check.outputs.paths-result }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check for non-markdown changes | |
| id: skip-check | |
| uses: fkirc/skip-duplicate-actions@v5 | |
| with: | |
| # Skip if only markdown files changed | |
| paths_ignore: '["**/*.md", "doc/**", "**/README*", "**/CHANGELOG*", "**/LICENSE*"]' | |
| # Don't skip on main branch or tags | |
| skip_after_successful_duplicate: 'false' | |
| # Simple job for markdown-only changes | |
| markdown-check: | |
| runs-on: ubuntu-latest | |
| needs: check-changes | |
| if: needs.check-changes.outputs.should-skip == 'true' | |
| steps: | |
| - name: Documentation changes only | |
| run: | | |
| echo "✅ Only documentation files were changed - skipping build" | |
| echo "📝 Changes detected in markdown files only" | |
| build: | |
| runs-on: ubuntu-latest | |
| needs: check-changes | |
| if: needs.check-changes.outputs.should-skip != 'true' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Shallow clones should be disabled for better analysis | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Display .NET info | |
| run: dotnet --info | |
| - name: Cache NuGet packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Build solution | |
| run: dotnet build --configuration Release --no-restore --verbosity minimal | |
| - name: Test solution | |
| run: | | |
| # Check if there are any test projects in the solution | |
| TEST_PROJECTS=$(find tests -name "*.csproj" -exec grep -l "Microsoft.NET.Test.Sdk\|xunit\|NUnit\|MSTest" {} \; 2>/dev/null || true) | |
| if [ -n "$TEST_PROJECTS" ]; then | |
| echo "Found test projects, running tests..." | |
| dotnet test --configuration Release --no-build --verbosity minimal --logger "trx;LogFileName=test-results-Release.trx" --results-directory TestResults/ | |
| else | |
| echo "No test projects found - skipping tests" | |
| mkdir -p TestResults | |
| echo "##[warning]No test projects found" | |
| fi | |
| continue-on-error: false | |
| - name: Publish test results | |
| uses: dorny/test-reporter@v2 | |
| if: success() || failure() | |
| with: | |
| name: Test Results (Release) | |
| path: TestResults/*.trx | |
| reporter: dotnet-trx | |
| fail-on-error: false | |
| fail-on-empty: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-artifacts-Release | |
| path: | | |
| src/NLWebNet/bin/Release/ | |
| demo/bin/Release/ | |
| retention-days: 7 | |
| code-quality: | |
| runs-on: ubuntu-latest | |
| needs: [check-changes, build] | |
| if: needs.check-changes.outputs.should-skip != 'true' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Run code analysis | |
| run: | | |
| dotnet build --configuration Release --verbosity minimal --warnaserror | |
| - name: Check formatting | |
| run: dotnet format --verify-no-changes --verbosity diagnostic | |
| security-scan: | |
| runs-on: ubuntu-latest | |
| needs: [check-changes, build] | |
| if: needs.check-changes.outputs.should-skip != 'true' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Run security scan | |
| run: | | |
| dotnet list package --vulnerable --include-transitive 2>&1 | tee security-scan.log | |
| if grep -q "has the following vulnerable packages" security-scan.log; then | |
| echo "❌ Vulnerable packages found!" | |
| exit 1 | |
| else | |
| echo "✅ No vulnerable packages found." | |
| fi | |
| package-validation: | |
| runs-on: ubuntu-latest | |
| needs: [check-changes, build] | |
| if: needs.check-changes.outputs.should-skip != 'true' && (github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))) | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Need full history for git describe | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Determine Version | |
| id: version | |
| run: | | |
| # Check if this is a tag push | |
| if [[ $GITHUB_REF == refs/tags/v* ]]; then | |
| # Extract version from tag (remove 'v' prefix) | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| echo "📦 Using tag version: ${VERSION}" | |
| IS_RELEASE_TAG="true" | |
| else | |
| # Ensure we have tags available | |
| git fetch --tags --quiet || true | |
| # Get the latest git tag or use 0.1.0 as default | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.1.0") | |
| # Remove 'v' prefix if present | |
| VERSION=${LATEST_TAG#v} | |
| # Add pre-release suffix with commit count and short SHA | |
| COMMITS_SINCE_TAG=$(git rev-list --count ${LATEST_TAG}..HEAD 2>/dev/null || echo "0") | |
| SHORT_SHA=$(git rev-parse --short HEAD) | |
| VERSION="${VERSION}-alpha.${COMMITS_SINCE_TAG}+${SHORT_SHA}" | |
| echo "📦 Using development version: ${VERSION}" | |
| IS_RELEASE_TAG="false" | |
| fi | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "is_release_tag=${IS_RELEASE_TAG}" >> $GITHUB_OUTPUT | |
| - name: Build (Release) for packaging | |
| run: dotnet build src/NLWebNet --configuration Release --no-restore --verbosity minimal | |
| - name: Pack NuGet package | |
| run: dotnet pack src/NLWebNet --configuration Release --no-build --output ./packages -p:PackageVersion=${{ steps.version.outputs.version }} | |
| - name: Upload package artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: nuget-packages | |
| path: ./packages/*.nupkg | |
| retention-days: 30 | |
| - name: Validate NuGet Package | |
| run: | | |
| echo "📦 Validating NuGet package..." | |
| dotnet tool install --global dotnet-validate --version 0.0.1-preview.537 | |
| PACKAGE_FILE=$(find ./packages -name "*.nupkg" | head -n 1) | |
| echo "Validating package: $PACKAGE_FILE" | |
| # Run validation but skip deterministic build check if it fails | |
| dotnet validate package local "$PACKAGE_FILE" || { | |
| echo "⚠️ Validation failed but continuing (non-blocking for prerelease)" | |
| echo "##[warning]Package validation failed but build will continue" | |
| } | |
| - name: Publish to NuGet.org | |
| if: steps.version.outputs.is_release_tag == 'true' | |
| run: | | |
| PACKAGE_FILE=$(find ./packages -name "*.nupkg" | head -n 1) | |
| echo "🚀 Publishing package to NuGet.org: $PACKAGE_FILE" | |
| dotnet nuget push "$PACKAGE_FILE" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate | |
| echo "✅ Package published successfully!" | |
| - name: Create GitHub Release | |
| if: steps.version.outputs.is_release_tag == 'true' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: ./packages/*.nupkg | |
| generate_release_notes: true | |
| prerelease: ${{ contains(steps.version.outputs.version, '-') }} | |
| tag_name: ${{ github.ref_name }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| docker-build: | |
| runs-on: ubuntu-latest | |
| needs: [check-changes, build] | |
| if: needs.check-changes.outputs.should-skip != 'true' && (github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))) | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build Docker image (test build) | |
| run: | | |
| echo "🐳 Building Docker image for testing..." | |
| docker build -t nlwebnet-demo:test . | |
| echo "✅ Docker build successful" | |
| - name: Test Docker image | |
| run: | | |
| echo "🧪 Testing Docker image..." | |
| # Start container in background | |
| docker run -d --name nlwebnet-test -p 8080:8080 nlwebnet-demo:test | |
| # Wait for container to start | |
| sleep 10 | |
| # Test health endpoint | |
| if curl -f http://localhost:8080/health; then | |
| echo "✅ Health check passed" | |
| else | |
| echo "❌ Health check failed" | |
| docker logs nlwebnet-test | |
| exit 1 | |
| fi | |
| # Cleanup | |
| docker stop nlwebnet-test | |
| docker rm nlwebnet-test |