diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/.gitignore b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/.gitignore index 6d3bfed57..be1505eb2 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/.gitignore +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/.gitignore @@ -123,3 +123,9 @@ build/ .project .settings/ .factorypath + +# Sample application clones (created by docs/environment-setup.md) +repos/ + +# modernize CLI artifacts (repos.json, assessment reports, plans) +.github/modernize/ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/Readme.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/Readme.md index d1c115a0b..c7f4dce0d 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/Readme.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/Readme.md @@ -5,7 +5,6 @@ - [**Objectives**](#objectives) - [**Environment setup**](#environment-setup) - [**MicroHack challenges**](#microhack-challenges) -- [**Contributors**](#contributors) # MicroHack introduction @@ -23,7 +22,7 @@ Across the challenges you will work with **PhotoAlbum** and **PhotoAlbum-Java** After completing this MicroHack you will: -- Know how to author a **Custom Agent** (`.agent.md`), package a reusable **Skill** (`SKILL.md`), and configure **MCP** (`mcp.json`), and understand the gated assess → plan → execute → validate loop. +- Know how to author a **Custom Agent** (`.agent.md`), package a reusable **Skill** (`SKILL.md`), and configure **MCP** (`.github/mcp.json` for GitHub Copilot CLI), and understand the gated assess → plan → execute → validate loop. - Understand how to use the GitHub Copilot App Modernization agent (modernize CLI). - Know how to assess applications for cloud readiness and framework upgrade opportunities. - Be able to upgrade .NET and Java applications to their latest framework versions. @@ -40,19 +39,19 @@ This MicroHack has a few but important prerequisites. In order to use the MicroHack time most effectively, the following should be in place before you start: - An **Azure Subscription** with permission to create resource groups and resources (Contributor or Owner). -- A **GitHub account** to fork the sample repositories. +- A **GitHub account** to sign in to GitHub Copilot and clone the sample repositories. - An active **GitHub Copilot** subscription. -- For the recommended Codespaces setup: permission to create a Codespace from your MicroHack fork. -- For a local setup: **Visual Studio Code**, the **GitHub Copilot App Modernization agent (modernize CLI)**, **GitHub CLI**, **Azure CLI**, **Docker Desktop**, **Git**, and the relevant SDKs (.NET and Java). +- For the recommended Codespaces setup: permission to create a Codespace from the MicroHack repository (or a fork of it). +- For a local setup: **Visual Studio Code**, the **GitHub Copilot App Modernization agent (modernize CLI)**, **GitHub Copilot CLI**, **GitHub CLI**, **Azure CLI**, **Docker Desktop**, **Git**, and the relevant SDKs (.NET and Java). -GitHub Codespaces is the recommended environment for this MicroHack. The dedicated **Azure / App Innovation / GHCP App Modernization** development container installs the required tools consistently for all participants. +GitHub Codespaces is the **supported environment** for this MicroHack — local setups are best-effort. The dedicated **Azure / App Innovation / GHCP App Modernization** development container installs the required tools consistently for all participants. Complete the [environment setup guide](docs/environment-setup.md) before starting the challenges. It covers: - creating a Codespace with the correct development container, - verifying the modernization and platform tools, - signing in to GitHub for GitHub Copilot and signing in to Azure, -- forking and cloning both sample applications, and +- cloning both sample applications, and - troubleshooting installation, authentication, SSO, and repository access. # MicroHack challenges diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-01.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-01.md index 01227af01..dc1ab7f3f 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-01.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-01.md @@ -1,42 +1,52 @@ -# Fundamentals — Custom Agents, Skills & MCP for App Modernization +# 1. Fundamentals — Custom Agents, Skills & MCP for App Modernization **[Home](../Readme.md)** - [Next Challenge](challenge-02.md) ## Goal -Build the AI foundation you will reuse in the next challenges. Learn how **GitHub Copilot Custom Agents**, **Skills**, and **MCP (Model Context Protocol)** servers fit together, then author your own modernization Custom Agent, package a reusable Skill, and configure the MCP tools that let the agent assess, build, and validate a legacy application. +Build the AI foundation you will reuse in the next challenges. Learn how **Custom Agents**, **Skills**, and **MCP (Model Context Protocol)** servers fit together, then author your own modernization Custom Agent, package a reusable Skill, and configure MCP for **GitHub Copilot CLI** — all inside the target repository, where both Copilot CLI and the **modernize CLI** pick them up. + +> ⚙️ Complete the [environment setup](../docs/environment-setup.md) first. It creates the recommended Codespace (Copilot CLI and modernize CLI preinstalled) and clones the two sample apps into `repos/`. ## Scenario -Before pointing AI at a real .NET or Java application (challenges 2 and 3), you assemble a reusable, gated modernization playbook: +Before pointing AI at a real .NET or Java application (challenges 2 and 3), you assemble a reusable, gated modernization playbook. Everything is authored once in the target repository under `.github/`, so it travels with the code and works across surfaces: + +- an **Agent** (`.github/agents/`) that defines *who* is working and *how* the assess → plan → execute → validate loop runs (with approval gates), +- a **Skill** (`.github/skills/`) that packages the *domain knowledge* (migration rules, breaking-changes checklist) — the modernize CLI auto-detects these skills when it creates a plan, +- an **MCP** configuration (`.github/mcp.json`) that gives the agent extra *tools* to act (Azure resource queries, quotas, deployments, diagnostics). -- an **Agent** that defines *who* is working and *how* the assess → plan → execute → validate loop runs (with approval gates), -- a **Skill** that packages the *domain knowledge* (migration rules, breaking-changes checklist) the agent pulls in on demand, -- an **MCP** configuration that gives the agent the *tools* to act (assessment, build, CVE scan, deployment). +Use **`repos/PhotoAlbum-Java`** (cloned during environment setup) as the target repository — it is the same app you upgrade in Challenge 2. > 📖 Read [docs/00-fundamentals.md](../docs/00-fundamentals.md) first (~15 min). It gives you the mental model: *Agent = who/how*, *Skill = what it knows*, *MCP = what it can do*. ## Actions * Read [docs/00-fundamentals.md](../docs/00-fundamentals.md) and review the base templates in [templates/](../templates/). -* **Author a Custom Agent** — copy [templates/agents/modernization.agent.md](../templates/agents/modernization.agent.md) to `.github/agents/.agent.md` in a target repo, replace every `{{PLACEHOLDER}}`, and tighten the tool allow-list so the assessment phase stays read-only (least privilege). -* **Author a Skill** — copy [templates/skills/modernization-skill/SKILL.md](../templates/skills/modernization-skill/SKILL.md) to `.github/skills//SKILL.md`, and write an explicit `WHEN:` trigger description plus at least one transformation-rules table. Optionally use the [skill-creator](../templates/skills/skill-creator/SKILL.md) meta-skill to iterate. -* **Configure MCP** — copy [templates/mcp/mcp.json](../templates/mcp/mcp.json) to `.vscode/mcp.json`, then run **MCP: List Servers** and confirm the `appmod-*` tools (registered by the App Modernization extensions) appear in the agent's tool picker. +* **Author a Custom Agent** — copy [templates/agents/modernization.agent.md](../templates/agents/modernization.agent.md) to `.github/agents/.agent.md` in the target repo, replace every `{{PLACEHOLDER}}`, and keep the tool allow-list least-privilege. Verify it: run `copilot` inside the repo (confirm folder trust when prompted — you are asked once per folder) and pick your agent with `/agent`. +* **Author a Skill** — copy [templates/skills/modernization-skill/SKILL.md](../templates/skills/modernization-skill/SKILL.md) to `.github/skills//SKILL.md` (lowercase, hyphenated folder name), set the frontmatter `name:` to match the folder, and write an explicit `WHEN:` trigger description plus at least one transformation-rules table. The `description` is what both Copilot CLI and the modernize CLI match against your prompt. Verify it: `/skills list` in Copilot CLI. Optionally use the [skill-creator](../templates/skills/skill-creator/SKILL.md) meta-skill to iterate. +* **Configure MCP for Copilot CLI** — copy [templates/mcp/copilot-cli-mcp.json](../templates/mcp/copilot-cli-mcp.json) to `.github/mcp.json` in the target repo. Verify it: inside `copilot`, run `/mcp list` — the `azure` server appears (project MCP servers load only in trusted folders; the GitHub MCP server is built in and needs no entry). +* **Dry-run skill detection** — from the target repo, run `modernize plan create ""` and confirm the generated plan under `.github/modernize/` references your skill with `"location": "project"` in its `tasks.json`. Create the plan only — execution happens in challenges 2 and 3. Finally, commit your authored `.github/` files on the `modernize` branch so the repository is clean for Challenge 2. * Compare your work against the pre-tailored references shipped in [templates/](../templates/) (`dotnet-modernization.agent.md`, `dotnet-upgrade`, `java-modernization.agent.md`, `java-upgrade`). ## Success criteria * You can explain, in one sentence each, what an Agent, a Skill, and an MCP server contribute to a modernization workflow. -* A valid Custom Agent (`.agent.md` with YAML frontmatter) exists, with a phased, gated workflow and a least-privilege tool list. -* A valid Skill (`SKILL.md`) exists with an explicit `WHEN:` trigger description and at least one rules table. -* `.vscode/mcp.json` is configured and **MCP: List Servers** resolves the servers; the `appmod-*` tools are visible to the agent. +* A valid Custom Agent (`.agent.md` with YAML frontmatter) exists in `.github/agents/`, has a phased, gated workflow and a least-privilege tool list, and shows up in Copilot CLI's `/agent` picker. +* A valid Skill (`SKILL.md`) exists in `.github/skills//` with an explicit `WHEN:` trigger description and at least one rules table, and `/skills list` shows it. +* `.github/mcp.json` resolves in Copilot CLI: `/mcp list` shows the `azure` server. +* A modernize CLI plan created from your prompt references your custom skill in its `tasks.json` — and you have **not** executed the plan. + +> 💻 **Using VS Code instead of the CLI?** The same `.github/agents/` files are picked up by VS Code's agent picker. MCP is configured differently there: copy [templates/mcp/mcp.json](../templates/mcp/mcp.json) to `.vscode/mcp.json` and run **MCP: List Servers** — the formats are not interchangeable, and Copilot CLI does not read `.vscode/mcp.json`. The `appmod-*` tool families come from the GitHub Copilot app modernization VS Code extensions; install the one for your stack if you work in the IDE. > Need the detailed, step-by-step walkthrough? See the [Challenge 1 Solution](../walkthrough/challenge-01/solution-01.md). ## Learning resources -* [Custom chat modes / agents in VS Code](https://code.visualstudio.com/docs/copilot/chat/chat-modes) -* [MCP servers in VS Code](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) -* [GitHub Copilot app modernization for .NET](https://learn.microsoft.com/dotnet/core/porting/github-copilot-app-modernization-overview) +* [About custom agents](https://docs.github.com/en/copilot/concepts/agents/about-custom-agents) and the [custom agents configuration reference](https://docs.github.com/en/copilot/reference/custom-agents-configuration) +* [Add agent skills to Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills) · [Agent skills specification](https://agentskills.io/specification) +* [Add MCP servers to Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers) +* [Customize the modernization agent with your own skills](https://learn.microsoft.com/azure/developer/github-copilot-app-modernization/modernization-agent/customization) +* [GitHub Copilot app modernization for .NET](https://learn.microsoft.com/dotnet/azure/migration/appmod/overview) * [GitHub Copilot app modernization for Java](https://learn.microsoft.com/azure/developer/java/migration/migrate-github-copilot-app-modernization-for-java) * [Model Context Protocol](https://modelcontextprotocol.io/) diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-02.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-02.md index 693c059b7..0adb56a11 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-02.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-02.md @@ -9,30 +9,29 @@ Use the GitHub Copilot App Modernization agent (modernize CLI) to assess and upg ## Actions * Complete the [environment setup guide](../docs/environment-setup.md), including GitHub and Azure authentication and the tool verification steps. -* Fork the two sample repositories into your own GitHub account: +* Make sure the two sample repositories are cloned into the `repos/` working directory (done during environment setup — no forking needed) and that each is on its local `modernize` branch: * PhotoAlbum-Java (Spring Boot): `https://github.com/Azure-Samples/PhotoAlbum-Java` * PhotoAlbum (.NET): `https://github.com/Azure-Samples/PhotoAlbum` -* Clone both forks into the `repos/` working directory created by the environment setup. Confirm that each `origin` points to your fork. * Use the preinstalled GitHub Copilot App Modernization agent (modernize CLI) in the recommended Codespace, or install it as described in the environment setup for a local workstation. You will use it end-to-end for assessment, upgrade, planning, and execution. -* Create a repositories config file so the CLI can operate on both apps in a single batch run. -* Run a **batch assessment** across both repositories, selecting the *Upgrade* and *Cloud readiness* analyses with full analysis coverage. Let the assessment run locally and wait for it to complete. -* Explore the assessment output: the **aggregated report** (overall recommendations, target platforms, upgrade paths, and migration waves) and the **per-repository reports** (detailed findings per app). +* Create the repositories config file at `.github/modernize/repos.json` in the hack working directory, using local `path` entries that point at the two clones in `repos/` — the CLI then operates on your local working copies in a single batch run instead of cloning fresh ones. +* Run a **batch assessment** across both repositories, selecting the *Upgrade* and *Cloud readiness* analyses with full analysis coverage, and verify the upgrade targets on the configuration page (**.NET 10** and **OpenJDK 25**). Let the assessment run locally and wait for it to complete. +* Explore the assessment output in `.github/modernize/assessment/`: the **aggregated report** (overall recommendations, target platforms, upgrade paths, and migration waves) and the **per-repository reports** (detailed findings per app). * Because a batch upgrade requires both repositories to share the same language, **upgrade each app individually**: * Upgrade the .NET app to the version recommended in the assessment (.NET 10). * Upgrade the Java app to the versions recommended in the assessment (Java 25 and Spring Boot 4.0). -* Confirm each upgrade reports success, then commit and push the changes to each respective forked repository. +* Confirm each upgrade reports success, then commit the changes on each repository's `modernize` branch. (Optional) Publish a repository to your own GitHub account with `gh repo create` if you want a remote copy — the upstream `Azure-Samples` repositories are read-only. > [!TIP] -> The assessment and each upgrade can take several minutes to run. Review the generated reports while you wait — they explain *why* each recommendation was made. +> With full analysis coverage, the batch assessment takes roughly 10-20 minutes for the two repositories, and each upgrade can take 15-45 minutes. Review the generated reports while you wait — they explain *why* each recommendation was made. ## Success criteria -* Both PhotoAlbum-Java and PhotoAlbum are forked and available in your working directory. -* GitHub CLI is authenticated with the GitHub account that has Copilot access, and both application remotes point to forks where you can push. +* Both PhotoAlbum-Java and PhotoAlbum are cloned into `repos/` and checked out on their local `modernize` branch. +* GitHub CLI is authenticated with the GitHub account that has Copilot access. * The modernize CLI is installed and configured to target both repositories from a config file. * A batch assessment completes and produces both an aggregated report and per-repository reports. * The .NET app is upgraded to .NET 10 and the Java app is upgraded to Java 25 / Spring Boot 4.0, each reporting a successful upgrade. -* All upgrade changes are committed and pushed to the respective remote repositories. +* All upgrade changes are committed on the `modernize` branch of each repository. > Need the detailed, step-by-step walkthrough? See the [Challenge 2 Solution](../walkthrough/challenge-02/solution-02.md). diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-03.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-03.md index a8c8079a6..7bc8e2af4 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-03.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/challenge-03.md @@ -8,24 +8,30 @@ Take the two apps you upgraded in Challenge 2 and use the modernize CLI to creat ## Actions -* Using the modernize CLI, create a **cloud modernization plan** that targets both repositories from your config file. Instruct the plan to: +* Using the modernize CLI, create a **cloud modernization plan** for both repositories: select **Plan**, choose **From a config file** (the `repos.json` you created in Challenge 2), select both apps, and choose **Keep the plan local**. Name the plan `cloud-modernization-plan` and instruct it to: * Ignore any upgrade recommendations from the earlier assessment (the apps are already upgraded). * Focus on resolving cloud readiness issues, provisioning Azure infrastructure for each app, and deploying each app to Azure. * Migrate any OracleDB dependency to PostgreSQL if present. -* Review the generated plan and its tasks, then review and **merge the pull request** the agent produces. -* **Deploy the PhotoAlbum-Java app**: pull the latest plan branch, execute the plan with the modernize CLI, and wait for all tasks to finish. Validate the deployment by inspecting the created resource group in Azure and browsing to the Frontend Container App URL. -* **Deploy the PhotoAlbum (.NET) app**: pull the latest plan branch and execute the plan. If the plan does not provision infrastructure or deploy resources for this app, create a second, more explicit plan (for example, an "infra-setup-plan" that provisions Azure resources and deploys the app), then execute it. +* Review each generated plan at `.github/modernize/cloud-modernization-plan/plan.md` inside the respective repository and adjust it if needed — plans are local files in each repository's working tree (the CLI keeps them out of git); nothing is committed or pushed. +* **Deploy the PhotoAlbum-Java app**: from `repos/PhotoAlbum-Java`, execute the plan with the modernize CLI and wait for all tasks to finish. Validate the deployment by inspecting the created resource group in Azure and browsing to the Frontend Container App URL. +* **Deploy the PhotoAlbum (.NET) app**: execute the plan from `repos/PhotoAlbum`. If the plan does not provision infrastructure or deploy resources for this app, create a second, more explicit plan (for example, an `infra-setup-plan` that provisions Azure resources and deploys the app), then execute it. * Validate the .NET deployment the same way — confirm the Azure resources and open the Frontend Container App URL. +> [!NOTE] +> You have Owner rights on the lab subscription, and the agent typically provisions into a resource group it creates. To deploy into your pre-created lab resource group instead, add `resource group: ` to the plan prompt. + +> [!TIP] +> If the .NET container build fails with a **Six Labors (ImageSharp) license** error: Release builds of ImageSharp 3.2+ require a license key. Get a free community key from and set the `SixLaborsLicenseKey` build property — or instruct the agent to publish a Debug build for this lab. + > [!TIP] -> If a deployment step fails, use GitHub Copilot CLI to help diagnose and fix the error before retrying. +> If a deployment step fails, use GitHub Copilot CLI to help diagnose and fix the error before retrying — the Azure MCP server you configured in Challenge 1 (`.github/mcp.json`) gives it the tools to inspect your Azure resources. > [!NOTE] -> Plan generation and execution can each take a while (roughly 15–20 minutes per plan). This is a good point to take a break while the agent works. +> Plan generation and execution can each take a while (roughly 15-20 minutes per plan). This is a good point to take a break while the agent works. ## Success criteria -* A cloud modernization plan is generated for both repositories and its pull request is reviewed and merged. +* A cloud modernization plan is generated locally for both repositories, and you have reviewed each plan. * The PhotoAlbum-Java app is deployed to Azure, with its resources visible in a resource group and the Frontend Container App reachable. * The PhotoAlbum (.NET) app is deployed to Azure — creating an explicit infrastructure/deployment plan where needed — with its resources visible and the Frontend Container App reachable. * Both applications run successfully in Azure. @@ -35,7 +41,9 @@ Take the two apps you upgraded in Challenge 2 and use the modernize CLI to creat ## Learning resources * [GitHub Copilot App Modernization – create a modernization plan](https://learn.microsoft.com/azure/developer/github-copilot-app-modernization/modernization-agent/quickstart) +* [Batch plan across multiple repositories](https://learn.microsoft.com/azure/developer/github-copilot-app-modernization/modernization-agent/batch-plan) +* [Prepare infrastructure and deploy applications](https://learn.microsoft.com/azure/developer/github-copilot-app-modernization/modernization-agent/infra-deployment) * [Azure Container Apps documentation](https://learn.microsoft.com/azure/container-apps/) * [Migrate Oracle to Azure Database for PostgreSQL](https://learn.microsoft.com/azure/postgresql/migrate/) -* [GitHub Copilot CLI](https://docs.github.com/copilot/github-copilot-in-the-cli) +* [GitHub Copilot CLI](https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli) * [Azure deployment best practices](https://learn.microsoft.com/azure/architecture/) diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/docs/00-fundamentals.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/docs/00-fundamentals.md deleted file mode 100644 index c21ccd538..000000000 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/docs/00-fundamentals.md +++ /dev/null @@ -1,154 +0,0 @@ -# Module 0 — Fundamentals: Custom Agents, Skills, and MCP for App Modernization - -This module gives you the mental model you need. Read time: ~15 minutes. - ---- - -## 1. The Big Picture - -Modernization is a **multi-step, knowledge-heavy workflow**: assess → plan → execute → validate. AI coding agents are good at executing steps, but out of the box they lack: - -| Gap | Solved by | -|-----|-----------| -| A defined *role*, scope, and guardrails for the workflow | **Custom Agent** | -| Reusable *domain knowledge* (migration rules, upgrade recipes, conventions) | **Skill** | -| *Tools* to act on the real world (run AppCAT, build, scan CVEs, deploy) | **MCP server** | - -```mermaid -flowchart LR - U[User prompt] --> A["Custom Agent
(role + workflow + guardrails)"] - A -->|loads knowledge on demand| S["Skills
(SKILL.md files)"] - A -->|calls tools| M["MCP Servers
(assessment, build, CVE, deploy)"] - M --> R[(Real systems:
code, Azure, registries)] -``` - -**Rule of thumb:** -- *Agent* = **who** is working and **how** the workflow runs. -- *Skill* = **what** the agent knows (loaded only when relevant — progressive disclosure). -- *MCP* = **what** the agent can do (tools with typed inputs/outputs). - ---- - -## 2. Custom Agents (`.agent.md`) - -A Custom Agent is a markdown file with YAML frontmatter, placed in `.github/agents/` (repo-scoped) or your user profile. It defines: - -| Element | Purpose | -|---------|---------| -| `description` | When the agent should be picked (shown in agent picker / used for routing) | -| `tools` | Allow-list of tools the agent may use (limits blast radius) | -| Body (markdown) | System-prompt-like instructions: persona, workflow stages, gates, output format | - -### Why custom agents matter for modernization - -- **Phased workflows with gates** — e.g., "do not modify code until the assessment report is approved by the user." -- **Tool restriction** — an *assessment* agent gets read-only tools; an *execution* agent gets build/edit tools. -- **Consistency across teams** — every team modernizes with the same playbook. - -### Minimal anatomy - -```markdown ---- -description: One-line routing description for this agent -tools: ['codebase', 'search', 'runCommands', 'editFiles'] ---- - -# Role -You are a specialized in . - -# Workflow -1. Assess … (STOP and ask for approval) -2. Plan … -3. Execute … -4. Validate … - -# Guardrails -- Never … / Always … -``` - ---- - -## 3. Skills (`SKILL.md`) - -A Skill is a folder containing a `SKILL.md` (plus optional supporting files: scripts, rule books, examples). The agent reads the skill **only when the task matches its description** — this keeps context lean (progressive disclosure). - -| Element | Purpose | -|---------|---------| -| `name` | Unique skill identifier | -| `description` | **Critical**: trigger phrases — "WHEN: upgrade Spring Boot, fix CVE…" — that route tasks to this skill | -| Body | The actual instructions: steps, rules, decision tables, command references | -| Supporting files | Migration rulebooks, code-mapping tables, validation scripts | - -### Modernization-specific skill examples - -- "Struts → Spring MVC transformation rules" -- ".NET Framework → .NET 9 breaking-changes checklist" -- "Containerization plan generator for legacy apps" -- "Integration test layers for migrated apps (TestContainers → smoke → Azure → behavioral)" - -**Skill vs Agent:** A skill is *knowledge a task can pull in*; an agent is *an actor that orchestrates tasks*. Agents typically reference several skills. - ---- - -## 4. MCP — Model Context Protocol - -MCP is an open protocol that exposes **tools, resources, and prompts** from a server to any MCP-capable client (VS Code, CLI agents). Configuration lives in `.vscode/mcp.json` (workspace) or user settings. - -```jsonc -{ - "servers": { - "my-server": { - "type": "stdio", // or "http" / "sse" for remote servers - "command": "npx", - "args": ["-y", "@scope/my-mcp-server"], - "env": { "API_KEY": "${input:api-key}" } - } - } -} -``` - -### Modernization-specific MCP tooling - -The GitHub Copilot **app modernization** extensions register MCP tools the agent can call directly: - -| Tool family (examples) | Stage | What it does | -|---|---|---| -| `appmod-run-assessment-*`, `appmod-dotnet-run-assessment` (AppCAT) | Assess | Scans code for cloud-readiness & migration issues | -| `appmod-get-plan`, `appmod-recommend-migration-tasks` | Plan | Generates plan.md / tasks.json | -| `appmod-dotnet-build-project`, `appmod-install-maven`, `appmod-install-jdk` | Execute | Build & toolchain management | -| `appmod-dotnet-cve-check`, `appmod-java-cve-assessment` | Validate | Dependency vulnerability scans | -| `appmod-generate-k8s-manifest`, `appmod-plan-generate-dockerfile`, `appmod-scan-docker-image` | Deploy | Containerization & deployment artifacts | -| Azure MCP server (`azure-mcp`) | Deploy | Resource queries, quotas, deployments, diagnostics | - -> You don't need to write an MCP server for this MicroHack — you will **configure** existing ones and let your custom agent call them. - ---- - -## 5. Putting It Together — the Modernization Loop - -```mermaid -sequenceDiagram - participant User - participant Agent as Custom Agent - participant Skill as Skills - participant MCP as MCP Tools - - User->>Agent: "Modernize this app to .NET 9 / Java 21" - Agent->>MCP: run assessment (AppCAT / appmod) - MCP-->>Agent: findings report - Agent->>User: 🚦 GATE — approve plan? - User->>Agent: approved - Agent->>Skill: load migration rules / upgrade recipes - Agent->>MCP: build, fix, iterate - Agent->>MCP: CVE scan + tests - Agent->>User: summary + validation evidence -``` - -Key design principles you will apply in the challenges: - -1. **Gates before writes** — the agent must pause for approval after assessment and after planning. -2. **Least-privilege tools** — only list the tools each phase needs. -3. **Skills as triggers, not dumps** — write descriptions with explicit "WHEN:" trigger phrases. -4. **Evidence-based completion** — the agent must show build output + test results + CVE scan before claiming success. - -➡️ Continue to the [templates](../templates/) and then [Challenge 1 — Fundamentals](../challenges/challenge-01.md). diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/finish.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/finish.md index 52bd508de..09c58c1fe 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/finish.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/challenges/finish.md @@ -13,23 +13,23 @@ Throughout this MicroHack, you've gained hands-on experience with the complete m - Learned how GitHub Copilot Custom Agents, Skills, and MCP servers fit together (*Agent = who/how*, *Skill = what it knows*, *MCP = what it can do*) - Authored a Custom Agent (`.agent.md`) with a phased, gated workflow and a least-privilege tool allow-list - Packaged a reusable Skill (`SKILL.md`) with an explicit `WHEN:` trigger and transformation-rules table -- Configured MCP (`mcp.json`) and confirmed the `appmod-*` tools resolve in the agent's tool picker -- Dry-ran the gated assess → plan → execute → validate loop, confirming the agent stops at the assessment and plan approval gates before editing code +- Configured MCP for GitHub Copilot CLI (`.github/mcp.json`) and confirmed the `azure` server resolves via `/mcp list` +- Dry-ran skill detection: created a plan with `modernize plan create` and confirmed your custom skill was referenced in the plan's `tasks.json` — without executing the plan ### Challenge 2: Batch Upgrade a Java App and a .NET App -- Forked the PhotoAlbum-Java (Spring Boot) and PhotoAlbum (.NET) sample repositories +- Cloned the PhotoAlbum-Java (Spring Boot) and PhotoAlbum (.NET) sample repositories and worked on a local `modernize` branch - Installed and configured the GitHub Copilot App Modernization agent (modernize CLI) - Ran a batch assessment across both repositories for Upgrade and Cloud readiness - Reviewed the aggregated and per-repository assessment reports - Upgraded the .NET app to .NET 10 and the Java app to Java 25 / Spring Boot 4.0 -- Committed and pushed the upgraded code to each repository +- Committed the upgraded code on each repository's `modernize` branch ### Challenge 3: Modernize the Upgraded Apps and Deploy Them to Azure - Created a cloud modernization plan targeting both repositories - Resolved cloud readiness issues and migrated dependencies (for example, Oracle to PostgreSQL) -- Reviewed and merged the modernization pull request +- Reviewed the locally generated plans and executed them with the modernize CLI - Provisioned Azure infrastructure and deployed the PhotoAlbum-Java app to Azure - Created an explicit infrastructure/deployment plan and deployed the PhotoAlbum (.NET) app to Azure - Validated both applications running on Azure Container Apps diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/docs/00-fundamentals.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/docs/00-fundamentals.md index 8036d27ea..d60a6ebc1 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/docs/00-fundamentals.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/docs/00-fundamentals.md @@ -31,7 +31,7 @@ flowchart LR ## 2. Custom Agents (`.agent.md`) -A Custom Agent is a markdown file with YAML frontmatter, placed in `.github/agents/` (repo-scoped) or your user profile. It defines: +A Custom Agent is a markdown file with YAML frontmatter, placed in `.github/agents/` in the target repo (picked up by GitHub Copilot CLI, VS Code, and the Copilot coding agent) or at user level in `~/.copilot/agents/` (Copilot CLI only). It defines: | Element | Purpose | |---------|---------| @@ -50,7 +50,7 @@ A Custom Agent is a markdown file with YAML frontmatter, placed in `.github/agen ```markdown --- description: One-line routing description for this agent -tools: ['codebase', 'search', 'runCommands', 'editFiles'] +tools: ['read', 'search', 'execute', 'edit'] --- # Role @@ -66,23 +66,29 @@ You are a specialized in . - Never … / Always … ``` +> Tool names are environment-specific, but the portable aliases `read`, `search`, `edit`, and `execute` work across Copilot CLI, VS Code, and the coding agent — unrecognized names are simply ignored. MCP tools are referenced as `/` or `/*`. + --- ## 3. Skills (`SKILL.md`) -A Skill is a folder containing a `SKILL.md` (plus optional supporting files: scripts, rule books, examples). The agent reads the skill **only when the task matches its description** — this keeps context lean (progressive disclosure). +A Skill is a folder containing a `SKILL.md` (plus optional supporting files: scripts, rule books, examples). Repo-level skills live in `.github/skills//SKILL.md`; personal skills in `~/.copilot/skills/` (Copilot CLI). The agent reads the skill **only when the task matches its description** — this keeps context lean (progressive disclosure). | Element | Purpose | |---------|---------| -| `name` | Unique skill identifier | +| `name` | Unique skill identifier — lowercase, hyphenated, no spaces | | `description` | **Critical**: trigger phrases — "WHEN: upgrade Spring Boot, fix CVE…" — that route tasks to this skill | | Body | The actual instructions: steps, rules, decision tables, command references | | Supporting files | Migration rulebooks, code-mapping tables, validation scripts | +### Skills are the modernize CLI's customization mechanism + +The **modernize CLI** automatically scans `.github/skills/` when you run `modernize plan create ""`: it compares your prompt with each skill's `description`, incorporates matching skills into the plan, and records them in the plan's `tasks.json` (`"skills": [{"name": …, "location": "project"}]`). This is how organization-specific migration patterns are applied consistently across repositories — and it is exactly what you verify at the end of Challenge 1. GitHub Copilot CLI picks up the same folder (`/skills list`). + ### Modernization-specific skill examples - "Struts → Spring MVC transformation rules" -- ".NET Framework → .NET 9 breaking-changes checklist" +- ".NET Framework → .NET 10 breaking-changes checklist" - "Containerization plan generator for legacy apps" - "Integration test layers for migrated apps (TestContainers → smoke → Azure → behavioral)" @@ -92,31 +98,40 @@ A Skill is a folder containing a `SKILL.md` (plus optional supporting files: scr ## 4. MCP — Model Context Protocol -MCP is an open protocol that exposes **tools, resources, and prompts** from a server to any MCP-capable client (VS Code, CLI agents). Configuration lives in `.vscode/mcp.json` (workspace) or user settings. +MCP is an open protocol that exposes **tools, resources, and prompts** from a server to any MCP-capable client. Each client reads its own configuration file — the formats are **not interchangeable**: -```jsonc +| Client | Configuration location | Format | +|---|---|---| +| **GitHub Copilot CLI** (used in this hack) | `.github/mcp.json` (committed, shared) or `.mcp.json` (local override) in the repo; `~/.copilot/mcp-config.json` (personal) | top-level `mcpServers`, `type: "local"` or `"http"` | +| VS Code | `.vscode/mcp.json` (workspace) or user settings | top-level `servers`, `type: "stdio"` or `"http"` | + +Copilot CLI does not read `.vscode/mcp.json` — author each configuration in its own client's file and format. The **GitHub MCP server is built into Copilot CLI** — you only configure additional servers, such as Azure. Copilot CLI example (`.github/mcp.json`): + +```json { - "servers": { - "my-server": { - "type": "stdio", // or "http" / "sse" for remote servers + "mcpServers": { + "azure": { + "type": "local", "command": "npx", - "args": ["-y", "@scope/my-mcp-server"], - "env": { "API_KEY": "${input:api-key}" } + "args": ["-y", "@azure/mcp@latest", "server", "start"], + "tools": ["*"] } } } ``` +In Copilot CLI, verify with `/mcp list`; project-level servers load only after you confirm folder trust. Manage personal servers with `/mcp add` or `copilot mcp add`. + ### Modernization-specific MCP tooling -The GitHub Copilot **app modernization** extensions register MCP tools the agent can call directly: +The **modernize CLI** ships its assessment, planning, build, and CVE capabilities built in — you don't configure MCP for it. In **VS Code**, the GitHub Copilot **app modernization** extensions register equivalent `appmod-*` MCP tools the agent can call directly: | Tool family (examples) | Stage | What it does | |---|---|---| | `appmod-run-assessment-*`, `appmod-dotnet-run-assessment` (AppCAT) | Assess | Scans code for cloud-readiness & migration issues | | `appmod-get-plan`, `appmod-recommend-migration-tasks` | Plan | Generates plan.md / tasks.json | | `appmod-dotnet-build-project`, `appmod-install-maven`, `appmod-install-jdk` | Execute | Build & toolchain management | -| `appmod-dotnet-cve-check`, `appmod-java-cve-assessment` | Validate | Dependency vulnerability scans | +| `appmod-dotnet-cve-check`, `appmod-cve-assessment` | Validate | Dependency vulnerability scans | | `appmod-generate-k8s-manifest`, `appmod-plan-generate-dockerfile`, `appmod-scan-docker-image` | Deploy | Containerization & deployment artifacts | | Azure MCP server (`azure-mcp`) | Deploy | Resource queries, quotas, deployments, diagnostics | @@ -133,7 +148,7 @@ sequenceDiagram participant Skill as Skills participant MCP as MCP Tools - User->>Agent: "Modernize this app to .NET 9 / Java 21" + User->>Agent: "Modernize this app to .NET 10 / Java 25" Agent->>MCP: run assessment (AppCAT / appmod) MCP-->>Agent: findings report Agent->>User: 🚦 GATE — approve plan? diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/docs/environment-setup.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/docs/environment-setup.md index d253b7d2e..911423969 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/docs/environment-setup.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/docs/environment-setup.md @@ -1,14 +1,14 @@ # Environment setup -Use GitHub Codespaces for this MicroHack unless your facilitator asks you to use a local workstation. The repository provides a dedicated development container with the required .NET, Java, Docker, Azure, GitHub, Copilot, and modernization tooling. +GitHub Codespaces is the **supported environment** for this MicroHack — use it unless your facilitator explicitly asks you to use a local workstation. The repository provides a dedicated development container with the required .NET, Java, Docker, Azure, GitHub, Copilot, and modernization tooling. ## Option A: GitHub Codespaces (recommended) ### 1. Create the Codespace 1. Sign in to [GitHub](https://github.com/) with the account that has your GitHub Copilot subscription. -1. Fork the MicroHack repository if you do not already have a fork you can modify. -1. From your fork, select **Code** > **Codespaces** > **New with options**. +1. Open the [MicroHack repository](https://github.com/microsoft/MicroHack). If your organization restricts creating Codespaces on public repositories, fork it first and continue from your fork. +1. Select **Code** > **Codespaces** > **New with options**. 1. For **Dev container configuration**, select **Azure / App Innovation / GHCP App Modernization**. 1. Create the Codespace and wait for the container setup to finish. @@ -21,6 +21,7 @@ Open a terminal in the Codespace and run: ```bash gh --version modernize --version +copilot --version az --version dotnet --version java --version @@ -44,11 +45,22 @@ gh auth login --web --git-protocol https gh auth status ``` -Follow the browser prompt and use the same GitHub account that owns your sample application forks and has GitHub Copilot access. +Follow the browser prompt and use the GitHub account that has GitHub Copilot access. > [!NOTE] > GitHub and Azure use separate authentication sessions. A successful `az login` does not sign in the modernization CLI to GitHub. +**GitHub Copilot CLI** keeps its own sign-in session, separate from GitHub CLI. Start it and sign in on first use: + +```bash +copilot +``` + +If you are not signed in, run the `/login` slash command and follow the instructions — in a Codespace this is a device-code flow: open and enter the one-time code. Verify the signed-in account with `/user`; it must be the account that has GitHub Copilot access. + +> [!NOTE] +> An explicitly exported `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, or `GITHUB_TOKEN` environment variable overrides the `/login` session (the token a Codespace injects automatically does not). If Copilot CLI reports an authentication error, unset those variables and sign in with `/login`. Classic personal access tokens (`ghp_…`) are not supported. + ### 4. Sign in to Azure Sign in with the Azure account and subscription assigned to the MicroHack: @@ -67,23 +79,42 @@ az account show --output table ## Option B: Local workstation +> [!IMPORTANT] +> Local setups are best-effort. If the modernize CLI or Copilot CLI installation fails on your workstation, switch to the recommended Codespace instead of debugging the installation during the event. + Use the [modernization agent quickstart](https://learn.microsoft.com/azure/developer/github-copilot-app-modernization/modernization-agent/quickstart) for the current platform-specific prerequisites and installation options. On Linux or macOS, install and verify the modernization CLI with: ```bash -curl -fsSL https://raw.githubusercontent.com/microsoft/modernize-cli/main/scripts/install.sh | sh +curl -fsSL https://raw.githubusercontent.com/microsoft/modernize-cli/main/scripts/install.sh | bash source ~/.bashrc modernize --version ``` -If you use Zsh, run `source ~/.zshrc` instead. On Windows, install the CLI with: +If you use Zsh, run `source ~/.zshrc` instead. On macOS or Linux you can also install it with Homebrew: + +```bash +brew tap microsoft/modernize https://github.com/microsoft/modernize-cli +brew install modernize +``` + +On Windows, install the CLI with: ```powershell winget install GitHub.Copilot.modernization.agent ``` -Open a new terminal after the Windows installation. Then authenticate and verify GitHub CLI: +Open a new terminal after the Windows installation. + +On **every platform**, also install **GitHub Copilot CLI**, which Challenge 1 uses to verify agents, skills, and MCP configuration ([installation guide](https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/install-copilot-cli)): + +```bash +npm install -g @github/copilot +copilot --version +``` + +Then authenticate and verify GitHub CLI: ```bash gh auth login @@ -92,42 +123,37 @@ gh auth status Your workstation must also provide the SDKs and tools listed in the [general prerequisites](../Readme.md#general-prerequisites). -## Fork and clone the sample applications - -Keep the sample applications in separate repositories. Challenges 2 and 3 create commits, branches, and pull requests independently for each application. +## Clone the sample applications -### 1. Create the forks +Keep the sample applications in separate repositories. Challenges 2 and 3 create commits and branches independently for each application. You do not need to fork the samples — clone them directly from `Azure-Samples` and work on a local branch, as in the [modernization agent quickstart](https://learn.microsoft.com/azure/developer/github-copilot-app-modernization/modernization-agent/quickstart). -Open both fork pages while signed in with the GitHub account used by `gh`: +### 1. Clone the repositories -- [Fork PhotoAlbum-Java](https://github.com/Azure-Samples/PhotoAlbum-Java/fork) -- [Fork PhotoAlbum](https://github.com/Azure-Samples/PhotoAlbum/fork) +In the GHCP App Modernization Codespace, the terminal starts in the hack directory. Stay there — every command in this MicroHack runs from the hack directory. Run: -Create both forks under your GitHub account or the organization assigned by your facilitator. +```bash +mkdir -p repos +git clone https://github.com/Azure-Samples/PhotoAlbum-Java.git repos/PhotoAlbum-Java +git clone https://github.com/Azure-Samples/PhotoAlbum.git repos/PhotoAlbum +``` -### 2. Clone your forks +### 2. Create a working branch -In the GHCP App Modernization Codespace, the terminal starts in the hack directory. Run: +Create a `modernize` branch in each repository — your modernization commits stay on this branch: ```bash -mkdir -p repos -cd repos - -GH_USER="$(gh api user --jq .login)" -git clone "https://github.com/${GH_USER}/PhotoAlbum-Java.git" -git clone "https://github.com/${GH_USER}/PhotoAlbum.git" +git -C repos/PhotoAlbum-Java checkout -b modernize +git -C repos/PhotoAlbum checkout -b modernize ``` -If your forks belong to an organization rather than your personal account, replace `${GH_USER}` with the organization name in both clone URLs. - -Verify that each `origin` points to your fork: +Verify both repositories: ```bash -git -C PhotoAlbum-Java remote -v -git -C PhotoAlbum remote -v +git -C repos/PhotoAlbum-Java status +git -C repos/PhotoAlbum status ``` -Do not continue until both `origin` URLs refer to repositories where you have permission to push. +Each should report `On branch modernize` with a clean working tree. `origin` points to the upstream `Azure-Samples` repositories, which are read-only for you — your work stays on the local `modernize` branch, and the challenges tell you when a push target is needed. ## Troubleshooting @@ -135,11 +161,15 @@ Do not continue until both `origin` URLs refer to repositories where you have pe | --- | --- | | `modernize: command not found` in Codespaces | Confirm that the Codespace was created with **Azure / App Innovation / GHCP App Modernization**. If it was not, delete that Codespace and create a new one with the correct configuration. If it was, rebuild the container and check the creation log for installation errors. | | `modernize: command not found` after a local installation | Open a new terminal, or reload the shell with `source ~/.bashrc` or `source ~/.zshrc`, then run `modernize --version`. | +| `copilot: command not found` | In Codespaces: confirm the Codespace uses the **Azure / App Innovation / GHCP App Modernization** configuration (it installs GitHub Copilot CLI). Locally: install it with `npm install -g @github/copilot` and open a new terminal. | +| Copilot CLI reports an authentication or authorization error | Run `/login` inside `copilot` and verify the account with `/user`. Unset any explicitly exported `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, or `GITHUB_TOKEN` variable — it overrides the signed-in session. Classic personal access tokens (`ghp_…`) are not supported. | +| A CLI installation keeps failing on a local workstation | Switch to the recommended Codespace — it has all tools preinstalled and is the supported environment for this MicroHack. | +| The .NET assessment fails with `Failed to install .NET AppCAT tool` | Run the `dotnet tool install --tool-path … dotnet-appcat` command shown in the error message, then re-run the assessment. | | `gh auth status` reports no account or the wrong account | Run `gh auth login --web --git-protocol https` and authenticate with the GitHub account that has GitHub Copilot access. | -| GitHub reports an SSO or SAML authorization error | Authorize the GitHub CLI credential for the organization through the link shown by GitHub. If repository creation through `gh` remains blocked, create the fork in the browser and clone it over HTTPS. | +| GitHub reports an SSO or SAML authorization error | Authorize the GitHub CLI credential for the organization through the link shown by GitHub, then retry the command. | | The modernization CLI reports that Copilot is unavailable | Compare the account shown by `gh auth status` with the account that owns the GitHub Copilot subscription. Sign out and back in with the licensed account if they differ. | -| A sample repository fork already exists | Reuse the existing fork. Clone it into `repos/` and confirm its `origin` with `git remote -v`. | -| `Permission denied` when pushing a sample application | The clone probably points to the upstream `Azure-Samples` repository or to the wrong account. Update `origin` to your fork before continuing. | +| A `repos/` clone already exists | Reuse it. Run `git -C status`, make sure the working tree is clean, and create the `modernize` branch if it is missing. | +| `Permission denied` when pushing a sample application | Expected — the upstream `Azure-Samples` repositories are read-only for you. Keep your commits on the local `modernize` branch; the challenges tell you when and where to publish changes. | | Azure commands use the wrong tenant or subscription | Run `az login --use-device-code`, then select the assigned subscription with `az account set --subscription ""`. | -After the tools, authentication, forks, and remotes are verified, continue with [Challenge 1](../challenges/challenge-01.md). +After the tools, authentication, and sample clones are verified, continue with [Challenge 1](../challenges/challenge-01.md). diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/lab-defaults.json b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/lab-defaults.json index 7756b356e..833726c19 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/lab-defaults.json +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/lab-defaults.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/microsoft/MicroHack/refs/heads/main/lab-defaults-schema.json", "groups": [ "GHCPUsers" ], - "deploymentType": "resourcegroup", + "deploymentType": "resourcegroup-with-subscriptionowner", "labsPerSubscription": 20, "preferredLocation": "swedencentral, norwayeast, spaincentral", "estimatedDailyCostsUsd": 10.0, diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/main.bicep b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/main.bicep deleted file mode 100644 index e69de29bb..000000000 diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/shared-deploy-lab.ps1 b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/shared-deploy-lab.ps1 index 8313009f6..343669a4f 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/shared-deploy-lab.ps1 +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/labautomation/shared-deploy-lab.ps1 @@ -26,21 +26,35 @@ param( $scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition $requiredProviders = @( - "Microsoft.Apps", + "Microsoft.App", # Azure Container Apps "Microsoft.ContainerRegistry", - "Microsoft.DBforPostgreSQL" + "Microsoft.DBforPostgreSQL", + "Microsoft.OperationalInsights", # Log Analytics - required by Container Apps environments + "Microsoft.ManagedIdentity" # identities used by ACA/ACR deployments ) foreach($provider in $requiredProviders) { - $state = (Get-AzResourceProvider -ProviderNamespace $provider -ErrorAction SilentlyContinue | Select-Object -First 1).RegistrationState - if($state -ne "Registered") { + $unregistered = Get-AzResourceProvider -ProviderNamespace $provider -ErrorAction SilentlyContinue | + Where-Object { $_.RegistrationState -ne "Registered" } + if($unregistered) { Write-Host "[$SubscriptionId] Registering resource provider: $provider" - Register-AzResourceProvider -ProviderNamespace $provider -ErrorAction Stop + Register-AzResourceProvider -ProviderNamespace $provider -ErrorAction Stop | Out-Null } else { Write-Host "[$SubscriptionId] Resource provider $provider is already registered." } } +# Register-AzResourceProvider is asynchronous - wait (bounded) until every provider reports Registered, +# so the first lab deployment does not race the registration (MissingSubscriptionRegistration). +$deadline = (Get-Date).AddMinutes(10) +foreach($provider in $requiredProviders) { + while((Get-Date) -lt $deadline -and (Get-AzResourceProvider -ProviderNamespace $provider -ErrorAction SilentlyContinue | + Where-Object { $_.RegistrationState -ne "Registered" })) { + Write-Host "[$SubscriptionId] Waiting for $provider registration to complete..." + Start-Sleep -Seconds 15 + } +} + <# # EXAMPLE: shared resources, e.g. hub networks, bastion host, etc. can be deployed here... diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/dotnet-modernization.agent.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/dotnet-modernization.agent.md index e77529a59..cdb38eeb3 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/dotnet-modernization.agent.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/dotnet-modernization.agent.md @@ -1,15 +1,16 @@ --- description: >- .NET modernization agent: assess a legacy .NET Framework application with - AppCAT, plan the upgrade to .NET 9, execute the migration task-by-task, and + AppCAT, plan the upgrade to .NET 10, execute the migration task-by-task, and validate with build, tests, and CVE scan. Gated workflow — never edits code before assessment and plan are approved. tools: - - 'codebase' + # Portable core (Copilot CLI, VS Code, coding agent): + - 'read' - 'search' - - 'editFiles' - - 'runCommands' - - 'problems' + - 'edit' + - 'execute' + # Registered by the VS Code appmod extensions (ignored in environments without them): - 'appmod-dotnet-install-appcat' - 'appmod-dotnet-run-assessment' - 'appmod-get-plan' @@ -27,7 +28,7 @@ tools: You are a **senior .NET modernization engineer** responsible for modernizing **{{APPLICATION — e.g. "Contoso Expenses (ASP.NET MVC)"}}** from -**.NET Framework 4.8** to **.NET 9** {{TARGET_HOST — e.g. "on Azure Container Apps"}}. +**.NET Framework 4.8** to **.NET 10** {{TARGET_HOST — e.g. "on Azure Container Apps"}}. # Scope @@ -47,7 +48,7 @@ You are a **senior .NET modernization engineer** responsible for modernizing ## Phase 2 — Plan 1. Build `PLAN.md` from assessment findings (`appmod-get-plan` / `appmod-recommend-migration-tasks`): ordered tasks, acceptance criteria, rollback note per task. -2. Default order: SDK-style conversion → multi-target / retarget to net9.0 → replace +2. Default order: SDK-style conversion → multi-target / retarget to net10.0 → replace incompatible APIs → config migration (web.config → appsettings.json) → CVE fixes. > 🚦 **GATE 2**: Present `PLAN.md` and STOP for approval. diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/java-modernization.agent.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/java-modernization.agent.md index 8c61062bf..c1266617e 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/java-modernization.agent.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/java-modernization.agent.md @@ -1,15 +1,16 @@ --- description: >- Java modernization agent: assess a legacy Java/Spring Boot application, plan - the upgrade to Java 21 + Spring Boot 3, execute incrementally, and validate + the upgrade to Java 25 + Spring Boot 4, execute incrementally, and validate with build, tests, and CVE assessment. Gated workflow — never edits code before assessment and plan are approved. tools: - - 'codebase' + # Portable core (Copilot CLI, VS Code, coding agent): + - 'read' - 'search' - - 'editFiles' - - 'runCommands' - - 'problems' + - 'edit' + - 'execute' + # Registered by the VS Code appmod extensions (ignored in environments without them): - 'appmod-run-assessment-action' - 'appmod-run-assessment-report' - 'appmod-get-plan' @@ -18,7 +19,7 @@ tools: - 'appmod-install-jdk' - 'appmod-list-mavens' - 'appmod-install-maven' - - 'appmod-java-cve-assessment' + - 'appmod-cve-assessment' # Optional containerization phase: # - 'appmod-get-containerization-plan' # - 'appmod-plan-generate-dockerfile' @@ -31,7 +32,7 @@ tools: You are a **senior Java modernization engineer** responsible for upgrading **{{APPLICATION — e.g. "Fabrikam Orders (Spring Boot 2.3, Maven)"}}** from **Java {{SOURCE_JAVA — e.g. 8}} / Spring Boot {{SOURCE_BOOT — e.g. 2.3}}** to -**Java 21 / Spring Boot 3.x** {{TARGET_HOST — e.g. "for Azure Container Apps"}}. +**Java 25 / Spring Boot 4.x** {{TARGET_HOST — e.g. "for Azure Container Apps"}}. # Scope @@ -45,7 +46,7 @@ You are a **senior Java modernization engineer** responsible for upgrading ## Phase 1 — Assess (read-only) 1. Inventory: modules, `pom.xml`/`build.gradle`, Java version, Boot version, key dependencies. 2. Run assessment (`appmod-run-assessment-action` → `appmod-run-assessment-report`) - and CVE assessment (`appmod-java-cve-assessment`). + and CVE assessment (`appmod-cve-assessment`). 3. Produce `ASSESSMENT.md`: findings by severity (🔴/🟡/🟢), CVE table, effort estimates, blockers. > 🚦 **GATE 1**: Present `ASSESSMENT.md` and STOP for explicit approval. @@ -53,7 +54,8 @@ You are a **senior Java modernization engineer** responsible for upgrading ## Phase 2 — Plan 1. Generate `PLAN.md` (+ `tasks.json` via `appmod-get-plan` / `appmod-recommend-migration-tasks`). 2. Default incremental order — never jump versions in one step: - Java 8 → 11 → 17 → 21, then Boot 2.x → 2.7 → 3.x (jakarta rename happens at 3.0). + Java 8 → 11 → 17 → 21 → 25, then Boot 2.x → 2.7 → 3.x → 4.x + (jakarta rename happens at 3.0; clean up 3.x deprecations before 4.0). 3. Each task: acceptance criteria + rollback note. > 🚦 **GATE 2**: Present `PLAN.md` and STOP for approval. @@ -65,8 +67,8 @@ You are a **senior Java modernization engineer** responsible for upgrading 4. Keep changes commit-sized; never mix version bumps with refactoring. ## Phase 4 — Validate -1. Full build zero errors on Java 21; all tests pass: `mvn clean verify`. -2. Re-run `appmod-java-cve-assessment`; fix criticals/highs or document waivers. +1. Full build zero errors on the target JDK (Java 25); all tests pass: `mvn clean verify`. +2. Re-run `appmod-cve-assessment`; fix criticals/highs or document waivers. 3. Smoke-test app startup ({{SMOKE_TEST — e.g. "actuator /health returns UP"}}). 4. Produce `VALIDATION.md`: build summary, test results, CVE before/after table, residual risks. diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/modernization.agent.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/modernization.agent.md index 62c33bd90..f2c454947 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/modernization.agent.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/agents/modernization.agent.md @@ -4,18 +4,20 @@ description: >- assess, plan, execute, and validate the migration to ."}} tools: # ── Allow-list ONLY the tools this agent needs (least privilege) ── - - 'codebase' # workspace search & read - - 'search' # text/grep search - - 'editFiles' # remove for assessment-only agents - - 'runCommands' # terminal — remove if the agent must not execute anything - - 'problems' # compile/lint errors - # - '{{MCP_TOOL_1}}' # e.g. appmod-run-assessment-action + # Portable names (Copilot CLI, VS Code, coding agent — unrecognized names are ignored): + - 'read' # read files in the workspace + - 'search' # grep/glob search + - 'edit' # remove for assessment-only agents + - 'execute' # shell/terminal — remove if the agent must not run anything + # - 'azure/*' # all tools from the 'azure' MCP server (.github/mcp.json) — use '/' for single tools + # - '{{MCP_TOOL_1}}' # e.g. appmod-run-assessment-action (registered by the VS Code appmod extensions; ignored elsewhere) # - '{{MCP_TOOL_2}}' # e.g. appmod-dotnet-build-project --- @@ -23,7 +25,7 @@ tools: You are a **{{ROLE — e.g. "senior .NET modernization engineer"}}** responsible for modernizing **{{APPLICATION}}** from **{{SOURCE — e.g. .NET Framework 4.8 / Java 8 + Struts}}** -to **{{TARGET — e.g. .NET 9 on Azure Container Apps / Java 21 + Spring Boot 3 on AKS}}**. +to **{{TARGET — e.g. .NET 10 on Azure Container Apps / Java 25 + Spring Boot 4 on AKS}}**. # Scope diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/README.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/README.md new file mode 100644 index 000000000..56b668c7e --- /dev/null +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/README.md @@ -0,0 +1,28 @@ +# MCP configuration templates + +Two templates for the two MCP-capable clients used in this MicroHack. **The formats are not interchangeable** — Copilot CLI does not read `.vscode/mcp.json` (it uses the unsupported top-level key `servers`), and VS Code's documented locations are `.vscode/mcp.json` and user settings, not the Copilot CLI files. + +| Template | Client | Copy to | Verify with | +|---|---|---|---| +| [copilot-cli-mcp.json](copilot-cli-mcp.json) | **GitHub Copilot CLI** (used in this hack) | `/.github/mcp.json` | `/mcp list` inside `copilot` | +| [mcp.json](mcp.json) | VS Code | `/.vscode/mcp.json` | **MCP: List Servers** in the Command Palette | + +## copilot-cli-mcp.json (GitHub Copilot CLI) + +- Top-level key is `mcpServers`; each server is `type: "local"` (stdio command) or `type: "http"` (remote URL). `tools` is an allow-list — `["*"]` enables all tools from that server. +- The **GitHub MCP server is built into Copilot CLI** — do not add an entry for it. +- The `azure` server uses your `az login` context; optionally pin a subscription by adding `"AZURE_SUBSCRIPTION_ID": ""` to `env`. Never commit secrets — this file is meant to be committed to the repo. +- Configuration levels (highest precedence first): + 1. `.mcp.json` — local, per-checkout (not committed), + 2. `.github/mcp.json` — shared project config, committed to the repo, + 3. `~/.copilot/mcp-config.json` — your personal servers; manage with `/mcp add` (interactive form) or `copilot mcp add -- `. +- Project-level servers are loaded only after you confirm **folder trust** on first launch of `copilot` in the repo. +- Reference MCP tools in an agent's `tools:` list as `/` or `/*` (for example `azure/*`). + +## mcp.json (VS Code) + +- VS Code JSONC format: top-level `servers` key, `type: "stdio"` or `"http"`, plus `inputs` for prompted values. +- The `appmod-*` tool families are **not** MCP servers you configure — they are registered automatically by the GitHub Copilot app modernization VS Code extensions. Install the extension for your stack (.NET or Java). +- After editing, run **MCP: List Servers** and start/inspect the servers. + +Docs: [Add MCP servers to Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers) · [MCP servers in VS Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/copilot-cli-mcp.json b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/copilot-cli-mcp.json new file mode 100644 index 000000000..c4991261a --- /dev/null +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/copilot-cli-mcp.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "azure": { + "type": "local", + "command": "npx", + "args": ["-y", "@azure/mcp@latest", "server", "start"], + "env": {}, + "tools": ["*"] + } + } +} diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/mcp.json b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/mcp.json index 17c1849f0..f22c5623d 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/mcp.json +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/mcp/mcp.json @@ -1,8 +1,10 @@ { - // MCP SERVER CONFIGURATION TEMPLATE — App Modernization + // MCP SERVER CONFIGURATION TEMPLATE — App Modernization (VS CODE VARIANT) // Copy to: /.vscode/mcp.json + // For the CLI-first path (GitHub Copilot CLI) use copilot-cli-mcp.json instead — + // Copilot CLI does not read .vscode/mcp.json. See README.md in this folder. // Replace {{PLACEHOLDER}} values. Remove servers you don't need. - // Docs: https://code.visualstudio.com/docs/copilot/chat/mcp-servers + // Docs: https://code.visualstudio.com/docs/copilot/customization/mcp-servers "inputs": [ { // Prompted once and stored securely — never hardcode secrets here. diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/dotnet-upgrade/SKILL.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/dotnet-upgrade/SKILL.md index d2241a5cb..109bb2890 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/dotnet-upgrade/SKILL.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/dotnet-upgrade/SKILL.md @@ -2,25 +2,25 @@ name: dotnet-upgrade description: >- Transformation rules and verification steps for upgrading .NET Framework 4.x - applications to .NET 9. - WHEN: upgrade to .NET 9, migrate .NET Framework, retarget TFM, convert to + applications to .NET 10. + WHEN: upgrade to .NET 10, migrate .NET Framework, retarget TFM, convert to SDK-style project, System.Web replacement, web.config migration, packages.config to PackageReference, binding redirect cleanup. NOT for: greenfield .NET apps, NuGet version bumps within the same TFM, Azure infrastructure changes. --- -# .NET Framework 4.x → .NET 9 Upgrade Rules +# .NET Framework 4.x → .NET 10 Upgrade Rules ## Purpose Packages the API mappings, project-file rules, and verification checklist needed to -retarget a .NET Framework app to .NET 9 without behavioral change. +retarget a .NET Framework app to .NET 10 without behavioral change. ## Prerequisites - `ASSESSMENT.md` exists and is approved (AppCAT findings available). -- .NET 9 SDK installed — verify: `dotnet --list-sdks`. +- .NET 10 SDK installed — verify: `dotnet --list-sdks`. ## Procedure @@ -33,11 +33,11 @@ upgrade-assistant upgrade .\src\{{Project}}.csproj - Migrate `packages.config` → `PackageReference`. - Delete `AssemblyInfo.cs` attributes now generated by the SDK. -- Remove binding redirects from app/web.config (not honored on .NET 9). +- Remove binding redirects from app/web.config (not honored on .NET 10). ### Step 2 — Apply API transformation rules -| Source pattern (.NET Framework) | Target pattern (.NET 9) | Notes | +| Source pattern (.NET Framework) | Target pattern (.NET 10) | Notes | |---|---|---| | `System.Web.Mvc` controllers | `Microsoft.AspNetCore.Mvc` | Routing moves to endpoint routing | | `Global.asax` / `HttpModule` | ASP.NET Core middleware in `Program.cs` | Order matters — replicate pipeline order | @@ -45,7 +45,7 @@ upgrade-assistant upgrade .\src\{{Project}}.csproj | `ConfigurationManager.AppSettings` | `IConfiguration` via DI | Inject, don't service-locate | | `HttpContext.Current` | `IHttpContextAccessor` | Audit for thread-safety assumptions | | WCF server (`System.ServiceModel`) | CoreWCF **or** gRPC/REST | Decision required — escalate to user | -| EF6 `ObjectContext`/EDMX | EF Core (or EF6 on .NET 9 as interim) | EDMX must be re-scaffolded for EF Core | +| EF6 `ObjectContext`/EDMX | EF Core (or EF6 on .NET 10 as interim) | EDMX must be re-scaffolded for EF Core | | `System.Drawing` (non-Windows) | `ImageSharp` / `SkiaSharp` | `System.Drawing.Common` is Windows-only | | {{APP_SPECIFIC_RULE_1}} | {{TARGET_1}} | {{NOTE}} | | {{APP_SPECIFIC_RULE_2}} | {{TARGET_2}} | {{NOTE}} | @@ -61,7 +61,7 @@ upgrade-assistant upgrade .\src\{{Project}}.csproj ## Common Pitfalls - ⚠️ **Upgrading hub projects first** — always go leaf-first in the dependency graph, or you'll chase cascading build breaks. -- ⚠️ **`AppContext` switches / legacy config quirks** silently ignored on .NET 9 — search config for `` elements and review each. +- ⚠️ **`AppContext` switches / legacy config quirks** silently ignored on .NET 10 — search config for `` elements and review each. - ⚠️ **Culture-sensitive string APIs** changed defaults (ICU vs NLS) — pin `InvariantGlobalization` consciously, don't copy-paste it. - ⚠️ {{APP_SPECIFIC_PITFALL}} diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/java-upgrade/SKILL.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/java-upgrade/SKILL.md index 2df4d0511..4572f92be 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/java-upgrade/SKILL.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/java-upgrade/SKILL.md @@ -2,25 +2,25 @@ name: java-upgrade description: >- Transformation rules and verification steps for upgrading Java 8/11 + - Spring Boot 2.x applications to Java 21 + Spring Boot 3.x. + Spring Boot 2.x applications to Java 25 + Spring Boot 4.x. WHEN: upgrade Java version, migrate Spring Boot 2 to 3, javax to jakarta, - fix CVE in Java dependencies, update Maven/Gradle build for Java 21, - Spring Security 5 to 6 migration. + fix CVE in Java dependencies, update Maven/Gradle build for Java 25, + Spring Security 5 to 6 migration, Spring Boot 3 to 4 migration. NOT for: greenfield Java services, framework replacement rewrites (Struts/EJB — use dedicated migration rulebooks), infrastructure-only changes. --- -# Java 8 / Spring Boot 2.x → Java 21 / Spring Boot 3.x Upgrade Rules +# Java 8 / Spring Boot 2.x → Java 25 / Spring Boot 4.x Upgrade Rules ## Purpose Packages the version-step strategy, API mappings, and verification checklist for a -behavior-preserving upgrade to Java 21 + Spring Boot 3.x. +behavior-preserving upgrade to Java 25 + Spring Boot 4.x. ## Prerequisites - `ASSESSMENT.md` exists and is approved. -- JDK 21 + compatible Maven installed — verify: `java -version`, `mvn -version`. +- Target JDK + compatible Maven installed — verify: `java -version`, `mvn -version`. ## Procedure @@ -31,8 +31,10 @@ behavior-preserving upgrade to Java 21 + Spring Boot 3.x. | 1 | Java 8 → 11 | Removed JEE modules (JAXB, JAX-WS) — add explicit deps | | 2 | Java 11 → 17 | Strong encapsulation of JDK internals (`--add-opens` smells) | | 3 | Java 17 → 21 | Mostly safe; check agents/bytecode libs (ASM, CGLIB versions) | -| 4 | Boot 2.x → 2.7 | Deprecation cleanup before the big jump | -| 5 | Boot 2.7 → 3.x | `javax → jakarta`, Spring Security 6, Hibernate 6 | +| 4 | Java 21 → 25 | Recheck bytecode/agent libs and build-plugin versions for the new class-file level | +| 5 | Boot 2.x → 2.7 | Deprecation cleanup before the big jump | +| 6 | Boot 2.7 → 3.x | `javax → jakarta`, Spring Security 6, Hibernate 6 | +| 7 | Boot 3.x → 4.x | APIs deprecated in 3.x are removed — clean up all deprecation warnings first | ```powershell mvn -q clean verify # run after EVERY step; fix before proceeding @@ -54,10 +56,10 @@ mvn -q clean verify # run after EVERY step; fix before proceeding ### Step 3 — Verify -- [ ] `mvn clean verify` passes on JDK 21 +- [ ] `mvn clean verify` passes on the target JDK (Java 25) - [ ] `grep -r "javax\." src/` returns only intentional matches (e.g. `javax.crypto`, `javax.sql` stay in the JDK) - [ ] App starts; health endpoint returns UP -- [ ] CVE assessment clean of criticals (`appmod-java-cve-assessment`) +- [ ] CVE assessment clean of criticals (`appmod-cve-assessment`) - [ ] No `--add-opens` workarounds left without a tracked issue ## Common Pitfalls @@ -70,6 +72,6 @@ mvn -q clean verify # run after EVERY step; fix before proceeding ## References -- Spring Boot 3.x migration guide; Spring Security 6 migration guide +- Spring Boot 3.x and 4.x migration guides; Spring Security 6 migration guide - OpenRewrite recipes: `org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_x` - appmod assessment report (linked from `ASSESSMENT.md`) diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/modernization-skill/SKILL.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/modernization-skill/SKILL.md index 369f22c3a..93287a8ad 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/modernization-skill/SKILL.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/modernization-skill/SKILL.md @@ -1,9 +1,9 @@ --- -name: {{skill-name-kebab-case}} +name: "{{skill-name-kebab-case}}" description: >- {{WHAT this skill does in one sentence.}} WHEN: {{trigger phrase 1}}, {{trigger phrase 2}}, {{trigger phrase 3}}, - {{e.g. "upgrade .NET Framework to .NET 9", "migrate Struts to Spring MVC", + {{e.g. "upgrade .NET Framework to .NET 10", "migrate Struts to Spring MVC", "fix CVE vulnerabilities", "containerize legacy app"}}. NOT for: {{explicit exclusions — prevents false triggering, e.g. "greenfield development, infrastructure-only changes"}}. @@ -12,11 +12,14 @@ description: >- -# {{Skill Title — e.g. ".NET Framework → .NET 9 Migration Rules"}} +# {{Skill Title — e.g. ".NET Framework → .NET 10 Migration Rules"}} ## Purpose @@ -25,7 +28,7 @@ description: >- ## Prerequisites - {{e.g. "Assessment report (ASSESSMENT.md) exists"}} -- {{e.g. ".NET 9 SDK installed — verify with `dotnet --list-sdks`"}} +- {{e.g. ".NET 10 SDK installed — verify with `dotnet --list-sdks`"}} ## Procedure @@ -51,7 +54,7 @@ description: >- ## Common Pitfalls -- ⚠️ {{pitfall + how to avoid — e.g. "binding redirects are not honored in .NET 9; delete them and use the SDK-style project resolution"}} +- ⚠️ {{pitfall + how to avoid — e.g. "binding redirects are not honored in .NET 10; delete them and use the SDK-style project resolution"}} - ⚠️ {{pitfall + how to avoid}} ## References diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/skill-creator/FUNDAMENTALS.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/skill-creator/FUNDAMENTALS.md index 9ce36f70f..19cb5c41a 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/skill-creator/FUNDAMENTALS.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/templates/skills/skill-creator/FUNDAMENTALS.md @@ -58,7 +58,7 @@ Simple one-step requests ("read this file") won't trigger a skill no matter how | General patterns | Overfitting to one example | | Exact output templates | Vague "format nicely" | -Modern models have good theory of mind: a rule with a reason ("delete binding redirects — .NET 9 ignores them and they mask resolution errors") generalizes far better than a bare command. +Modern models have good theory of mind: a rule with a reason ("delete binding redirects — .NET 10 ignores them and they mask resolution errors") generalizes far better than a bare command. ## 5. The create → test → iterate loop diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-01/solution-01.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-01/solution-01.md index 0c7eaea21..6125ec7a8 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-01/solution-01.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-01/solution-01.md @@ -2,11 +2,13 @@ **[Home](../../Readme.md)** - [Next Challenge Solution](../challenge-02/solution-02.md) -**Duration:** 30 minutes +**Duration:** 40 minutes ## Goal -Author a reusable, gated modernization Custom Agent, package a Skill, and configure the MCP tools that back the assess → plan → execute → validate loop used in the .NET and Java challenges. +Author a reusable, gated modernization Custom Agent, package a Skill, configure MCP for GitHub Copilot CLI, and dry-run skill detection with the modernize CLI — the foundation of the assess → plan → execute → validate loop used in the .NET and Java challenges. + +All files are authored in the **target repository** `repos/PhotoAlbum-Java` (cloned during [environment setup](../../docs/environment-setup.md)). The commands below assume the Codespace terminal, which starts in the hack directory. ## Actions @@ -17,44 +19,113 @@ Author a reusable, gated modernization Custom Agent, package a Skill, and config - **Agent** = *who* is working and *how* the workflow runs (role + gates + tool allow-list). - **Skill** = *what* the agent knows (loaded only when the task matches — progressive disclosure). - **MCP** = *what* the agent can do (tools with typed inputs/outputs). +3. Everything lives under `.github/` in the target repo, so it is versioned with the code: `.github/agents/`, `.github/skills/`, `.github/mcp.json`. ### Author a Custom Agent -1. Copy [templates/agents/modernization.agent.md](../../templates/agents/modernization.agent.md) into your target repo at `.github/agents/modernization.agent.md`. +1. Copy [templates/agents/modernization.agent.md](../../templates/agents/modernization.agent.md) into the target repo: + + ```bash + cd repos/PhotoAlbum-Java + mkdir -p .github/agents + cp "../../templates/agents/modernization.agent.md" .github/agents/modernization.agent.md + ``` + 2. Replace every `{{PLACEHOLDER}}`: role, application, source/target platform, in/out of scope. -3. Keep the phased workflow with **Gate 1 (after assessment)** and **Gate 2 (after plan)**. -4. Trim the `tools:` allow-list to least privilege — the assess phase should *not* include `editFiles`. -5. Reload VS Code and confirm the agent appears in the Copilot Chat agent picker. +3. Keep the phased workflow with **Gate 1 (after assessment)** and **Gate 2 (after plan)** — the gate instructions in the body are what stop the agent from editing code before approval. +4. Trim the `tools:` allow-list to least privilege. The list applies to the whole agent, so keep it minimal: an assessment-only agent needs `read` and `search`; add `edit` and `execute` only when the agent is meant to change code and run builds. +5. Verify in Copilot CLI — start it inside the repo and confirm **folder trust** when prompted (you are asked once per folder), then open the agent picker: + + ```bash + copilot + ``` + + Type `/agent` and confirm your agent is listed. The sample repo ships with a few pre-existing example agents — yours appears alongside them; ignore the others. You can also invoke it non-interactively: + + ```bash + copilot --agent=modernization --prompt "Summarize your workflow phases and gates." + ``` > ✅ Reference answer: [templates/agents/dotnet-modernization.agent.md](../../templates/agents/dotnet-modernization.agent.md) and [templates/agents/java-modernization.agent.md](../../templates/agents/java-modernization.agent.md). ### Author a Skill -1. Copy [templates/skills/modernization-skill/SKILL.md](../../templates/skills/modernization-skill/SKILL.md) to `.github/skills//SKILL.md`. -2. Write the `description` as a routing contract: start it with an explicit `WHEN:` list of trigger phrases, and add a `NOT for:` line to prevent false triggering. +1. Copy [templates/skills/modernization-skill/SKILL.md](../../templates/skills/modernization-skill/SKILL.md) into the target repo — the skill folder name must be lowercase and hyphenated: + + ```bash + mkdir -p .github/skills/java-upgrade-playbook + cp "../../templates/skills/modernization-skill/SKILL.md" .github/skills/java-upgrade-playbook/SKILL.md + ``` + +2. Set the frontmatter `name:` to match the folder (`java-upgrade-playbook`), then write the `description` as a routing contract: start it with an explicit `WHEN:` list of trigger phrases, and add a `NOT for:` line to prevent false triggering. Both Copilot CLI and the modernize CLI use this description to decide when the skill applies — vague descriptions ("improve code") are never matched. 3. Fill in the **Procedure** with at least one transformation-rules table (source pattern → target pattern → notes) and a verification checklist. -4. (Optional) Use the [skill-creator](../../templates/skills/skill-creator/SKILL.md) meta-skill to test and iterate on the description. +4. Verify in Copilot CLI: run `/skills list` and confirm the skill appears as a project skill. +5. (Optional) Use the [skill-creator](../../templates/skills/skill-creator/SKILL.md) meta-skill to test and iterate on the description. > ✅ Reference answers: [templates/skills/dotnet-upgrade/SKILL.md](../../templates/skills/dotnet-upgrade/SKILL.md) and [templates/skills/java-upgrade/SKILL.md](../../templates/skills/java-upgrade/SKILL.md). -### Configure MCP +### Configure MCP for Copilot CLI + +1. Copy [templates/mcp/copilot-cli-mcp.json](../../templates/mcp/copilot-cli-mcp.json) to `.github/mcp.json` in the target repo: + + ```bash + cp "../../templates/mcp/copilot-cli-mcp.json" .github/mcp.json + ``` + +2. Start `copilot` in the repo. Project-level MCP servers are only loaded in trusted folders — you confirmed folder trust during the agent step (if not, confirm it now). +3. Run `/mcp list`: the `azure` server from `.github/mcp.json` appears. The GitHub MCP server is built into Copilot CLI and needs no configuration entry (depending on the CLI version it may not show in the list). +4. Know the configuration levels: `.github/mcp.json` is the shared, committed project config; `.mcp.json` is a local, per-checkout override; `~/.copilot/mcp-config.json` holds your personal servers (manage it with `/mcp add` or `copilot mcp add`). Project definitions take precedence over personal ones. + +> 💻 **VS Code route:** VS Code uses its own format and file — copy [templates/mcp/mcp.json](../../templates/mcp/mcp.json) to `.vscode/mcp.json` and run **MCP: List Servers** in the Command Palette. The two formats are not interchangeable — Copilot CLI does not read `.vscode/mcp.json`. The `appmod-*` tool families are registered by the GitHub Copilot app modernization VS Code extensions (install the one for your stack; no MCP entry needed). + +### Dry-run skill detection with the modernize CLI + +1. From the target repo root, create a plan with a prompt that matches your skill's description — create the plan only, do **not** execute it: + + ```bash + modernize plan create "upgrade this app to the latest Java LTS and Spring Boot version" --plan-name fundamentals-dry-run + ``` + + Answer the clarifying questions the agent asks. Plan generation takes a few minutes. + +2. Confirm your skill was detected — the plan's `tasks.json` references project skills by name: + + ```bash + grep -rn "java-upgrade-playbook" .github/modernize* + ``` + + Expected (inside `tasks.json`): + + ```json + "skills": [ + { "name": "java-upgrade-playbook", "location": "project" } + ] + ``` + + > If grep reports `No such file or directory`, no plan folder exists yet — make sure `modernize plan create` completed successfully before searching. + +3. If the skill is not referenced: make the skill `description` more specific (or the prompt closer to it), then re-run with `--overwrite`. Check that the YAML front matter parses and the skill name contains no spaces. +4. **Stop here.** Executing plans is the subject of challenges 2 and 3. Commit your authored files so the repository is clean before Challenge 2 (the modernize CLI git-ignores its own plan folders, so they stay out of the commit): -1. Copy [templates/mcp/mcp.json](../../templates/mcp/mcp.json) to `.vscode/mcp.json`. -2. Remove servers you don't need; keep `azure` and `github` if relevant. -3. Open the Command Palette → **MCP: List Servers** and start/inspect the servers. -4. Confirm the `appmod-*` tool families appear in the agent's tool picker — they are registered automatically by the GitHub Copilot app modernization extensions (install the extension for your stack; no `mcp.json` entry needed). + ```bash + git add .github + git commit -m "Add modernization agent, skill, and MCP config" + ``` ## Success Criteria - ✅ You can explain Agent vs Skill vs MCP in one sentence each -- ✅ A valid `.agent.md` exists with a gated, phased workflow and a least-privilege tool list -- ✅ A valid `SKILL.md` exists with an explicit `WHEN:` trigger description and a rules table -- ✅ `.vscode/mcp.json` resolves via **MCP: List Servers**; `appmod-*` tools are visible to the agent +- ✅ A valid `.agent.md` exists in `.github/agents/` with a gated, phased workflow and a least-privilege tool list, and `/agent` in Copilot CLI lists it +- ✅ A valid `SKILL.md` exists in `.github/skills//` with an explicit `WHEN:` trigger description and a rules table, and `/skills list` shows it +- ✅ `/mcp list` in Copilot CLI shows the `azure` server from `.github/mcp.json` +- ✅ A modernize CLI plan references your skill in `tasks.json` with `"location": "project"`, and no plan has been executed ## Learning Resources -- [Custom chat modes / agents in VS Code](https://code.visualstudio.com/docs/copilot/chat/chat-modes) -- [MCP servers in VS Code](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) -- [GitHub Copilot app modernization for .NET](https://learn.microsoft.com/dotnet/core/porting/github-copilot-app-modernization-overview) +- [About custom agents](https://docs.github.com/en/copilot/concepts/agents/about-custom-agents) · [Custom agents configuration reference](https://docs.github.com/en/copilot/reference/custom-agents-configuration) +- [Add agent skills to Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills) · [Agent skills specification](https://agentskills.io/specification) +- [Add MCP servers to Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers) +- [Customize the modernization agent with your own skills](https://learn.microsoft.com/azure/developer/github-copilot-app-modernization/modernization-agent/customization) +- [GitHub Copilot app modernization for .NET](https://learn.microsoft.com/dotnet/azure/migration/appmod/overview) - [GitHub Copilot app modernization for Java](https://learn.microsoft.com/azure/developer/java/migration/migrate-github-copilot-app-modernization-for-java) - [Model Context Protocol](https://modelcontextprotocol.io/) diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/img/1.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/img/1.png deleted file mode 100644 index 740acdb2d..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/img/1.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/img/7.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/img/7.png deleted file mode 100644 index 75fea4886..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/img/7.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0030.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0030.png deleted file mode 100644 index 9d9128bfc..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0030.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0040.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0040.png deleted file mode 100644 index 4c17bf36e..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0040.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0050.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0050.png deleted file mode 100644 index 998d18f0f..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0050.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0060.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0060.png deleted file mode 100644 index 81afed1b6..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0060.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0070.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0070.png deleted file mode 100644 index 6a66c9f3c..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0070.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0080.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0080.png deleted file mode 100644 index 7a386632e..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/media/0080.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/solution-02.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/solution-02.md index fbb0b778b..dc93bf70b 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/solution-02.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-02/solution-02.md @@ -2,35 +2,26 @@ [Previous Challenge Solution](../challenge-01/solution-01.md) - **[Home](../../Readme.md)** - [Next Challenge Solution](../challenge-03/solution-03.md) -## 2.1. Fork the sample repositories +## 2.1. Verify the sample repositories -Complete the [environment setup guide](../../docs/environment-setup.md) before continuing. It explains how to start the recommended GHCP App Modernization Codespace, authenticate GitHub CLI for GitHub Copilot, authenticate Azure CLI, and verify the required tools. - -Fork both applications while signed in with the same GitHub account used by `gh`: - -- [Fork PhotoAlbum-Java](https://github.com/Azure-Samples/PhotoAlbum-Java/fork) -- [Fork PhotoAlbum](https://github.com/Azure-Samples/PhotoAlbum/fork) - -Forking the PhotoAlbum sample repositories +Complete the [environment setup guide](../../docs/environment-setup.md) before continuing. It explains how to start the recommended GHCP App Modernization Codespace, authenticate GitHub CLI for GitHub Copilot, authenticate Azure CLI, verify the required tools, and clone the two sample applications directly from `Azure-Samples` — no forking needed; your work stays on a local `modernize` branch. ## 2.2. Set up your working directory -The recommended Codespace opens in the GHCP App Modernization hack directory. Clone your forks into a `repos/` working directory: +The recommended Codespace opens in the GHCP App Modernization hack directory, and the environment setup cloned both samples into `repos/`. From the hack directory, confirm they are present and on the `modernize` branch: ```bash -mkdir -p repos -cd repos - -GH_USER="$(gh api user --jq .login)" -git clone "https://github.com/${GH_USER}/PhotoAlbum-Java.git" -git clone "https://github.com/${GH_USER}/PhotoAlbum.git" +git -C repos/PhotoAlbum-Java status +git -C repos/PhotoAlbum status ``` -If your forks belong to an organization, use the organization name instead of `${GH_USER}`. Verify that the remotes point to repositories where you can push: +If a repository is missing, clone it and create the working branch: ```bash -git -C PhotoAlbum-Java remote -v -git -C PhotoAlbum remote -v +git clone https://github.com/Azure-Samples/PhotoAlbum-Java.git repos/PhotoAlbum-Java +git clone https://github.com/Azure-Samples/PhotoAlbum.git repos/PhotoAlbum +git -C repos/PhotoAlbum-Java checkout -b modernize +git -C repos/PhotoAlbum checkout -b modernize ``` The modernization CLI is already installed in the recommended Codespace. Confirm the installation and GitHub authentication: @@ -42,15 +33,32 @@ gh auth status For a local workstation, follow the installation instructions in the [environment setup guide](../../docs/environment-setup.md#option-b-local-workstation). We will use the modernization CLI end-to-end for upgrade, assessment, planning, and execution. -For batch operations across many repositories, create a JSON config file to list all repositories. For example, create it at `.github/modernize/repos.json` in your working directory, or provide a custom path. +For batch operations across multiple repositories, create a JSON config file that lists them. Create it at `.github/modernize/repos.json` in the hack directory (the folder you launch `modernize` from), using local `path` entries so the CLI operates on your clones in `repos/`. Paths must be absolute — print them with: + +```bash +echo "$(pwd)/repos/PhotoAlbum-Java" +echo "$(pwd)/repos/PhotoAlbum" +``` + +```json +{ + "repos": [ + { "name": "PhotoAlbum-Java", "path": "" }, + { "name": "PhotoAlbum", "path": "" } + ] +} +``` -Reference: +Reference: Config file listing the repositories +> [!NOTE] +> The screenshot shows a config that lists repository URLs. In this MicroHack you use local `path` entries instead, so the assessment and upgrades run directly on your working copies — nothing is re-cloned. + ## 2.3. Run the batch assessment -In your terminal, run the modernize CLI agent by typing _modernize_ (you can verify the Modernize CLI is properly installed and see the available commands by typing _modernize --help_) and accept execution in your working directory. +From the hack directory, run the modernize CLI by typing `modernize` (verify the installation and see the available commands with `modernize --help`) and accept execution in the working directory when prompted. Run "Assess" to analyze the code of the 2 apps and generate a report. @@ -68,14 +76,14 @@ Check both "Upgrade" and "Cloud readiness". Leave "Security" unchecked. Selecting Upgrade and cloud readiness -Change the Analysis coverage to "Full analysis" and press enter to continue. +Change the Analysis coverage to "Full analysis". On the same configuration page, verify the upgrade targets before continuing: **.NET / Target Framework = .NET 10** and **Java / Target Runtime = OpenJDK 25** — the report's upgrade recommendations are driven by these values. Then press enter to continue. Setting analysis coverage to Full analysis -Chose to assess locally (using cloud agents is also possible) +Choose to assess locally. (Cloud-agent delegation is not available in this setup — it requires github.com repository URLs, and this hack uses local `path` entries.) > [!NOTE] -> Note that an assessment-config.yaml file gets automatically generated. Both repositories get cloned and assessment starts. It may take about 5-10 min to complete, so it's a good time to take a coffee break. +> An `assessment-config.yaml` file is generated automatically and the assessment starts on your local working copies. With Full analysis it takes roughly 10-20 minutes for the two repositories, so it's a good time to take a coffee break. Assessment running locally @@ -92,6 +100,8 @@ Batch assessment is especially valuable for migration planning because it enable **Per repository report:** Provides detailed insights on the two aspects identified at the individual repository level. +All reports are written to **`.github/modernize/assessment/`** in the hack directory (the folder you launched `modernize` from), inside a timestamped `reports-*` subfolder: an aggregated report (`index.md`) plus one report per repository. The CLI opens the aggregated report automatically when the assessment finishes; use this path to get back to the reports later. + Per repository report Per repository report details @@ -102,13 +112,13 @@ Now that we have an assessment report, we could jump straight to a modernization For a batch upgrade, both repositories would need to use the same programming language, which is not the case here, so let's upgrade both apps individually. -Exit the modernize CLI, navigate to the folder of the PhotoAlbum (.NET) and relaunch the modernize CLI. +When the assessment finishes, the CLI asks how to continue — select **Return to main menu** (creating a modernization plan is the subject of Challenge 3). Exit the modernize CLI, navigate to the folder of the PhotoAlbum (.NET) and relaunch the modernize CLI. Select the Upgrade option, current folder, and upgrade locally. In the prompt box, submit the following prompt: "Upgrade to .NET 10", as recommended previously in our assessment report. -Migrate CLI imediately starts creating an upgrade plan, followed by execution of the necessary code changes. +The modernize CLI immediately starts creating an upgrade plan, followed by execution of the necessary code changes. Check the resulting Plan Execution Summary for each app. Upgrade should show "Success". @@ -116,10 +126,11 @@ Check the resulting Plan Execution Summary for each app. Upgrade should show "Su Navigate to the PhotoAlbum-Java directory and repeat the same process for the Java version of the app. Use the following prompt: "Upgrade to Java 25 and upgrade to Spring Boot 4.0", as recommended previously in our assessment report. -Exit modernize CLI, navigate to each app folder, commit and push your changes to each respective remote repository. Ensure all changes are committed and pushed. +Exit the modernize CLI, navigate to each app folder, and commit your changes on the `modernize` branch (the upgrade may already have created commits — check with `git log`). The upstream `Azure-Samples` repositories are read-only for you, so there is nothing to push; if you want a remote copy, publish a repository to your own account with `gh repo create --source=. --private --push`. -Congratulations 🎉 your apps are now upgraded and you have completed challenge 2. +> [!WARNING] +> The sample repositories ship with pre-existing example content under `.github/` (agents, prompts, and several GitHub Actions workflows). If you publish a copy to your own account, delete `.github/workflows/` first — otherwise those workflows start running on your account, and pushing workflow files requires the `workflow` scope on your GitHub CLI credential. -Navigate back to your parent directory and launch modernize CLI again. +Congratulations 🎉 your apps are now upgraded and you have completed challenge 2. You are now ready to initiate challenge 3 - modernize your upgraded apps and deploy them in Azure. diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/15.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/15.png deleted file mode 100644 index ae80ee4c7..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/15.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/16.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/16.png deleted file mode 100644 index 09096b3ae..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/16.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/17.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/17.png deleted file mode 100644 index 06f69d907..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/17.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/21.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/21.png deleted file mode 100644 index 435d415d4..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/21.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/22.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/22.png deleted file mode 100644 index 48bcd5071..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/22.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/23.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/23.png deleted file mode 100644 index 4feeb547a..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/23.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/24.png b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/24.png deleted file mode 100644 index bd44f44ce..000000000 Binary files a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/img/24.png and /dev/null differ diff --git a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/solution-03.md b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/solution-03.md index 2757c15d0..41b713d61 100644 --- a/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/solution-03.md +++ b/03-Azure/01-01-App Innovation/03_GHCPAppModernization/walkthrough/challenge-03/solution-03.md @@ -4,42 +4,35 @@ ## 3.1. Create the cloud modernization plan -Select the "Plan" option, then target both repositories from the config file. +From the hack directory, launch the modernize CLI and select the **Plan** option. Choose **From a config file** — the CLI auto-detects the `.github/modernize/repos.json` you created in Challenge 2 — and select both apps. Choose **Keep the plan local** and name the plan `cloud-modernization-plan`. -Select both apps and use cloud agents. Name the plan "cloud-modernization-plan" - -Type the following instruction in the prompt "An assessment has been previously completed for both apps, but after that both apps have been upgrated to their latest respective framework versions. In this plan, you should ignore any upgrade recommendations in the existing assessment report. You should focus on resolving the cloud readiness issues, set up Azure infrastructure for each app, and deploy the App on Azure. If OracleDB exists, migrate to PostgreSQL." +Type the following instruction in the prompt: "An assessment has been previously completed for both apps, but after that both apps have been upgraded to their latest respective framework versions. In this plan, you should ignore any upgrade recommendations in the existing assessment report. You should focus on resolving the cloud readiness issues, set up Azure infrastructure for each app, and deploy the App on Azure. If OracleDB exists, migrate to PostgreSQL." Entering the cloud modernization plan prompt +Answer the clarifying questions the agent asks about your goals, then let it generate the plans. + > [!NOTE] -> Generating the plan should take about 15-20 min. Once finished, you should see a series of tasks to be executed. +> Generating the plans should take about 15-20 min. Once finished, you should see a series of tasks to be executed. Generated plan tasks Generated plan tasks continued -## 3.2 Review and merge the pull request - -Review the pull request and merge it. - -Pull request overview +## 3.2 Review the generated plans -Pull request changes - -Merging the pull request +A plan is generated locally inside each repository: open `repos//.github/modernize/cloud-modernization-plan/plan.md` (the task list sits next to it in `.metadata/tasks.json`). Review the strategy and tasks for each app, and edit the files if you want to adjust the approach before execution — the plans are plain local files in each repository's working tree (the CLI git-ignores them); nothing is committed or pushed anywhere. ## 3.3 Deploy the PhotoAlbum-Java app -Navigate to repos\PhotoAlbum-Java and pull the latest changes in he cloud-modernization-plan branch, which include the latest plan.md. - -Pulling the latest changes for PhotoAlbum-Java - -Launch Modernize CLI and execute the plan (cloud-modernization-plan). +Navigate to `repos/PhotoAlbum-Java`, launch the modernize CLI, select **Execute**, and pick the `cloud-modernization-plan`. Executing the plan in Modernize CLI -Plan execution will start. Wait for all tasks to complete. It may take a while. Maybe a good time to stretch your legs. +Plan execution will start. Wait for all tasks to complete. It may take a while. Maybe a good time to stretch your legs. + +> [!NOTE] +> You have Owner rights on the lab subscription, so the agent can provision into a resource group it creates (as shown below). If you prefer to deploy into your pre-created lab resource group instead, add `resource group: ` to the plan prompt in step 3.1. Once finished, check the resource group on Azure with the deployed resources. Next, open the Frontend Container app URL. @@ -49,34 +42,30 @@ Once finished, check the resource group on Azure with the deployed resources. Ne Frontend Container app - Congratulations! 🎉 You managed to migrate and deploy in Azure the upgraded PhotoAlbum-Java app. ## 3.4 Deploy the PhotoAlbum (.NET) app -Now, let's migrate and deploy in Azure the .NET version of the app. Navigate to repos\PhotoAlbum and pull the latest changes in he cloud-modernization-plan branch, which include the latest plan.md. - -Launch Modernize CLI and execute the plan (cloud-modernization-plan). +Now, let's migrate and deploy in Azure the .NET version of the app. Navigate to `repos/PhotoAlbum`, launch the modernize CLI, select **Execute**, and pick the `cloud-modernization-plan`. Plan execution will start. Wait for all tasks to complete. It may take a while. Notice this plan didn't create the infrastructure code nor deployed any resource in Azure. Let's create another plan and be explicit in our prompt. -Create a new plan, locally this time, name it "infra-setup-plan", and use the following prompt "Provision Azure resources and deploy the app." - -Wait for the plan to be generated. +Create a new plan, locally this time, name it `infra-setup-plan`, and use the following prompt: "Provision Azure resources and deploy the app." -Once finished, you can check the plan at `.\.github\modernize\infra-setup-plan` +Wait for the plan to be generated. Once finished, you can check the plan at `.github/modernize/infra-setup-plan`. Generated infra-setup-plan -Finally, execute the plan. +Finally, execute the plan. Plan execution will start. Wait for all tasks to complete. -Plan execution will start. Wait for all tasks to complete. It may take a while. +> [!WARNING] +> The .NET app's Release container build can fail with a **Six Labors (ImageSharp) license** error — ImageSharp 3.2+ (pulled in by the Challenge 2 security fixes) enforces license checks in Release builds. Get a free community key from and set the `SixLaborsLicenseKey` build property, or instruct the agent to publish a Debug build for this lab. Once finished, check the resource group on Azure with the deployed resources. Next, open the Frontend Container app link. > [!TIP] -> If you get any deployment error, you can use Github Copilot CLI to diagnose and help you fix it. +> If you get any deployment error, use GitHub Copilot CLI to diagnose and help you fix it — the Azure MCP server you configured in Challenge 1 (`.github/mcp.json`) lets it query your Azure resources directly. Congratulations! 🎉 You managed to migrate and deploy in Azure the upgraded PhotoAlbum (.NET) app, and finish the challenge 3 successfully!