Paweł Łukasiewicz: programista blogger
Paweł Łukasiewicz
2026-03-03
Paweł Łukasiewicz: programista blogger
Paweł Łukasiewicz
2026-03-03
Udostępnij Udostępnij Kontakt
Wprowadzenie – ostatni wpis cyklu

To jest ostatni wpis cyklu "Agentic Development z GitHub Copilot". Przez czternaście wpisów omawialiśmy koncepty, mechanizmy i konfigurację od podstaw. Teraz czas na format który jest najbardziej użyteczny na co dzień: cookbook – zbiór gotowych do wklejenia przepisów bez zbędnego kontekstu.

Oryginalne repozytorium awesome-copilot dostarcza cookbook w formie skoncentrowanej na Copilot SDK – snippety dla różnych języków programowania pokazujące jak budować aplikacje na bazie API Copilota. Mój wkład w ten wpis jest inny: przepisy stricte dla .NET developera który chce skonfigurować agentic development w swoim projekcie – od pierwszego pliku do działającego pipeline'u.

Każdy przepis to: gotowy kod do skopiowania, czas wykonania i wskazanie do którego wpisu cyklu się odwołuje po więcej kontekstu. Przepisy są ułożone od najprostszych do najbardziej złożonych – możesz zatrzymać się w dowolnym miejscu. Oryginalne źródło cookbook: Cookbook – Awesome GitHub Copilot Learning Hub.

📦 Rozdział 1 – Konfiguracja od zera
🏗️
Minimalna konfiguracja nowego projektu .NET
Trzy pliki które powinna mieć każda nowa aplikacja
Instrukcja
⏱ ~10 minut .github/copilot-instructions.md → Wpis 4, 5

Zanim napiszesz pierwszą linię kodu, stwórz te trzy pliki. To minimalny zestaw który sprawia że Copilot wie o projekcie więcej niż widzi w otwartych plikach.

projekt-root/
├── .github/
    ├── copilot-instructions.md    ← globalny kontekst projektu
    ├── instructions/
    │   └── tests.instructions.md    ← stack testowy
    └── agents/
        └── (wpis 7 gdy będziesz gotowy)

Plik 1 – .github/copilot-instructions.md (szablon do uzupełnienia):

# Instrukcje projektu – [NAZWA PROJEKTU]

## Stack technologiczny
- .NET [WERSJA], C# [WERSJA]
- ASP.NET Core Minimal API / [lub: MVC / Blazor]
- Entity Framework Core [WERSJA] + [PostgreSQL / SQL Server / SQLite]
- MediatR + FluentValidation + Ardalis.Result
- xUnit + FluentAssertions + NSubstitute

## Architektura
Projekt używa Clean Architecture z warstwami:
- `src/[Nazwa].Domain` – encje, value objects, interfejsy repozytoriów
- `src/[Nazwa].Application` – commandy, query, handlery MediatR
- `src/[Nazwa].Infrastructure` – EF Core, repozytoria, serwisy zewnętrzne
- `src/[Nazwa].API` – Minimal API endpoints, middleware

## Kluczowe konwencje
- Warstwa Application NIGDY nie dotyka DbContext bezpośrednio
- Każdy endpoint używa MediatR ISender, nie serwisów bezpośrednio
- Handlery zwracają Ardalis.Result, endpoints mapują przez .ToMinimalApiResult()
- Async wszędzie – brak .Result i .Wait()
- CancellationToken w każdej publicznej metodzie async

## Nazewnictwo
- Commandy: [Akcja][Encja]Command (np. CancelOrderCommand)
- Query: Get[Encja]Query, Get[Encja]sQuery
- Handlery: [Nazwa]CommandHandler, [Nazwa]QueryHandler
- Testy: [Klasa]Tests, metody: [Metoda]_When[Warunek]_Should[Wynik]

## Zatwierdzony stack testowy
- Framework: xUnit 2
- Asercje: FluentAssertions
- Mocki: NSubstitute (NIE Moq)
- Wzorzec: AAA z komentarzami // Arrange / // Act / // Assert
- Testuj zachowanie, nie implementację – unikaj .Received() poza edge cases

## Czego NIE rób
- Nie dodawaj nowych zależności NuGet bez konsultacji
- Nie twórz klas statycznych w warstwie Application
- Nie hardcoduj connection strings – używaj IConfiguration
- Nie modyfikuj plików *.csproj bez potwierdzenia

