How I Use a Custom AI Skill to Upgrade a Large ABP Solution

cover

TL;DR: I created a project-specific AI skill that treats an ABP upgrade as a complete engineering workflow—not merely a package update. It inventories the current solution, creates recovery points, applies the upgrade, resolves known breaking changes, validates the result, and records new lessons for the next upgrade.

Introduction

Upgrading a small application can be as simple as changing a few package versions and rebuilding. Upgrading a mature ABP solution is different.

My solution contains custom ABP service replacements, Entity Framework Core migrations, NuGet and npm dependencies, authentication, Redis, background processing, multiple user interfaces, and production-specific integrations. A framework upgrade can affect any of those areas. More importantly, a successful compilation does not prove that authentication, billing, localization, caching, or database behavior still works.

I wanted my coding agent to understand that wider context every time I asked it to perform an upgrade. Repeating a large prompt from memory was unreliable, so I captured the workflow in a custom skill. You can call yours anything; the reusable example included with this article is named upgrade-abp-solution.

The skill gives the agent:

  • A repeatable upgrade process
  • Project-specific validation requirements
  • PowerShell helpers for inventory, backup, and verification
  • References for migration and namespace changes
  • A durable log of problems encountered in previous upgrades
  • An explicit rollback path

This article explains how the skill is structured, how I use it, and why the most valuable part is not the automation—it is the memory the workflow builds over time.

Why abp update Is Only One Step

The ABP CLI does a useful job of updating ABP-related dependencies:

abp update --version 10.5.0

However, an update command cannot answer solution-specific questions such as:

  • Do custom classes still match constructors in ABP base classes?
  • Has an implemented ABP interface gained a new member?
  • Does the new ABP version require an EF Core migration?
  • Are directly pinned packages now downgrading transitive dependencies?
  • Is the LeptonX version line different from the main ABP version?
  • Did a cached value become incompatible with the new application?
  • Do login, two-factor authentication, password reset, and token flows still behave correctly?
  • Can the solution be restored if a generated migration is unsafe?

My skill therefore treats abp update as an implementation detail inside a larger process:

Inspect → Protect → Research → Update → Compile → Migrate → Validate → Learn

That change in perspective matters. The goal is not to make package files say the new version. The goal is to move the entire solution to the new version with evidence that it remains safe to ship.

The Anatomy of the Skill

The skill is deliberately small enough to inspect and maintain:

upgrade-abp-solution/
├── SKILL.md
├── agents/
│   └── openai.yaml
├── references/
│   ├── encountered-issues.md
│   └── migration-checklist.md
└── scripts/
    ├── Get-AbpInventory.ps1
    ├── New-PreUpgradeSnapshot.ps1
    └── Test-AbpUpgrade.ps1

Each part has a distinct responsibility.

You can browse or copy the complete sample upgrade-abp-solution skill included with this article. It is generic and has no dependencies on my solution.

SKILL.md: The Operating Procedure

SKILL.md is the entry point. Its description tells the agent when the skill applies, while its body describes the ordered workflow.

At a high level, the instructions require the agent to:

  1. Review problems from earlier upgrades.
  2. Back up the database and create a Git recovery point.
  3. Identify the current and target versions.
  4. Read the applicable migration guidance.
  5. Update the ABP CLI and solution dependencies.
  6. Update the .NET SDK and target frameworks when required.
  7. Restore and compile before touching the database.
  8. Generate and manually review EF Core migrations.
  9. Run automated and application-level validation.
  10. Add newly discovered issues to the knowledge log.

The ordering is intentional. For example, generating a migration before resolving all compilation errors produces noise rather than useful evidence. Likewise, an upgrade should not begin until the recovery path is known.

references/migration-checklist.md: The Stable Checklist

The migration checklist contains the things I want checked on every upgrade:

  • Git and database recovery points
  • ABP and .NET version alignment
  • Official migration guidance
  • NuGet restore and full-solution compilation
  • EF Core migration review
  • Unit and integration tests
  • Authentication and CRUD smoke tests
  • Redis and deployment configuration

