14 KiB
name, description, compatibility, metadata
| name | description | compatibility | metadata | ||||
|---|---|---|---|---|---|---|---|
| development-lifecycle | Development lifecycle workflow - Code → Build → Test → Fix → Deploy. Use for understanding complete development process, debugging build errors, fixing test failures, and continuous improvement cycles in GoodGo microservices. | .NET 10+, Docker 24+, docker-compose 2.x |
|
Development Lifecycle / Quy Trình Phát Triển
Complete iterative development workflow from code to deployment with focus on troubleshooting and debugging.
When to Use This Skill / Khi Nào Sử Dụng
Use this skill when:
- Starting development on a new feature / Bắt đầu phát triển feature mới
- Debugging build or test failures / Debug lỗi build hoặc test
- Understanding the complete dev cycle / Hiểu quy trình phát triển hoàn chỉnh
- Setting up local development environment / Setup môi trường local
- Troubleshooting deployment issues / Khắc phục sự cố deployment
Core Concepts / Khái Niệm Cốt Lõi
Development Cycle / Chu Kỳ Phát Triển
graph LR
A[① CODE<br/>Write Features] --> B[② BUILD<br/>Compile & Package]
B --> C[③ TEST<br/>Run Tests]
C --> D{Pass?}
D -->|No| E[④ FIX<br/>Debug & Resolve]
E --> B
D -->|Yes| F[⑤ DEPLOY<br/>Local/Staging/Prod]
F --> G{Issues?}
G -->|Yes| E
G -->|No| H[✓ Done]
Philosophy / Triết Lý
- Fail Fast - Phát hiện lỗi sớm nhất có thể
- Iterative - Cải tiến liên tục qua từng cycle
- Automated - Tự động hóa các bước lặp lại
- Observable - Luôn có visibility vào system state
Phase 1: CODE ✍️
Goal: Viết code sạch, maintainable theo architecture chuẩn
Workflow
Use existing skills cho coding phase:
- dotnet-microservice-workflow - 4-layer architecture
- api-design - RESTful endpoints
- cqrs-mediatr - Commands/Queries
- domain-driven-design - Domain modeling
Best Practices
// ✅ GOOD: Clear intention, follows patterns
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, OrderResult>
{
private readonly IOrderRepository _repository;
public async Task<OrderResult> Handle(CreateOrderCommand cmd, CancellationToken ct)
{
var order = new Order(cmd.UserId, cmd.ShippingAddress);
foreach (var item in cmd.Items)
order.AddItem(item.ProductId, item.Quantity, item.Price);
await _repository.AddAsync(order, ct);
await _repository.UnitOfWork.SaveChangesAsync(ct);
return new OrderResult(order.Id);
}
}
// ❌ BAD: Mixed concerns, no separation
[HttpPost]
public async Task<IActionResult> CreateOrder(CreateOrderRequest request)
{
var order = new Order { UserId = request.UserId };
_context.Orders.Add(order);
await _context.SaveChangesAsync();
return Ok(order.Id);
}
Phase 2: BUILD 🔨
Goal: Compile code và tạo artifacts (DLLs, Docker images)
Local .NET Build
# Restore NuGet packages
dotnet restore
# Build solution
dotnet build
# Build specific project
dotnet build src/MyService.API/
# Release build
dotnet build -c Release
# Verbose output (for debugging)
dotnet build -v detailed
Docker Build
# Build service image
docker build -t my-service:latest -f services/my-service-net/Dockerfile .
# Build via docker-compose
docker-compose -f deployments/local/docker-compose.yml build my-service-net
# No cache (clean build)
docker-compose -f deployments/local/docker-compose.yml build --no-cache my-service-net
# Parallel build multiple services
docker-compose -f deployments/local/docker-compose.yml build --parallel
Common Build Errors
| Error Code | Cause | Solution |
|---|---|---|
| CS0246 | Missing type/namespace | Run dotnet restore, add package reference |
| CS0103 | Name does not exist | Add using statement |
| CS1061 | Missing member | Check property/method name, NuGet version |
| NU1101 | Unable to find package | Check package name, NuGet source |
| Docker context | Wrong build context | Verify -f and context path |
See detailed solutions: references/build-errors.md
Phase 3: TEST 🧪
Goal: Validate correctness through automated tests
Test Pyramid
┌──────────────┐
│ E2E Tests │ ← ~5% - Slow, brittle
│ (UI/API) │
├──────────────┤
│ Integration │ ← ~15% - Medium speed
│ Tests │ Database, HTTP
├──────────────┤
│ Unit Tests │ ← ~80% - Fast, isolated
│ (Handlers, │ Pure logic
│ Domain) │
└──────────────┘
Test Commands
# Run all tests
dotnet test
# Run specific test project
dotnet test tests/MyService.UnitTests/
# Run with filter
dotnet test --filter Category=Unit
dotnet test --filter FullyQualifiedName~CreateOrderHandler
# Watch mode (TDD)
dotnet watch test --project tests/MyService.UnitTests/
# Coverage report
dotnet test /p:CollectCoverage=true /p:CoverageReportFormat=opencover
# Detailed output
dotnet test --logger "console;verbosity=detailed"
Test Structure
Use testing skill: dotnet-senior-tester
// ✅ GOOD: Arrange-Act-Assert, clear mocking
public class CreateOrderCommandHandlerTests
{
[Fact]
public async Task Handle_ValidCommand_CreatesOrder()
{
// Arrange
var repository = Substitute.For<IOrderRepository>();
var unitOfWork = Substitute.For<IUnitOfWork>();
repository.UnitOfWork.Returns(unitOfWork);
var handler = new CreateOrderCommandHandler(repository);
var command = new CreateOrderCommand(UserId: Guid.NewGuid(), /* ... */);
// Act
var result = await handler.Handle(command, CancellationToken.None);
// Assert
await repository.Received(1).AddAsync(Arg.Any<Order>(), Arg.Any<CancellationToken>());
await unitOfWork.Received(1).SaveChangesAsync(Arg.Any<CancellationToken>());
Assert.NotEqual(Guid.Empty, result.OrderId);
}
}
See test failure patterns: references/test-failures.md
Phase 4: FIX 🔧
Goal: Debug và resolve issues nhanh chóng
Debugging Workflow
graph TD
A[Error Detected] --> B{Error Type?}
B -->|Build| C[Check Build Logs]
B -->|Test| D[Check Test Output]
B -->|Runtime| E[Check App Logs]
C --> F[Identify Root Cause]
D --> F
E --> F
F --> G[Apply Fix]
G --> H[Verify Fix]
H --> I{Fixed?}
I -->|No| F
I -->|Yes| J[Document Solution]
Debugging Tools
Build Errors:
# Verbose build output
dotnet build -v detailed
# Clean and rebuild
dotnet clean && dotnet build
# Check references
dotnet list package
Test Failures:
# Run single test with details
dotnet test --filter TestMethodName --logger "console;verbosity=detailed"
# Debug test in VS Code
# Set breakpoint, F5 to debug
Runtime Issues:
# Container logs
docker logs -f my-service-net
docker logs --tail 100 my-service-net
# Follow logs
docker-compose -f deployments/local/docker-compose.yml logs -f my-service-net
# Exec into container
docker exec -it my-service-net sh
# Check health endpoint
curl http://localhost/api/v1/my-service/health
Common Fix Patterns
| Issue | Pattern | Example |
|---|---|---|
| NullReferenceException | Check mock setup | repository.Setup(x => x.Get()).Returns(entity) |
| Async deadlock | Use ConfigureAwait(false) |
await task.ConfigureAwait(false); |
| Database timeout | Check connection string, indexes | Add index on frequently queried columns |
| Container won't start | Check environment vars, ports | Verify docker-compose.yml config |
See detailed guide: references/debugging-guide.md
Phase 5: DEPLOY 🚀
Goal: Deploy và verify application in target environment
Local Deployment
# Start service with docker-compose
docker-compose -f deployments/local/docker-compose.yml up -d my-service-net
# Check status
docker-compose -f deployments/local/docker-compose.yml ps
# Health check
curl http://localhost/api/v1/my-service/health
# Swagger UI
open http://localhost/api/v1/my-service/swagger
Health Checks
Every service MUST have /health endpoint:
// Program.cs
builder.Services.AddHealthChecks()
.AddNpgSql(connectionString, name: "database")
.AddRedis(redisConnection, name: "redis");
app.MapHealthChecks("/health");
Verification Checklist
- Service starts without errors
/healthreturns 200 OK- Database migrations applied
- Swagger UI accessible
- Sample API call works
- Logs show no errors
Staging/Production
Use deployment skill: deployment-kubernetes
# kubectl commands for K8s
kubectl apply -f deployments/kubernetes/my-service.yaml
kubectl rollout status deployment/my-service
kubectl get pods -l app=my-service
Development Patterns / Các Mẫu Phát Triển
Pattern 1: Test-Driven Development (TDD)
1. ❌ RED - Write failing test
2. ✅ GREEN - Write minimal code to pass
3. 🔧 REFACTOR - Improve code quality
4. Repeat
Benefits:
- Better design (testable code)
- High confidence in changes
- Living documentation
Pattern 2: Incremental Development
# Small commits with working state
git commit -m "feat: add CreateOrder command"
git commit -m "test: add CreateOrderHandler tests"
git commit -m "fix: validate order items quantity"
Pattern 3: Hot Reload Development
# .NET hot reload (faster iteration)
dotnet watch run --project src/MyService.API
# Docker with volume mount (for config changes)
docker-compose up --build
Helper Scripts / Scripts Hỗ Trợ
Check Environment
# Verify development environment
./scripts/check-env.sh
Quick Build
# Build single service quickly
./scripts/quick-build.sh my-service-net
Debug Build
# Debug build errors with verbose output
./scripts/debug-build.sh my-service-net
Health Check
# Check all services health
./scripts/health-check.sh
Common Mistakes / Lỗi Thường Gặp
1. Skip Tests
Problem: Bugs go to production
Solution: Write tests first (TDD) or immediately after feature
# ❌ BAD: Push without testing
git push origin main
# ✅ GOOD: Always test first
dotnet test && git push origin main
2. Ignore Build Warnings
Problem: Tech debt accumulates, future breaks
Solution: Treat warnings as errors
<!-- MyService.API.csproj -->
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
3. No Logging
Problem: Hard to debug production issues
Solution: Add structured logging
// ✅ GOOD: Structured logging
_logger.LogInformation("Creating order for user {UserId} with {ItemCount} items",
command.UserId, command.Items.Count);
4. Skip Health Checks
Problem: Can't verify deployment success
Solution: Always add /health endpoint
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
Quick Reference / Tham Chiếu Nhanh
Development Commands
| Task | Command |
|---|---|
| Restore packages | dotnet restore |
| Build | dotnet build |
| Run tests | dotnet test |
| Run locally | dotnet run --project src/MyService.API |
| Watch mode | dotnet watch run |
| Hot reload tests | dotnet watch test |
Docker Commands
| Task | Command |
|---|---|
| Build image | docker-compose build my-service-net |
| Start service | docker-compose up -d my-service-net |
| View logs | docker-compose logs -f my-service-net |
| Restart | docker-compose restart my-service-net |
| Stop | docker-compose down |
| Rebuild & start | docker-compose up -d --build my-service-net |
Debugging Commands
| Task | Command |
|---|---|
| Verbose build | dotnet build -v detailed |
| Clean build | dotnet clean && dotnet build |
| Test with logs | dotnet test --logger console |
| Container logs | docker logs -f my-service-net |
| Exec into container | docker exec -it my-service-net sh |
Resources / Tài Nguyên
Related Skills
- dotnet-microservice-workflow - 4-phase architecture workflow
- dotnet-senior-tester - Comprehensive testing
- docker-traefik - Docker patterns
- error-handling-patterns - Exception handling
- project-rules - Coding standards
Helper Resources
- Build Errors Catalog - Common build errors and solutions
- Test Failures Guide - Test debugging patterns
- Debugging Guide - Advanced debugging techniques