Plik 2 – .github/instructions/tests.instructions.md (path-specific):

---
description: Standardy testów jednostkowych projektu
applyTo: "**/*Tests.cs, **/Tests/**/*.cs"
---

# Standardy testów – [NAZWA PROJEKTU]

Używaj xUnit 2, FluentAssertions i NSubstitute.

## Wzorzec klasy testowej
```csharp
public class [Klasa]Tests
{
    private readonly I[Zależność] _[dep] = Substitute.For();
    private readonly [Klasa] _sut;

    public [Klasa]Tests()
    {
        _sut = new [Klasa](_[dep]);
    }
}
```

## Konwencja nazewnictwa metod
[Metoda]_When[Warunek]_Should[OczekiwanyWynik]

## Asercje
- Używaj FluentAssertions: result.Should().Be(...)
- Nie używaj Assert.NotNull – sprawdzaj konkretne wartości
- Mockuj przez NSubstitute: _repo.GetByIdAsync(1).Returns(entity)
⚙️
Środowisko Coding Agent – setup steps dla .NET
Agent startuje ze zbudowanym projektem i zielonymi testami
Coding Agent
⏱ ~5 minut .github/copilot-setup-steps.yml → Wpis 11

Copilot Coding Agent uruchamia ten plik przed każdą sesją. Bez niego agent traci minuty na diagnostykę środowiska. Dostosuj wersję .NET i ścieżki do swojego projektu.

# .github/copilot-setup-steps.yml
steps:
  - name: Setup .NET SDK
    uses: actions/setup-dotnet@v4
    with:
      dotnet-version: '9.0.x'

  - name: Restore NuGet packages
    run: dotnet restore MyApp.sln

  - name: Build solution (verify it compiles)
    run: dotnet build MyApp.sln --no-restore --configuration Debug

  - name: Run tests to establish baseline
    run: >
      dotnet test MyApp.sln
      --no-build
      --verbosity normal
      --logger "console;verbosity=detailed"
    continue-on-error: true   # Agent widzi które testy były czerwone na starcie
🔍 Dlaczego continue-on-error: true przy testach?

Jeśli projekt ma czerwone testy zanim agent zacznie pracę, agent widzi je jako część środowiska – nie jako błąd który sam wprowadził. Dzięki temu nie traci sesji na naprawianie istniejących problemów i skupia się na zadaniu z issue.

🛠️ Rozdział 2 – Skills gotowe do użycia
🧪
Skill: generowanie testów jednostkowych (xUnit / NSubstitute)
Wywołaj: /generate-unit-tests lub automatycznie przez agenta
Skill
⏱ ~8 minut .github/skills/generate-unit-tests/SKILL.md → Wpis 6
---
name: generate-unit-tests
description: >
  Generuje kompletne testy jednostkowe dla wskazanej klasy lub metody.
  Używa xUnit 2, FluentAssertions i NSubstitute. Wzorzec AAA.
  Pokrywa: happy path, przypadki brzegowe, scenariusze błędów.
---

# Skill: Generowanie testów jednostkowych

## Cel
Napisz kompletny plik testowy dla klasy lub metody wskazanej przez użytkownika.

## Wymagania
- **Framework**: xUnit 2
- **Asercje**: FluentAssertions (`.Should().Be()`, `.Should().BeTrue()`)
- **Mocki**: NSubstitute (`Substitute.For()`, `.Returns()`)
- **Wzorzec**: AAA z komentarzami `// Arrange`, `// Act`, `// Assert`

## Nazewnictwo metod testowych
Format: `[Metoda]_When[Warunek]_Should[OczekiwanyWynik]`
Przykłady:
- `Handle_WhenOrderExists_ShouldReturnSuccess`
- `Handle_WhenOrderNotFound_ShouldReturnNotFound`
- `Handle_WhenOrderAlreadyCancelled_ShouldReturnConflict`

## Struktura klasy testowej
```csharp
public class [KlasaDoTestowania]Tests
{
    private readonly I[Zależność1] _[dep1] = Substitute.For();
    private readonly I[Zależność2] _[dep2] = Substitute.For();
    private readonly [KlasaDoTestowania] _sut;

    public [KlasaDoTestowania]Tests()
    {
        _sut = new [KlasaDoTestowania](_[dep1], _[dep2]);
    }
}
```