It also groups recurring problems by area: Entity Framework Core, authorization, localization, caching, background jobs, and ABP system tables.

This file represents stable knowledge. It changes occasionally as the architecture evolves, but it is not rewritten for every upgrade.

Migration References: Fast Triage for Compile Errors

Framework upgrades frequently move types, add async APIs, or change module contracts. The migration checklist and encountered-issues log provide focused places to capture those changes and search patterns.

When the build reports a missing type, the skill directs the agent to:

  1. Search the current ABP source for the type.
  2. Read the migration guide for the target version.
  3. Determine whether the type moved, its package was split, or its API was replaced.
  4. Apply bulk edits only after confirming the correct replacement.

That sequence avoids a common failure mode: guessing a namespace that compiles but represents the wrong abstraction.

references/encountered-issues.md: The Compounding Asset

The issue log is the part I value most. After every upgrade, the agent records:

  • Source and target versions
  • The exact error or symptom
  • The solution that worked
  • Relevant files
  • Time spent
  • Runtime concerns to retest
  • Advice for the next upgrade

This converts one-off debugging into reusable operational knowledge.

For example, the log now knows that:

  • Visual Studio can lock project files while abp update is running.
  • A failing ABP CLI discovery step may justify a controlled manual package bump.
  • Custom implementations of ABP base classes and interfaces deserve early attention.
  • Direct dependency pins can become downgrade errors after transitive requirements move.
  • LeptonX can follow a different version line from the main ABP packages.
  • A green build does not resolve a test process that hangs after the test runner starts.

The next upgrade begins with those lessons already in context.

The Three Helper Scripts

The scripts turn repetitive checks into consistent evidence. They do not replace engineering judgment; they make it easier to apply that judgment to the right information.

1. Inventory the Current State

Get-AbpInventory.ps1 scans the solution and reports:

  • Resolved Volo.Abp, Volo.CmsKit, Volo.Docs, and Volo.Blogging packages
  • The installed ABP CLI version
  • The active .NET SDK
  • Target frameworks found across project files

I can run it from the solution root:

.\scripts\Get-AbpInventory.ps1 -SolutionDir "D:\Projects\MySolution"

This provides a baseline before any file changes occur. It can also reveal version drift that was already present before the upgrade.

2. Create a Recovery Point

New-PreUpgradeSnapshot.ps1 records the state needed to understand or reverse the code-side upgrade:

.\scripts\New-PreUpgradeSnapshot.ps1 `
    -SolutionDir "D:\Projects\MySolution" `
    -OutputDir "D:\Backups\abp-upgrades"

The script:

  • Warns about uncommitted changes
  • Saves the current package list
  • Copies central build and SDK configuration
  • Records the current commit
  • Creates a timestamped Git restore branch
  • Writes restore instructions alongside the backup

It intentionally reminds me that the database backup is a separate operation. A Git branch can restore code; it cannot restore a database after a destructive migration.

3. Validate the Result

Test-AbpUpgrade.ps1 provides a repeatable first validation pass:

.\scripts\Test-AbpUpgrade.ps1 `
    -SolutionDir "D:\Projects\MySolution" `
    -Detailed

It checks:

  • Whether the solution builds without restoring again
  • Whether obsolete API warnings appeared
  • Whether unit tests pass
  • Whether ABP package versions are consistent
  • Whether expected configuration files are present
  • Whether EF Core migrations exist
  • Whether known breaking-change patterns remain
  • Whether deployment files may still reference an older .NET version

Warnings are deliberately distinct from failures. A warning means the script cannot prove something automatically; it does not mean the concern can be ignored.

For example, finding a migrations directory is not the same as proving the model is current. I still run an explicit drift check:

dotnet ef migrations has-pending-model-changes `
    --project src\MySolution.EntityFrameworkCore `
    --startup-project src\MySolution.DbMigrator

