Skip to content

Commit bb1a92b

Browse files
Copilotlinkdotnet
andauthored
Add automated upgrade assistant for appsettings.json migrations (#463)
* Add Upgrade Assistant tool for appsettings.json migration - Created LinkDotNet.Blog.UpgradeAssistant console tool in tools folder - Implemented migration framework with version tracking - Added migrations for 8.0→9.0, 9.0→11.0, and 11.0→12.0 - Colorful console output using ANSI colors - Automatic backup functionality with timestamps - Dry-run mode to preview changes - Comprehensive documentation in docs/Migrations/UpgradeAssistant.md - Updated MIGRATION.md to reference the new tool - Added ConfigVersion field to appsettings.json - Added backups/ to .gitignore Co-authored-by: linkdotnet <[email protected]> * Add unit tests for Upgrade Assistant - Created test project LinkDotNet.Blog.UpgradeAssistant.Tests - Added comprehensive tests for Migration8To9, Migration9To11, Migration11To12 - Added tests for MigrationManager including end-to-end scenarios - All 17 tests passing Co-authored-by: linkdotnet <[email protected]> * Address code review feedback - Remove OutputType from test project csproj - Fix document disposal pattern in MigrationManager - Use separate variable for each migration document Co-authored-by: linkdotnet <[email protected]> * Address PR feedback - use Spectre.Console, remove old migrations, skip appsettings.json - Replace CommandLineParser with Spectre.Console for CLI and colorful output - Remove Migration_8_To_9 and Migration_9_To_11 (current version is 11.0) - Make CurrentVersion dynamic based on highest ToVersion from migrations - Skip version-controlled appsettings.json file during migration - Update tests to reflect changes (9 tests passing) - Enhanced help and version output with Figlet text and tables Co-authored-by: linkdotnet <[email protected]> * Add projects to solution and remove unnecessary comments - Added LinkDotNet.Blog.UpgradeAssistant and LinkDotNet.Blog.UpgradeAssistant.Tests to LinkDotNet.Blog.sln - Removed inline comments from code, using descriptive method names instead - Extracted ParseCommandLineArguments method for better code organization - Created DetermineCurrentVersionFromMigrations and IsVersionControlledAppsettingsFile methods - Kept only XML documentation comments (///) which are standard - All tests passing (9/9) Co-authored-by: linkdotnet <[email protected]> * Add Automated Migration documentation to README files - Added chapter about Automated Configuration Migration (Version 12+) in docs/Migrations/Readme.md - Documented Upgrade Assistant features, usage examples, and benefits - Added "Automated Configuration Migration" as a feature in main Readme.md - Provided clear migration path: automated for v12+, manual for pre-v12 Co-authored-by: linkdotnet <[email protected]> * docs: Add clarification and cleanup * docs: Add readme * fix: Build errors --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: linkdotnet <[email protected]> Co-authored-by: Steven Giesel <[email protected]>
1 parent 1c38853 commit bb1a92b

File tree

19 files changed

+1319
-1
lines changed

19 files changed

+1319
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,8 @@ bundle.min.css
3030
/**/coverage*.xml
3131
/CoverageReport/
3232

33+
# Upgrade Assistant backups
34+
backups/
35+
3336
# MacOS
3437
.DS_Store

Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@
5858
<ItemGroup Label="Tools">
5959
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
6060
<PackageVersion Include="Microsoft.Playwright" Version="1.57.0" />
61+
<PackageVersion Include="Spectre.Console" Version="0.49.1" />
6162
</ItemGroup>
6263
</Project>

LinkDotNet.Blog.sln

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,40 +43,128 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{A931171C
4343
EndProject
4444
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinkDotNet.Blog.CriticalCSS", "tools\LinkDotNet.Blog.CriticalCSS\LinkDotNet.Blog.CriticalCSS.csproj", "{8CB83177-C078-4953-BC27-8968D2A6E0FE}"
4545
EndProject
46+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinkDotNet.Blog.UpgradeAssistant", "tools\LinkDotNet.Blog.UpgradeAssistant\LinkDotNet.Blog.UpgradeAssistant.csproj", "{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}"
47+
EndProject
48+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinkDotNet.Blog.UpgradeAssistant.Tests", "tests\LinkDotNet.Blog.UpgradeAssistant.Tests\LinkDotNet.Blog.UpgradeAssistant.Tests.csproj", "{8CD027B6-B188-4091-A1A0-FD678DF98C52}"
49+
EndProject
4650
Global
4751
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4852
Debug|Any CPU = Debug|Any CPU
53+
Debug|x64 = Debug|x64
54+
Debug|x86 = Debug|x86
4955
Release|Any CPU = Release|Any CPU
56+
Release|x64 = Release|x64
57+
Release|x86 = Release|x86
5058
EndGlobalSection
5159
GlobalSection(ProjectConfigurationPlatforms) = postSolution
5260
{6D6519BF-9265-488D-AA3B-C879F427930F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
5361
{6D6519BF-9265-488D-AA3B-C879F427930F}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{6D6519BF-9265-488D-AA3B-C879F427930F}.Debug|x64.ActiveCfg = Debug|Any CPU
63+
{6D6519BF-9265-488D-AA3B-C879F427930F}.Debug|x64.Build.0 = Debug|Any CPU
64+
{6D6519BF-9265-488D-AA3B-C879F427930F}.Debug|x86.ActiveCfg = Debug|Any CPU
65+
{6D6519BF-9265-488D-AA3B-C879F427930F}.Debug|x86.Build.0 = Debug|Any CPU
5466
{6D6519BF-9265-488D-AA3B-C879F427930F}.Release|Any CPU.ActiveCfg = Release|Any CPU
5567
{6D6519BF-9265-488D-AA3B-C879F427930F}.Release|Any CPU.Build.0 = Release|Any CPU
68+
{6D6519BF-9265-488D-AA3B-C879F427930F}.Release|x64.ActiveCfg = Release|Any CPU
69+
{6D6519BF-9265-488D-AA3B-C879F427930F}.Release|x64.Build.0 = Release|Any CPU
70+
{6D6519BF-9265-488D-AA3B-C879F427930F}.Release|x86.ActiveCfg = Release|Any CPU
71+
{6D6519BF-9265-488D-AA3B-C879F427930F}.Release|x86.Build.0 = Release|Any CPU
5672
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
5773
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
74+
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Debug|x64.ActiveCfg = Debug|Any CPU
75+
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Debug|x64.Build.0 = Debug|Any CPU
76+
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Debug|x86.ActiveCfg = Debug|Any CPU
77+
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Debug|x86.Build.0 = Debug|Any CPU
5878
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
5979
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Release|Any CPU.Build.0 = Release|Any CPU
80+
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Release|x64.ActiveCfg = Release|Any CPU
81+
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Release|x64.Build.0 = Release|Any CPU
82+
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Release|x86.ActiveCfg = Release|Any CPU
83+
{18F8E09D-FF0B-4FF9-93A9-971A388D0E2A}.Release|x86.Build.0 = Release|Any CPU
6084
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
6185
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
86+
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Debug|x64.ActiveCfg = Debug|Any CPU
87+
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Debug|x64.Build.0 = Debug|Any CPU
88+
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Debug|x86.ActiveCfg = Debug|Any CPU
89+
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Debug|x86.Build.0 = Debug|Any CPU
6290
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
6391
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Release|Any CPU.Build.0 = Release|Any CPU
92+
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Release|x64.ActiveCfg = Release|Any CPU
93+
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Release|x64.Build.0 = Release|Any CPU
94+
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Release|x86.ActiveCfg = Release|Any CPU
95+
{E8ED38D2-FCD3-473D-BD78-43EE78E08EE6}.Release|x86.Build.0 = Release|Any CPU
6496
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
6597
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
98+
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Debug|x64.ActiveCfg = Debug|Any CPU
99+
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Debug|x64.Build.0 = Debug|Any CPU
100+
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Debug|x86.ActiveCfg = Debug|Any CPU
101+
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Debug|x86.Build.0 = Debug|Any CPU
66102
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
67103
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Release|Any CPU.Build.0 = Release|Any CPU
104+
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Release|x64.ActiveCfg = Release|Any CPU
105+
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Release|x64.Build.0 = Release|Any CPU
106+
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Release|x86.ActiveCfg = Release|Any CPU
107+
{5B868911-7C93-4190-AEE4-3A6694F2FFCE}.Release|x86.Build.0 = Release|Any CPU
68108
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69109
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Debug|Any CPU.Build.0 = Debug|Any CPU
110+
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Debug|x64.ActiveCfg = Debug|Any CPU
111+
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Debug|x64.Build.0 = Debug|Any CPU
112+
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Debug|x86.ActiveCfg = Debug|Any CPU
113+
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Debug|x86.Build.0 = Debug|Any CPU
70114
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Release|Any CPU.ActiveCfg = Release|Any CPU
71115
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Release|Any CPU.Build.0 = Release|Any CPU
116+
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Release|x64.ActiveCfg = Release|Any CPU
117+
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Release|x64.Build.0 = Release|Any CPU
118+
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Release|x86.ActiveCfg = Release|Any CPU
119+
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A}.Release|x86.Build.0 = Release|Any CPU
72120
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
73121
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
122+
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Debug|x64.ActiveCfg = Debug|Any CPU
123+
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Debug|x64.Build.0 = Debug|Any CPU
124+
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Debug|x86.ActiveCfg = Debug|Any CPU
125+
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Debug|x86.Build.0 = Debug|Any CPU
74126
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
75127
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Release|Any CPU.Build.0 = Release|Any CPU
128+
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Release|x64.ActiveCfg = Release|Any CPU
129+
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Release|x64.Build.0 = Release|Any CPU
130+
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Release|x86.ActiveCfg = Release|Any CPU
131+
{310ABEE1-C131-43E6-A759-F2DB75A483DD}.Release|x86.Build.0 = Release|Any CPU
76132
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
77133
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
134+
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Debug|x64.ActiveCfg = Debug|Any CPU
135+
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Debug|x64.Build.0 = Debug|Any CPU
136+
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Debug|x86.ActiveCfg = Debug|Any CPU
137+
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Debug|x86.Build.0 = Debug|Any CPU
78138
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
79139
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Release|Any CPU.Build.0 = Release|Any CPU
140+
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Release|x64.ActiveCfg = Release|Any CPU
141+
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Release|x64.Build.0 = Release|Any CPU
142+
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Release|x86.ActiveCfg = Release|Any CPU
143+
{8CB83177-C078-4953-BC27-8968D2A6E0FE}.Release|x86.Build.0 = Release|Any CPU
144+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
145+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
146+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Debug|x64.ActiveCfg = Debug|Any CPU
147+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Debug|x64.Build.0 = Debug|Any CPU
148+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Debug|x86.ActiveCfg = Debug|Any CPU
149+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Debug|x86.Build.0 = Debug|Any CPU
150+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
151+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Release|Any CPU.Build.0 = Release|Any CPU
152+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Release|x64.ActiveCfg = Release|Any CPU
153+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Release|x64.Build.0 = Release|Any CPU
154+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Release|x86.ActiveCfg = Release|Any CPU
155+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4}.Release|x86.Build.0 = Release|Any CPU
156+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
157+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Debug|Any CPU.Build.0 = Debug|Any CPU
158+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Debug|x64.ActiveCfg = Debug|Any CPU
159+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Debug|x64.Build.0 = Debug|Any CPU
160+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Debug|x86.ActiveCfg = Debug|Any CPU
161+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Debug|x86.Build.0 = Debug|Any CPU
162+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Release|Any CPU.ActiveCfg = Release|Any CPU
163+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Release|Any CPU.Build.0 = Release|Any CPU
164+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Release|x64.ActiveCfg = Release|Any CPU
165+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Release|x64.Build.0 = Release|Any CPU
166+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Release|x86.ActiveCfg = Release|Any CPU
167+
{8CD027B6-B188-4091-A1A0-FD678DF98C52}.Release|x86.Build.0 = Release|Any CPU
80168
EndGlobalSection
81169
GlobalSection(SolutionProperties) = preSolution
82170
HideSolutionNode = FALSE
@@ -89,6 +177,8 @@ Global
89177
{DEFDA17A-9586-4E50-83FB-8F75AC29D39A} = {CAD2F4A3-1282-49B5-B0AB-655CDBED0A35}
90178
{310ABEE1-C131-43E6-A759-F2DB75A483DD} = {CAD2F4A3-1282-49B5-B0AB-655CDBED0A35}
91179
{8CB83177-C078-4953-BC27-8968D2A6E0FE} = {A931171C-22A6-4DB5-802B-67286B536BD2}
180+
{B0C71EE4-FD6F-4879-9F83-AEB4FD5824E4} = {A931171C-22A6-4DB5-802B-67286B536BD2}
181+
{8CD027B6-B188-4091-A1A0-FD678DF98C52} = {CAD2F4A3-1282-49B5-B0AB-655CDBED0A35}
92182
EndGlobalSection
93183
GlobalSection(ExtensibilityGlobals) = postSolution
94184
SolutionGuid = {FB9B0642-F1F0-4BD8-9EDD-15C95F082180}

MIGRATION.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
# Migration Guide
22
This document describes the changes that need to be made to migrate from one version of the blog to another.
33

4+
## Automated Upgrade Assistant
5+
6+
Starting with version 12.0, we provide an **Upgrade Assistant** tool that automates most configuration migrations. This tool:
7+
- Automatically detects your current configuration version
8+
- Applies necessary transformations to `appsettings.json` files
9+
- Creates backups before making changes
10+
- Provides colorful console output with clear warnings and instructions
11+
12+
**Usage:**
13+
```bash
14+
# From your blog directory
15+
dotnet run --project tools/LinkDotNet.Blog.UpgradeAssistant
16+
17+
# Preview changes without applying
18+
dotnet run --project tools/LinkDotNet.Blog.UpgradeAssistant -- --dry-run
19+
20+
# See all options
21+
dotnet run --project tools/LinkDotNet.Blog.UpgradeAssistant -- --help
22+
```
23+
24+
For detailed documentation, see [docs/Migrations/UpgradeAssistant.md](docs/Migrations/UpgradeAssistant.md).
25+
26+
**Note:** While the Upgrade Assistant handles most configuration changes automatically, some migrations still require manual steps (especially database schema changes). These are noted below.
27+
28+
---
29+
430
## 11.0 to 12.0
531
`ShowBuildInformation` setting was added on the root level of the `appsettings.json` file. This setting controls whether build information (like build date) is shown in the `Footer` component.
632

Readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ This also includes source code snippets. Highlighting is done via [highlight.js]
2727
- **About Me Page** - Customizable profile page that showcases skills and experience
2828
- **RSS Feed** - Allow readers to subscribe to content updates
2929
- **Visit Counter** - Get visitor counters for each blog post in the internal dashboard
30+
- **Automated Configuration Migration** - Upgrade Assistant tool automatically migrates appsettings.json files between versions
31+
- **Automated Database Migrations** - Seamless database schema updates using Entity Framework Migrations
3032

3133
## In Action
3234

docs/Migrations/Readme.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,33 @@ This is contrasted by Minor changes. These are things where the user does not ne
66

77
Breaking changes are recorded in the [MIGRATION.md](../../MIGRATION.md). Since version 9 of the blog, “Entity Framework Migrations” has been introduced for all SQL providers. You can read more in the [documentation](../Storage/Readme.md). In a nutshell, this means that database migration can be carried out easily via the “ef migration” CLI tool. More on this in the documentation linked above.
88

9-
Changes for the appsettings.json must currently still be made manually. The exact changes that need to be made here can be found in MIGRATION.md.
9+
Changes for the appsettings.json must currently still be made manually. The exact changes that need to be made here can be found in MIGRATION.md.
10+
11+
## Automated Configuration Migration (Version 12+)
12+
13+
Starting with **version 12**, the blog includes an **Automated Upgrade Assistant** that handles appsettings.json migrations automatically. This tool eliminates the need for manual configuration changes in most cases.
14+
15+
### What the Upgrade Assistant Does
16+
17+
- **Automatic Detection** - Detects your current configuration version
18+
- **Sequential Migration** - Applies necessary migrations step-by-step
19+
- **Safe Backups** - Creates timestamped backups before making any changes
20+
- **Smart Filtering** - Skips version-controlled `appsettings.json`, only migrates environment-specific files
21+
- **Colorful Output** - Provides clear, color-coded feedback about changes and warnings
22+
23+
### How to Use
24+
25+
Run the Upgrade Assistant from your blog directory:
26+
27+
```bash
28+
# Preview changes without applying them
29+
dotnet run --project tools/LinkDotNet.Blog.UpgradeAssistant -- --dry-run
30+
31+
# Migrate all environment-specific appsettings files
32+
dotnet run --project tools/LinkDotNet.Blog.UpgradeAssistant
33+
34+
# Migrate a specific file
35+
dotnet run --project tools/LinkDotNet.Blog.UpgradeAssistant -- --path appsettings.Production.json
36+
```
37+
38+
For detailed documentation on the Upgrade Assistant, see [UpgradeAssistant.md](./UpgradeAssistant.md).

0 commit comments

Comments
 (0)