## Scenariusze do zawsze pokrycia
1. Happy path – operacja kończy się sukcesem
2. Encja nie istnieje (NotFound)
3. Operacja już wykonana / konflikt stanu (Conflict)
4. Nieprawidłowe dane wejściowe (jeśli walidacja w handlerze)

## Zasady asercji
- Testuj wynik i zmianę stanu – NIE wywołania mocków
- Unikaj `.Received()` – używaj tylko gdy semantycznie konieczne
  (np. weryfikacja że email został wysłany)
- Preferuj `.Should().Be(konkretnaWartość)` nad `.Should().NotBeNull()`

## Lokalizacja pliku testowego
Umieść w: `tests/[NazwaWarstwy]/[Namespace]/[KlasaDoTestowania]Tests.cs`
🔌
Skill: scaffolding endpointu Minimal API + CQRS
Wywołaj: /scaffold-api-endpoint
Skill
⏱ ~10 minut .github/skills/scaffold-api-endpoint/SKILL.md → Wpis 6
---
name: scaffold-api-endpoint
description: >
  Generuje komplet plików dla nowego endpointu: Command/Query, Handler,
  Validator (FluentValidation) i Endpoint (Minimal API).
  Stosuje Clean Architecture i MediatR.
---

# Skill: Scaffolding endpointu Minimal API

## Generuj cztery pliki
Dla każdego nowego endpointu stwórz:

### 1. Command lub Query
```csharp
// src/Application/[Moduł]/[Akcja][Encja]Command.cs
public sealed record [Akcja][Encja]Command([Parametry]) : IRequest;
```

### 2. Handler
```csharp
// src/Application/[Moduł]/[Akcja][Encja]CommandHandler.cs
public sealed class [Akcja][Encja]CommandHandler
    : IRequestHandler<[Akcja][Encja]Command, Result>
{
    private readonly I[Encja]Repository _repo;
    private readonly ILogger<[Akcja][Encja]CommandHandler> _logger;

    public [Akcja][Encja]CommandHandler(
        I[Encja]Repository repo,
        ILogger<[Akcja][Encja]CommandHandler> logger)
    {
        _repo = repo;
        _logger = logger;
    }

    public async Task Handle(
        [Akcja][Encja]Command request,
        CancellationToken ct)
    {
        // implementacja
    }
}
```

### 3. Validator (FluentValidation)
```csharp
// src/Application/[Moduł]/[Akcja][Encja]CommandValidator.cs
public sealed class [Akcja][Encja]CommandValidator
    : AbstractValidator<[Akcja][Encja]Command>
{
    public [Akcja][Encja]CommandValidator()
    {
        RuleFor(x => x.[Pole]).NotEmpty();
        // dodatkowe reguły
    }
}
```

### 4. Endpoint (Minimal API)
```csharp
// src/API/Endpoints/[Moduł]/[Akcja][Encja]Endpoint.cs
public static class [Akcja][Encja]Endpoint
{
    public static RouteGroupBuilder Map[Akcja][Encja](
        this RouteGroupBuilder group)
    {
        group.Map[Metoda]("/[ścieżka]",
            async (
                [Parametry z URL],
                ISender sender,
                CancellationToken ct) =>
            {
                var result = await sender.Send(
                    new [Akcja][Encja]Command([mapowanie]), ct);
                return result.ToMinimalApiResult();
            })
            .WithName("[Akcja][Encja]")
            .WithSummary("[Opis endpointu]")
            .Produces(StatusCodes.Status200OK)
            .ProducesProblem(StatusCodes.Status404NotFound)
            .RequireAuthorization();

        return group;
    }
}
```

## Zasady
- Endpoint NIGDY nie wstrzykuje DbContext ani repozytoriów
- Endpoint używa wyłącznie ISender do wysłania command/query
- Handler zwraca Ardalis.Result, endpoint mapuje przez .ToMinimalApiResult()
- RequireAuthorization() domyślnie – usuń tylko jeśli endpoint jest jawnie publiczny
🗄️
Skill: migracja EF Core z checklistą
Wywołaj: /create-ef-migration
Skill
⏱ ~6 minut .github/skills/create-ef-migration/SKILL.md → Wpis 6
---
name: create-ef-migration
description: >
  Prowadzi przez dodanie migracji EF Core: weryfikuje schemat,
  generuje komendę CLI i checklist przed commitem.
---

# Skill: Tworzenie migracji EF Core