My End-to-End Upgrade Workflow

Here is how the skill guides an actual upgrade.

Phase 1: Preflight

First, the agent reads the issue log and applicable migration guidance. It inventories the current package graph, SDK, target frameworks, frontend packages, and explicit dependency pins.

It also identifies solution-specific risk areas before editing anything:

  • ABP base classes that have been subclassed
  • ABP interfaces implemented by custom infrastructure
  • Replaced application services
  • Custom DbContext interfaces
  • Authentication and OpenIddict customization
  • Custom event bus implementations
  • Packages pinned to work around earlier vulnerabilities or incompatibilities

This produces a risk map for the upgrade rather than waiting for the compiler to discover everything.

Phase 2: Protection

The working tree must be understood and a restore point must exist. I back up the database separately, then run the pre-upgrade script.

The key question is simple:

If the package update or migration goes wrong, can I return both the code and the data to a known state?

If the answer is uncertain, the upgrade does not proceed.

Phase 3: Dependency Update

The preferred path is the ABP updater:

dotnet tool update -g Volo.Abp.Cli
abp update --version X.Y.Z

The skill still expects the result to be inspected. An updater may change the primary ABP packages while leaving:

  • npm packages on another version
  • lock files stale
  • direct NuGet pins incompatible
  • container or CI SDK versions unchanged

If the CLI cannot complete, the issue log contains a bounded fallback: update the relevant packages manually, refresh lock files, and let restore surface inconsistencies. The fallback is controlled and reviewable, not a blind search-and-replace across every version string.

Phase 4: Restore and Compile

The next gate is:

dotnet restore
dotnet build --no-restore

Restore failures and compile failures are treated as different classes of problem.

Restore commonly exposes:

  • A package version that does not exist
  • A direct package pin below a new transitive lower bound
  • Mixed ABP versions
  • An unreachable or slow package source

Compilation commonly exposes:

  • New constructor dependencies in ABP base classes
  • New interface members
  • Changed override signatures
  • Moved namespaces
  • New DbSet requirements
  • Changes to custom infrastructure contracts

Separating these stages keeps the diagnosis precise.

Phase 5: Database Migration

Only after the solution compiles does the workflow check for model changes:

dotnet ef migrations add Upgraded_To_Abp_X_Y `
    --project src\MySolution.EntityFrameworkCore `
    --startup-project src\MySolution.DbMigrator

The generated migration is reviewed like production code. I specifically look for:

  • Dropped columns or tables
  • Destructive type or length changes
  • Unexpected modifications to ABP system tables
  • Changes that conflict with custom mappings
  • Provider-specific changes that do not apply to my database

An empty migration is removed. A dangerous migration is corrected or the upgrade is paused; it is never accepted simply because it was generated by a tool.

Phase 6: Validation

The automated validation script is only the first layer. The skill also calls for focused runtime checks:

  • Application startup
  • Login and logout
  • Two-factor authentication and password reset
  • Basic create, read, update, and delete operations
  • Tenant switching, when applicable
  • English and French localization
  • Audit logging
  • Redis serialization and cache behavior
  • Background workers
  • Critical business integrations

The exact list should reflect the solution. In my case, billing and external healthcare integrations deserve explicit checks because they are more important than a generic home-page smoke test.

Phase 7: Record What Was Learned

Finally, the agent adds new findings to encountered-issues.md.

This is not optional housekeeping. It closes the loop:

Previous upgrades inform this upgrade
             ↓
     A new issue is solved
             ↓
The solution is added to the skill
             ↓
 Future upgrades start smarter

Without this step, the skill is a static checklist. With it, the skill becomes a project-specific engineering memory.

Examples of Lessons That Paid Off

The upgrade log has already changed how later upgrades are performed.

Close Development Tools Before Updating

One upgrade produced confusing IOException failures because Visual Studio held project files open. The package changes mostly succeeded, leaving the solution in a partially updated state.

