diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9368ba8..7a3f5d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,6 +166,11 @@ jobs: echo "ASSEMBLY_VERSION=${{ steps.gitversion.outputs.assemblySemVer }}" >> $GITHUB_ENV echo "FILE_VERSION=${{ steps.gitversion.outputs.assemblySemFileVer }}" >> $GITHUB_ENV + - name: Replace version placeholders in documentation + shell: pwsh + run: | + ./build/replace-version.ps1 -Version "${{ env.PACKAGE_VERSION }}" -Path "." + - name: Build (Release) run: > dotnet build JD.Efcpt.Build.sln diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7aa26d0..0b16829 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -374,6 +374,50 @@ When contributing, please update: - **XML comments** - For all public APIs - **Code comments** - For complex logic +#### Version Placeholders in Documentation + +Documentation and README files use `PACKAGE_VERSION` as a placeholder for version numbers. This placeholder is automatically replaced with the actual version during the CI/CD build process. + +**When to use placeholders:** + +Use `PACKAGE_VERSION` in documentation for: +- SDK version references: `Sdk="JD.Efcpt.Sdk/PACKAGE_VERSION"` +- PackageReference version attributes: `Version="PACKAGE_VERSION"` +- Any mention of the current package version in examples + +**Example:** + +```xml + + + + + + + + + + + + + +``` + +**Testing version replacement locally:** + +```bash +# Dry run (shows what would be replaced) +pwsh ./build/replace-version.ps1 -Version "1.2.3" -DryRun + +# Actually replace versions +pwsh ./build/replace-version.ps1 -Version "1.2.3" + +# Revert changes after testing +git checkout README.md docs/ samples/ +``` + +**Important:** Always commit documentation with `PACKAGE_VERSION` placeholders, not actual version numbers. The CI/CD workflow automatically replaces these during the build and package process. + ### Commit Messages Follow conventional commits format: diff --git a/README.md b/README.md index 45328ca..eeb5105 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ dotnet build ### Option B: SDK Approach (Recommended) ```xml - + net8.0 @@ -101,7 +101,7 @@ Automatically generate SQL scripts from your live database when JD.Efcpt.Build d Server=...;Database=MyDb;... - + ``` @@ -110,7 +110,7 @@ Automatically generate SQL scripts from your live database when JD.Efcpt.Build d ```xml - + ``` diff --git a/build/README.md b/build/README.md new file mode 100644 index 0000000..9be4939 --- /dev/null +++ b/build/README.md @@ -0,0 +1,94 @@ +# Build Scripts + +This directory contains build-time scripts and tools used during the CI/CD process. + +## replace-version.ps1 + +PowerShell script that replaces version placeholders in documentation files with actual version numbers from GitVersion. + +### Purpose + +Ensures that all documentation (README, docs, samples) shows the current package version without requiring manual updates. This prevents version drift and user confusion. + +### Usage + +```powershell +# Dry run - shows what would be replaced without making changes +./replace-version.ps1 -Version "1.2.3" -DryRun + +# Replace versions in current directory +./replace-version.ps1 -Version "1.2.3" + +# Replace versions in specific path +./replace-version.ps1 -Version "1.2.3" -Path "../docs" +``` + +### Parameters + +- **Version** (required): The version string to use for replacement (e.g., "1.2.3") +- **Path** (optional): The root path to search for files (defaults to current directory) +- **DryRun** (optional): If specified, shows what would be replaced without making changes + +### Placeholders + +The script recognizes and replaces the following patterns: + +1. **SDK version in Sdk attribute**: `Sdk="JD.Efcpt.Sdk/PACKAGE_VERSION"` +2. **PackageReference Version attribute**: `Version="PACKAGE_VERSION"` +3. **Inline text placeholder**: `PACKAGE_VERSION` (word boundary) + +### CI/CD Integration + +This script is automatically executed during the release build in the CI/CD workflow: + +1. GitVersion calculates the version based on commits and tags +2. The version is stored in `PACKAGE_VERSION` environment variable +3. `replace-version.ps1` is executed to update all documentation +4. The build continues with the updated documentation +5. NuGet packages are created with the correct version in all docs + +### Testing + +```bash +# Test in dry run mode +pwsh ./build/replace-version.ps1 -Version "1.2.3" -DryRun + +# Test actual replacement (remember to revert after) +pwsh ./build/replace-version.ps1 -Version "1.2.3" + +# Revert test changes +git checkout README.md docs/ samples/ +``` + +### Adding Version Placeholders + +When adding new documentation: + +1. Use `PACKAGE_VERSION` instead of hardcoded version numbers +2. Place the placeholder where users would see version numbers +3. Test with the script to ensure replacement works correctly + +**Example:** + +```xml + + + + + + + + + + + + + +``` + +### Notes + +- The script only processes markdown (.md) files +- Files in `.git` and `node_modules` directories are excluded +- All replacements use regex for precise pattern matching +- The script preserves file encoding and line endings diff --git a/build/replace-version.ps1 b/build/replace-version.ps1 new file mode 100755 index 0000000..d0d1b76 --- /dev/null +++ b/build/replace-version.ps1 @@ -0,0 +1,112 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS + Replaces version placeholders in documentation files. + +.DESCRIPTION + This script replaces PACKAGE_VERSION placeholders in markdown and documentation + files with the actual version number from GitVersion or provided as a parameter. + +.PARAMETER Version + The version string to use for replacement (e.g., "1.2.3") + +.PARAMETER Path + The root path to search for files (defaults to repository root) + +.PARAMETER DryRun + If specified, shows what would be replaced without making changes + +.EXAMPLE + ./replace-version.ps1 -Version "1.2.3" + +.EXAMPLE + ./replace-version.ps1 -Version "1.2.3" -Path "../docs" -DryRun +#> + +param( + [Parameter(Mandatory=$true)] + [string]$Version, + + [Parameter(Mandatory=$false)] + [string]$Path = ".", + + [Parameter(Mandatory=$false)] + [switch]$DryRun +) + +$ErrorActionPreference = "Stop" + +# Resolve the path to an absolute path for consistent handling +$Path = [System.IO.Path]::GetFullPath($Path) + +Write-Host "Version Replacement Script" -ForegroundColor Cyan +Write-Host "=========================" -ForegroundColor Cyan +Write-Host "Version: $Version" -ForegroundColor Green +Write-Host "Path: $Path" -ForegroundColor Green +Write-Host "Dry Run: $DryRun" -ForegroundColor Green +Write-Host "" + +# Define the patterns to replace +$patterns = @( + # SDK version in Sdk attribute + @{ + Pattern = 'Sdk="JD\.Efcpt\.Sdk/PACKAGE_VERSION"' + Replacement = "Sdk=`"JD.Efcpt.Sdk/$Version`"" + }, + # PackageReference Version attribute + @{ + Pattern = 'Version="PACKAGE_VERSION"' + Replacement = "Version=`"$Version`"" + }, + # Inline text placeholder + @{ + Pattern = '\bPACKAGE_VERSION\b' + Replacement = $Version + } +) + +# Find all markdown files +$files = Get-ChildItem -Path $Path -Recurse -Include "*.md" -File | + Where-Object { $_.FullName -notmatch "[\\/]\.git[\\/]" -and $_.FullName -notmatch "[\\/]node_modules[\\/]" } + +Write-Host "Found $($files.Count) markdown files to process" -ForegroundColor Yellow +Write-Host "" + +$totalReplacements = 0 + +foreach ($file in $files) { + # Use GetRelativePath for robust path handling + $relativePath = [System.IO.Path]::GetRelativePath($Path, $file.FullName) + $content = Get-Content -Path $file.FullName -Raw -ErrorAction Stop + $fileReplacements = 0 + + foreach ($patternInfo in $patterns) { + $matches = [regex]::Matches($content, $patternInfo.Pattern) + if ($matches.Count -gt 0) { + $content = [regex]::Replace($content, $patternInfo.Pattern, $patternInfo.Replacement) + $fileReplacements += $matches.Count + } + } + + if ($fileReplacements -gt 0) { + Write-Host " $relativePath" -ForegroundColor White + Write-Host " -> $fileReplacements replacement(s)" -ForegroundColor Gray + + if (-not $DryRun) { + # Preserve the original file's newline behavior + # Get-Content with -Raw preserves trailing newlines, so we use -NoNewline to avoid adding an extra one + Set-Content -Path $file.FullName -Value $content -NoNewline -ErrorAction Stop + } + + $totalReplacements += $fileReplacements + } +} + +Write-Host "" +if ($DryRun) { + Write-Host "Dry run complete. Would have made $totalReplacements replacement(s) across $($files.Count) files." -ForegroundColor Yellow +} else { + Write-Host "Successfully replaced $totalReplacements version placeholder(s)." -ForegroundColor Green +} + +exit 0 diff --git a/docs/index.md b/docs/index.md index a4bbadd..ca21593 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,7 +31,7 @@ dotnet build ### Option B: SDK Approach (Recommended) ```xml - + net8.0 diff --git a/docs/user-guide/advanced.md b/docs/user-guide/advanced.md index e8a1749..067794b 100644 --- a/docs/user-guide/advanced.md +++ b/docs/user-guide/advanced.md @@ -26,7 +26,7 @@ Create a `Directory.Build.props` file at the solution root: - + ``` diff --git a/docs/user-guide/configuration.md b/docs/user-guide/configuration.md index 3dcac5a..51feee1 100644 --- a/docs/user-guide/configuration.md +++ b/docs/user-guide/configuration.md @@ -449,7 +449,7 @@ Just add the package; everything is auto-discovered: ```xml - + ``` @@ -511,7 +511,7 @@ Include only specific tables: - + ``` diff --git a/docs/user-guide/connection-string-mode.md b/docs/user-guide/connection-string-mode.md index 30e6edd..4c44cc7 100644 --- a/docs/user-guide/connection-string-mode.md +++ b/docs/user-guide/connection-string-mode.md @@ -320,7 +320,7 @@ Use Windows/Integrated Authentication when possible: ```xml - + @@ -333,7 +333,7 @@ Use Windows/Integrated Authentication when possible: ```xml - + @@ -346,7 +346,7 @@ Use Windows/Integrated Authentication when possible: ```xml - + @@ -359,7 +359,7 @@ Use Windows/Integrated Authentication when possible: ```xml - + @@ -380,7 +380,7 @@ Complete example for an ASP.NET Core project: - + diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md index 98ab2c9..31be145 100644 --- a/docs/user-guide/getting-started.md +++ b/docs/user-guide/getting-started.md @@ -28,7 +28,7 @@ The SDK approach provides the cleanest project files. Use the SDK in your project file with the version specified inline: ```xml - + net8.0 enable @@ -56,7 +56,7 @@ Add JD.Efcpt.Build to your application project (the project that should contain ```xml - + ``` diff --git a/docs/user-guide/sdk.md b/docs/user-guide/sdk.md index 3b7e5d8..9e0605b 100644 --- a/docs/user-guide/sdk.md +++ b/docs/user-guide/sdk.md @@ -30,7 +30,7 @@ Choose JD.Efcpt.Build (PackageReference) when: Use the SDK in your project file with the version specified inline: ```xml - + net8.0 enable @@ -147,7 +147,7 @@ The SDK works with all SQL project types: The SDK also supports connection string mode for direct database reverse engineering: ```xml - + net8.0 Server=localhost;Database=MyDb;Integrated Security=True; @@ -166,7 +166,7 @@ See [Connection String Mode](connection-string-mode.md) for details. The SDK supports multi-targeting just like the standard .NET SDK: ```xml - + net8.0;net9.0;net10.0 @@ -180,7 +180,7 @@ Model generation happens once and is shared across all target frameworks. | Feature | JD.Efcpt.Sdk | JD.Efcpt.Build (PackageReference) | |---------|--------------|-----------------------------------| -| Project file | `Sdk="JD.Efcpt.Sdk/1.0.0"` | `` | +| Project file | `Sdk="JD.Efcpt.Sdk/PACKAGE_VERSION"` | `` | | Version location | Sdk attribute or `global.json` | `.csproj` or Directory.Build.props | | Setup complexity | Lower | Slightly higher | | Existing projects | Requires SDK change | Drop-in addition | @@ -279,7 +279,7 @@ If you prefer using tools like `dotnet outdated` for version management, use `JD If you see an error like "The SDK 'JD.Efcpt.Sdk' could not be resolved": -1. Verify the version is specified (either inline `Sdk="JD.Efcpt.Sdk/1.0.0"` or in `global.json`) +1. Verify the version is specified (either inline `Sdk="JD.Efcpt.Sdk/PACKAGE_VERSION"` or in `global.json`) 2. Check that the version matches an available package version 3. Ensure the package is available in your NuGet sources @@ -295,7 +295,7 @@ If the SQL project isn't building: If you need different SDK versions for different projects: -1. Specify the version inline in each project file: `Sdk="JD.Efcpt.Sdk/1.0.0"` +1. Specify the version inline in each project file: `Sdk="JD.Efcpt.Sdk/PACKAGE_VERSION"` 2. Or use JD.Efcpt.Build via PackageReference instead ## Next Steps diff --git a/docs/user-guide/split-outputs.md b/docs/user-guide/split-outputs.md index e40a11b..d843db1 100644 --- a/docs/user-guide/split-outputs.md +++ b/docs/user-guide/split-outputs.md @@ -199,7 +199,7 @@ Edit `MyProject.Models/MyProject.Models.csproj`: - + @@ -246,7 +246,7 @@ Edit `MyProject.Data/MyProject.Data.csproj`: - + diff --git a/docs/user-guide/use-cases/enterprise.md b/docs/user-guide/use-cases/enterprise.md index d212bc0..1cfa7ad 100644 --- a/docs/user-guide/use-cases/enterprise.md +++ b/docs/user-guide/use-cases/enterprise.md @@ -53,7 +53,7 @@ dotnet new efcptbuild -n MyProject -o src/MyProject ```xml - + ``` @@ -63,7 +63,7 @@ dotnet new efcptbuild -n MyProject -o src/MyProject ```xml - + ``` diff --git a/samples/README.md b/samples/README.md index e84e9ca..df875b1 100644 --- a/samples/README.md +++ b/samples/README.md @@ -80,7 +80,7 @@ sdk-zero-config/ │ ├── DatabaseProject.csproj # Microsoft.Build.Sql project │ └── dbo/Tables/*.sql └── EntityFrameworkCoreProject/ - └── EntityFrameworkCoreProject.csproj # Uses JD.Efcpt.Sdk/1.0.0 + └── EntityFrameworkCoreProject.csproj # Uses JD.Efcpt.Sdk/PACKAGE_VERSION ``` **Key Features:** @@ -91,7 +91,7 @@ sdk-zero-config/ **Project File:** ```xml - + net8.0 diff --git a/samples/msbuild-sdk-sql-proj-generation/README.md b/samples/msbuild-sdk-sql-proj-generation/README.md index a4e77c6..2a1cb0d 100644 --- a/samples/msbuild-sdk-sql-proj-generation/README.md +++ b/samples/msbuild-sdk-sql-proj-generation/README.md @@ -55,7 +55,7 @@ In a real project, you would consume JD.Efcpt.Build as a NuGet package: ```xml - + ``` diff --git a/samples/simple-generation/README.md b/samples/simple-generation/README.md index d803366..f57a574 100644 --- a/samples/simple-generation/README.md +++ b/samples/simple-generation/README.md @@ -40,7 +40,7 @@ In a real project, you would consume JD.Efcpt.Build as a NuGet package: ```xml - + ``` diff --git a/samples/split-data-and-models-between-multiple-projects/README.md b/samples/split-data-and-models-between-multiple-projects/README.md index 0428ad5..1432cf0 100644 --- a/samples/split-data-and-models-between-multiple-projects/README.md +++ b/samples/split-data-and-models-between-multiple-projects/README.md @@ -131,7 +131,7 @@ In a real project, you would consume JD.Efcpt.Build as a NuGet package: ```xml - + ```