## Krok 1 – Opisz zmianę schematu
Zanim zaproponujesz migrację, zapytaj:
- Co się zmienia? (nowa tabela / kolumna / indeks / relacja)
- Jaka jest motywacja? (wydajność / nowe wymaganie / refaktoryzacja)

## Krok 2 – Wygeneruj komendę CLI
Format komendy:
```bash
dotnet ef migrations add [NazwaMigracji] \
  --project src/[Nazwa].Infrastructure \
  --startup-project src/[Nazwa].API \
  --output-dir Data/Migrations
```

Konwencja nazewnictwa migracji:
- Nowa tabela:     `Add[Nazwa]Table`
- Nowa kolumna:    `Add[Kolumna]To[Tabela]`
- Nowy indeks:     `Add[Kolumny]IndexTo[Tabela]`
- Usunięcie:       `Remove[Co]From[Gdzie]`
- Relacja:         `Add[Encja]To[Encja]Relationship`

## Krok 3 – Checklist przed commitem
Weryfikuj każdy punkt po wygenerowaniu migracji:

☐ Metoda `Up()` wprowadza dokładnie planowane zmiany – nie więcej
☐ Metoda `Down()` jest poprawna i w pełni cofa `Up()`
☐ Indeksy złożone zamiast wielu osobnych gdzie możliwe
☐ Indeksy filtrowane (WHERE clause) gdy kolumna ma selektywny warunek
☐ Nazwy indeksów: `IX_[Tabela]_[Kolumna1]_[Kolumna2]`
☐ Nullable columns mają odpowiedni DEFAULT lub są nullable
☐ Brak destructive operations (DROP COLUMN) bez migrationu danych
☐ Migracja przetestowana lokalnie: `dotnet ef database update`

## Przykład – indeks złożony z filtrem
```csharp
migrationBuilder.CreateIndex(
    name: "IX_Orders_CustomerId_Status",
    table: "Orders",
    columns: new[] { "CustomerId", "Status" },
    filter: "\"Status\" != 'Completed'");
```
🤖 Rozdział 3 – Agenci dla .NET projektu
🔍
Agent: .NET Code Reviewer
Wbudowany ekspert od review z priorytetami BLOCKER / WARNING / INFO
Agent
⏱ ~12 minut .github/agents/dotnet-code-reviewer.agent.md → Wpis 7
---
name: dotnet-code-reviewer
description: >
  Senior .NET developer specjalizujący się w code review dla projektów
  z Clean Architecture. Analizuje kod pod kątem architektury, testów,
  bezpieczeństwa i wydajności. Dostarcza ustrukturyzowany feedback
  z priorytetami BLOCKER / WARNING / INFO i gotowymi poprawkami.
model: claude-sonnet-4-20250514
tools:
  - codebase
  - editFiles
---

# Agent: .NET Code Reviewer

## Twoja tożsamość
Jesteś seniorem .NET developerem z 10-letnim doświadczeniem w:
- Clean Architecture i Domain-Driven Design
- ASP.NET Core (Minimal API i MVC)
- Entity Framework Core
- CQRS z MediatR
- Testowaniu z xUnit, FluentAssertions, NSubstitute

## Co sprawdzasz przy każdym review

### Architektura
- Zależności tylko w stronę centrum (Domain ← Application ← Infrastructure / API)
- Brak DbContext w warstwie Application
- Brak logiki biznesowej w endpointach / kontrolerach
- Poprawne użycie wzorca Result (Ardalis.Result)

### Kod
- Async/await konsekwentnie – brak .Result, .Wait(), .GetAwaiter().GetResult()
- CancellationToken propagowany do wszystkich wywołań I/O
- Brak hardcoded strings, magic numbers, connection stringów
- Null safety: nullable reference types, null checks

### Testy
- Czy zmiana ma pokrycie testowe?
- Czy testy sprawdzają zachowanie (nie implementację)?
- Czy konwencja nazewnictwa jest zachowana?

### Bezpieczeństwo
- Brak sekretów w kodzie
- Autoryzacja na endpointach
- Walidacja danych wejściowych (FluentValidation)
- SQL injection (raw queries w EF Core)

## Format odpowiedzi
```
## Podsumowanie zmian
[2-3 zdania o tym co PR robi]

## [BLOCKER] [Krótki tytuł]
Plik: [ścieżka], linia: [numer]
Problem: [opis]
Dlaczego to ważne: [wyjaśnienie]
Poprawka:
```csharp
[gotowy kod]
```

## [WARNING] [Krótki tytuł]
[analogicznie]

## [INFO] [Krótki tytuł]
[sugestia bez blokowania merge]

## Ogólna ocena: APPROVE / REQUEST CHANGES
[jedno zdanie uzasadnienia]
```