That experience became a preflight instruction: close Visual Studio before running the updater. A later upgrade avoided the problem entirely.

Do Not Spend Unlimited Time Fighting the Preferred Tool

During another upgrade, package discovery repeatedly timed out. The skill now recommends a time-bounded decision: try the CLI first, but move to a controlled manual bump when the failure is clearly environmental and repeatable.

This retains a preferred path without turning it into dogma.

Check Custom ABP Extension Points Early

Custom base-class overrides and interface implementations are frequent compile-break candidates because they mirror ABP contracts closely.

Past upgrades have required:

  • Passing new dependencies to base constructors
  • Implementing newly added interface methods
  • Updating a custom event bus for string-based event contracts
  • Adding a newly required identity DbSet

The skill now inspects those seams early rather than treating each error as an unrelated surprise.

Verify Behavior Even When There Are No Compile Breaks

One upgrade compiled cleanly and required no EF migration, but it introduced an identity token behavior change worth retesting. The build could not prove whether the application's login, two-factor, password-reset, and account-linking experiences still met expectations.

That lesson reinforces the central principle of the skill: compatibility includes behavior, not only APIs.

What the Skill Does Not Automate

I intentionally keep several decisions human-reviewed:

  • Approving destructive database migrations
  • Choosing when a failed updater should be replaced with a manual update
  • Deciding whether package-version differences are legitimate
  • Evaluating business-critical runtime workflows
  • Clearing production caches or authentication data
  • Deploying the upgraded solution

Commands such as flushing Redis or truncating OpenIddict tables can have serious operational consequences. They may be useful recovery options, but they should never run automatically merely because an upgrade occurred.

The skill makes these risks visible and supplies context. It does not remove ownership of the decision.

Design Principles for Your Own Upgrade Skill

If you want to build a similar skill for your ABP solution, I recommend the following principles.

Start with Your Architecture

Generic migration guidance is useful, but the skill becomes valuable when it knows your extension points, infrastructure, deployment model, and critical user journeys.

Separate Procedure, References, and Executable Checks

Keep the main skill concise. Put stable checklists and historical details in reference files, and put deterministic operations in scripts. This makes each layer easier to review.

Prefer Evidence-Producing Automation

A good helper script should answer a question:

  • What versions are installed?
  • Can I recover the previous state?
  • Does the solution compile?
  • Are package versions inconsistent?
  • Is the EF Core model current?

Avoid automation whose only output is “done.”

Make Rollback Part of the Happy Path

Rollback planning should happen before the update, not after an error. Record the Git commit, create a restore branch, save dependency state, and back up the database.

Treat Warnings as Unproven Conditions

Not every check can be binary. A warning should clearly identify what still needs review and why automation could not settle it.

Update the Skill After Every Upgrade

The knowledge log is what gives the skill compounding returns. Record exact errors and proven solutions while they are fresh.

Summary

My custom ABP upgrade skill turns a risky, memory-driven maintenance task into a repeatable workflow:

  • ✅ It inventories the full technology stack before changes begin.
  • ✅ It creates code recovery points and requires a separate database backup.
  • ✅ It combines official migration guidance with project-specific knowledge.
  • ✅ It distinguishes dependency, compilation, schema, and runtime validation.
  • ✅ It remembers real failures so future upgrades avoid the same traps.
  • ✅ It keeps destructive and business-critical decisions under deliberate review.

The skill does not make framework upgrades effortless, and that is not the goal. It makes them explainable, recoverable, and progressively more predictable.

For a large ABP solution, that is a much more useful kind of automation.

References


About the Author

Kori Francis
ABP Framework developer with experience building and operating large .NET solutions, cloud deployments, and project-specific AI engineering workflows.

Connect with me:


Have you built a project-specific workflow for framework upgrades? I would be interested to hear which checks and lessons have saved your team the most time.

Tags: #ABPFramework #DotNet #AI #Automation #EntityFrameworkCore #PowerShell