## Guardrails
- NIE modyfikuj plików – tylko czytaj i komentuj
- Skup się na zmianach w PRze, nie na istniejących problemach poza zakresem
- Bądź konstruktywny – każdy BLOCKER ma gotową poprawkę
- Nie generuj komentarzy dla kodu który jest poprawny
🗺️
Agent: .NET Planner – plan implementacji przed kodowaniem
Najpierw plan, potem kod – unikaj kosztownych refaktoryzacji
Agent
⏱ ~10 minut .github/agents/dotnet-planner.agent.md → Wpis 7
---
name: dotnet-planner
description: >
  Analizuje wymagania i planuje implementację w projekcie .NET
  zanim zostanie napisany kod. Produkuje plan: pliki do stworzenia,
  pliki do modyfikacji, kolejność kroków i potencjalne ryzyka.
model: claude-sonnet-4-20250514
tools:
  - codebase
---

# Agent: .NET Planner

## Twoja tożsamość
Jesteś architektem .NET który planuje implementację zanim ktokolwiek
dotknie klawiatury. Twoja praca to zapobieganie błędom architektonicznych
przez staranne przemyślenie planu przed jego realizacją.

## Twój proces dla każdego zadania

### Krok 1 – Zrozumienie
Przeczytaj wymaganie. Zadaj pytania clarifying jeśli czegoś brakuje.
Nigdy nie planuj z niepewnymi wymaganiami.

### Krok 2 – Analiza istniejącego kodu
Przeszukaj codebase przez `codebase`:
- Jakie podobne wzorce już istnieją?
- Które pliki będą dotknięte?
- Czy są konflikty z istniejącymi abstrakcjami?

### Krok 3 – Plan implementacji
Wygeneruj plan w formacie:

```
## Plan implementacji: [Nazwa zadania]

### Nowe pliki do stworzenia
| Plik | Warstwa | Opis |
|------|---------|------|
| src/Application/Orders/CancelOrderCommand.cs | Application | Command record |
| ... | ... | ... |

### Istniejące pliki do modyfikacji
| Plik | Zmiana |
|------|--------|
| src/API/Endpoints/OrdersEndpoints.cs | Dodaj nowy endpoint |

### Kolejność implementacji
1. Domain – zmiany encji jeśli potrzebne
2. Application – command/query + handler + validator
3. Infrastructure – zmiany repozytorium jeśli potrzebne
4. API – endpoint
5. Tests – testy jednostkowe handlera

### Potencjalne ryzyka
- [Ryzyko 1 i jak je zminimalizować]

### Nie wchodzi w zakres
- [Co explicite NIE będzie zrobione]
```

## Guardrails
- Produkujesz PLAN, nie implementację – nie pisz kodu produkcyjnego
- Zatrzymaj się i zapytaj gdy wymaganie jest niejednoznaczne
- Zawsze wskaż wzorzec do naśladowania w istniejącym kodzie
🔗 Rozdział 4 – Hooks i MCP
🔬
Hook: Quality Gate po sesji agenta (.NET)
Format + Analyzery + Build – automatycznie po każdej sesji
Hook
⏱ ~15 minut (łącznie z testowaniem) .github/hooks/ (3 pliki) → Wpis 9

Trzy pliki tworzące kompletny quality gate. Po skopiowaniu dostosuj zmienną SOLUTION_FILE.

Plik 1 – .github/hooks/dotnet-quality-gate.json

{
  "hooks": [
    {
      "event": "agentStop",
      "command": {
        "windows": "powershell -ExecutionPolicy Bypass -File .github/hooks/dotnet-quality-gate.ps1",
        "linux": "bash .github/hooks/dotnet-quality-gate.sh",
        "mac": "bash .github/hooks/dotnet-quality-gate.sh"
      }
    }
  ]
}

Plik 2 – .github/hooks/dotnet-quality-gate.sh

#!/usr/bin/env bash
set -euo pipefail

SOLUTION_FILE="MyApp.sln"   # ← dostosuj
FAIL_ON_WARNINGS="${FAIL_ON_WARNINGS:-true}"
ERRORS=0

echo "╔══════════════════════════════════════╗"
echo "║  🔬 .NET Quality Gate – Copilot Hook ║"
echo "╚══════════════════════════════════════╝"

# [1/3] Formatowanie
echo "▶ [1/3] dotnet format --verify-no-changes..."
if ! dotnet format "$SOLUTION_FILE" --verify-no-changes 2>&1; then
    echo "  ❌ Błędy formatowania. Uruchom: dotnet format $SOLUTION_FILE"
    ERRORS=$((ERRORS + 1))
else
    echo "  ✅ Formatowanie OK"
fi

# [2/3] Roslyn Analyzers
echo "▶ [2/3] Roslyn Analyzers..."
WARN_FLAG=""
[ "$FAIL_ON_WARNINGS" = "true" ] && WARN_FLAG="-warnaserror"
if ! dotnet build "$SOLUTION_FILE" \
    --no-restore \
    -p:TreatWarningsAsErrors=$FAIL_ON_WARNINGS \
    -p:EnforceCodeStyleInBuild=true \
    --verbosity quiet 2>&1; then
    echo "  ❌ Analyzery / warningi wykryte"
    ERRORS=$((ERRORS + 1))
else
    echo "  ✅ Analyzery OK"
fi

# [3/3] Build weryfikacyjny
echo "▶ [3/3] Build weryfikacyjny..."
if ! dotnet build "$SOLUTION_FILE" --no-restore --verbosity quiet 2>&1; then
    echo "  ❌ Build nieudany"
    ERRORS=$((ERRORS + 1))
else
    echo "  ✅ Build OK"
fi

echo "═══════════════════════════════════════"
if [ "$ERRORS" -gt 0 ]; then
    echo "  🚫 Quality gate NIEUDANY ($ERRORS problem(y))"
    exit 1
else
    echo "  ✅ Quality gate ZALICZONY"
fi

Plik 3 – .github/hooks/dotnet-quality-gate.ps1 (Windows)

$ErrorActionPreference = "Stop"
$SOLUTION_FILE = "MyApp.sln"   # ← dostosuj
$FAIL_ON_WARNINGS = $env:FAIL_ON_WARNINGS ?? "true"
$errors = 0

Write-Host "╔══════════════════════════════════════╗"
Write-Host "║  🔬 .NET Quality Gate – Copilot Hook ║"
Write-Host "╚══════════════════════════════════════╝"

# [1/3] Formatowanie
Write-Host "▶ [1/3] dotnet format --verify-no-changes..."
& dotnet format $SOLUTION_FILE --verify-no-changes
if ($LASTEXITCODE -ne 0) {
    Write-Host "  ❌ Błędy formatowania."
    $errors++
} else { Write-Host "  ✅ Formatowanie OK" }

# [2/3] Analyzery
Write-Host "▶ [2/3] Roslyn Analyzers..."
& dotnet build $SOLUTION_FILE --no-restore `
    -p:TreatWarningsAsErrors=$FAIL_ON_WARNINGS `
    -p:EnforceCodeStyleInBuild=true --verbosity quiet
if ($LASTEXITCODE -ne 0) {
    Write-Host "  ❌ Analyzery / warningi"
    $errors++
} else { Write-Host "  ✅ Analyzery OK" }

# [3/3] Build
Write-Host "▶ [3/3] Build weryfikacyjny..."
& dotnet build $SOLUTION_FILE --no-restore --verbosity quiet
if ($LASTEXITCODE -ne 0) {
    Write-Host "  ❌ Build nieudany"
    $errors++
} else { Write-Host "  ✅ Build OK" }

Write-Host "═══════════════════════════════════════"
if ($errors -gt 0) {
    Write-Host "  🚫 Quality gate NIEUDANY ($errors problem(y))"
    exit 1
} else {
    Write-Host "  ✅ Quality gate ZALICZONY"
}
🔌
MCP: kompletna konfiguracja dla .NET projektu
GitHub + PostgreSQL (read-only) + SQLite + Azure DevOps
MCP
⏱ ~20 minut (instalacja + konfiguracja) .vscode/mcp.json → Wpis 8

Skopiuj cały blok, odkomentuj serwery których potrzebujesz, wypełnij zmienne środowiskowe przez inputs.

{
  "inputs": [
    {
      "id": "github-pat",
      "type": "promptString",
      "description": "GitHub Personal Access Token (repo, issues, pull_requests)",
      "password": true
    },
    {
      "id": "postgres-connection",
      "type": "promptString",
      "description": "PostgreSQL connection string (read-only user!)",
      "password": true
    },
    {
      "id": "ado-pat",
      "type": "promptString",
      "description": "Azure DevOps Personal Access Token",
      "password": true
    }
  ],
  "servers": {

    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": {
        "Authorization": "Bearer ${input:github-pat}"
      }
    },

    "postgres-readonly": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-postgres",
        "${input:postgres-connection}"
      ],
      "env": {
        "POSTGRES_SSL": "require",
        "POSTGRES_READONLY": "true"
      }
    },

    "sqlite": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sqlite",
        "--db-path",
        "./data/local.db"
      ]
    },

    "azure-devops": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@tiberriver256/mcp-server-azure-devops"
      ],
      "env": {
        "AZURE_DEVOPS_ORG_URL": "https://dev.azure.com/TWOJA-ORGANIZACJA",
        "AZURE_DEVOPS_AUTH_METHOD": "pat",
        "AZURE_DEVOPS_PAT": "${input:ado-pat}"
      }
    }

  }
}
⚠️ Pamiętaj o read-only dla baz danych

Serwer PostgreSQL konfiguruj zawsze z użytkownikiem read-only. Agent korzystający z MCP może odczytywać schemat i dane – ale nie powinien mieć możliwości modyfikacji bazy przez MCP. Mutacje danych powinny przechodzić przez migracje EF Core, nie przez MCP.

📋 Rozdział 5 – Checklisty i szybkie odniesienia
Checklist: konfiguracja agentic development w nowym projekcie
Minimalne 30 minut, pełna konfiguracja 2-3 godziny
Checklista
→ Wpisy 1–15 (podsumowanie)

Minimalna konfiguracja (30 min) – zacznij tu:

  • Stwórz .github/copilot-instructions.md ze stackiem i kluczowymi konwencjami (Przepis 1.1)
  • Dodaj instrukcję path-specific dla testów (Przepis 1.1)
  • Stwórz .github/copilot-setup-steps.yml dla Coding Agenta (Przepis 1.2)

Standardowa konfiguracja (2-3 godziny) – dodaj po minimale:

  • Skill /generate-unit-tests (Przepis 2.1)
  • Skill /scaffold-api-endpoint (Przepis 2.2)
  • Skill /create-ef-migration (Przepis 2.3)
  • Agent dotnet-code-reviewer (Przepis 3.1)
  • Agent dotnet-planner (Przepis 3.2)
  • Hook quality gate (Przepis 4.1)

Pełna konfiguracja (dodatkowe 1-2 godziny):

  • MCP GitHub (zarządzanie issues i PRami przez agenta)
  • MCP PostgreSQL read-only (inspekcja schematu)
  • Agentic Workflow: triage nowych issues (Wpis 10)
  • Agentic Workflow: dzienny raport backlogu (Wpis 10)
  • Zapakowanie konfiguracji w plugin dla teamu (Wpis 12)
🧭
Tabela decyzyjna: które narzędzie do którego zadania
Szybkie odniesienie – wytnij i zachowaj
Odniesienie
Chcę... Użyj Gdzie konfigurować
Copilot zawsze pisał kod w moim stylu Instrukcja .github/copilot-instructions.md
Mieć regułę tylko dla plików testowych Instrukcja path-specific .github/instructions/tests.instructions.md
Wywołać standaryzowane generowanie kodu przez / Skill .github/skills/NAZWA/SKILL.md
Mieć wyspecjalizowanego asystenta z głęboką ekspertyzą Agent .github/agents/NAZWA.agent.md
Połączyć Copilot z zewnętrznym API / bazą danych MCP Server .vscode/mcp.json
Automatycznie sprawdzać jakość po każdej sesji agenta Hook (agentStop) .github/hooks/NAZWA.json
Zablokować niebezpieczne narzędzia przed ich użyciem Hook (preToolUse) .github/hooks/NAZWA.json
Automatycznie reagować na nowe issue 24/7 Agentic Workflow .github/workflows/NAZWA.md
Cyklicznie generować raport stanu projektu Agentic Workflow (schedule) .github/workflows/NAZWA.md
Oddelegować task developerski na kilka godzin Coding Agent Issue → Assignees → Copilot
Udostępnić całą konfigurację teamowi jedną komendą Plugin .github/plugin/plugin.json
Zmienić styl odpowiedzi tylko dla siebie (nie dla projektu) Instrukcja osobista VS Code Settings → user instructions
🚑
Troubleshooting – najczęstsze problemy i rozwiązania
Gdy coś nie działa jak powinno
Debug
Objaw Przyczyna i rozwiązanie
Copilot ignoruje instrukcje z copilot-instructions.md Plik za długi (wypycha kod z okna kontekstu). Skróć do <500 słów. Przenieś szczegóły do instrukcji path-specific.
Skill /generate-unit-tests nie pojawia się w podpowiedziach Sprawdź czy SKILL.md ma frontmatter z name:. Przeładuj VS Code (Developer: Reload Window). Sprawdź lokalizację: .github/skills/NAZWA/SKILL.mdNAZWA to katalog, nie plik.
Agent nie widzi MCP serwera Sprawdź .vscode/mcp.json – plik musi być w katalogu .vscode/, nie w .github/. Sprawdź czy serwer jest uruchomiony: Output panel → MCP. Sprawdź czy token w inputs jest poprawny.
Hook quality gate odpala się ale agent nie naprawia błędów Hook musi zwracać exit code >0 żeby agent dostał feedback. Sprawdź czy skrypt ma exit 1 przy błędzie. Sprawdź czy komunikat błędu jest czytelny – agent naprawia to co rozumie z output hooka.
Coding Agent tworzy draft PR ale nic nie implementuje Issue zbyt niejasne albo zbyt duże. Sprawdź czy copilot-setup-steps.yml kończy się sukcesem (zakładka Actions). Dodaj Optional prompt z konkretnym wskazaniem pliku startowego.
Coding Agent ciągle nie przechodzi quality gate – pętla Agent wszedł w pętlę guesswork. Interweniuj: skomentuj w draft PR z @copilot Przestań próbować naprawić ten test. Opisz w komentarzu co dokładnie nie przechodzi.
Agentic Workflow uruchamia się ale nie tworzy issue Sprawdź permissions: issues: write w frontmatter. Sprawdź safe-outputs – brak tej sekcji blokuje tworzenie issues. Sprawdź logi w zakładce Actions → konkretny run.
Instrukcja path-specific nie jest stosowana do plików testowych Wzorzec applyTo musi pasować. Sprawdź: "**/Tests/**/*.cs" vs "**/*Tests.cs". Użyj obu: "**/*Tests.cs, **/Tests/**/*.cs"
Zamknięcie cyklu – co dalej?

To był ostatni wpis cyklu "Agentic Development z GitHub Copilot". Przez piętnaście wpisów przeszliśmy od "czym jest agent?" do kompletnej konfiguracji produkcyjnej z instrukcjami, skills, agentami, MCP, hooks, agentic workflows, Coding Agent i pluginami. Przepisy z tego wpisu zbierają wszystko w kopiowalną formę.

Kilka rzeczy wartych śledzenia w tym ekosystemie bo zmieniają się szybko:

  • agents.md – wyłaniający się standard AGENTS.md dla instrukcji platform-agnostic (GitHub Copilot + Claude + inne)
  • agentskills.io – specyfikacja Skills która umożliwia ich przenośność między narzędziami
  • awesome-copilot.github.com – community library agentów, skills, hooks i pluginów – rośnie co tydzień
  • modelcontextprotocol.io – specyfikacja MCP – nowe serwery pojawiają się regularnie

Ekosystem agentic development jest w fazie intensywnego wzrostu. Terminy które dziś brzmią jak nowości (Coding Agent, Agentic Workflows, AGENTS.md) za rok będą standardem tak oczywistym jak CI/CD. Warto być w środku tej zmiany teraz.

💪 Ostatnie zadanie cyklu – wdrożenie w projekcie

Wybierz jeden aktywny projekt .NET i wdróż minimalną konfigurację z checklisty przepisu 5.1:

  1. Stwórz .github/copilot-instructions.md używając szablonu z przepisu 1.1
  2. Dodaj skill /generate-unit-tests (przepis 2.1) i przetestuj na istniejącej klasie
  3. Dodaj hook quality gate (przepis 4.1) i sprawdź że odpala się po sesji agenta
  4. Deleguj jedno małe, dobrze opisane zadanie do Coding Agenta i przejdź przez pełny cykl review

Koniec cyklu „Agentic Development z GitHub Copilot" · 15 wpisów · Dziękuję za lekturę!