Skip to content

Commit 37b5d6a

Browse files
committed
Phase 2 of the go port
This phase is focused on getting generate-script working, as it's the primary interface. - introduce a validator to ensure that we do not break compatibility with the scripts generated by the dotnet CLI (for now ;) ) - implement a template-based script generator in scriptgen
1 parent a4ff2fa commit 37b5d6a

30 files changed

Lines changed: 3488 additions & 29 deletions

GO_DEVELOPMENT.md

Lines changed: 272 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,64 @@
22

33
This document describes the Go implementation of the GitHub Enterprise Importer CLI, which is being ported from C#/.NET to Go.
44

5-
## Status: Phase 1 Complete ✅
5+
## Status: Phase 2 In Progress 🚧
66

7-
**Phase 1: Foundation** has been completed. The project structure, core packages, and build infrastructure are in place.
7+
**Phase 1: Foundation** ✅ Complete
8+
**Phase 2: API Clients + Script Generation** 🚧 In Progress (80% complete)
89

9-
### What's Working
10+
### Phase 1 Complete ✅
1011

1112
- ✅ Go module setup at repo root
1213
- ✅ Directory structure (cmd/, pkg/, internal/)
13-
- ✅ Core packages: logger, retry, env, filesystem
14+
- ✅ Core packages: logger, retry, env, filesystem, app
1415
- ✅ Manual DI infrastructure with provider pattern
1516
- ✅ Build system (justfile with Go targets)
1617
- ✅ Linting configuration (golangci-lint)
1718
- ✅ CI workflow for Go
1819
- ✅ Three CLI skeleton binaries (gei, ado2gh, bbs2gh)
1920
- ✅ Comprehensive test suite with 44.9% initial coverage
2021

22+
### Phase 2 Progress (80% Complete)
23+
24+
**Completed:**
25+
-**pkg/http** - Shared HTTP client with retry logic (75.5% coverage)
26+
- GET/POST/PUT/DELETE methods with headers support
27+
- Automatic retry with exponential backoff
28+
- SSL verification bypass option
29+
- Context-aware requests
30+
- JSON payload support
31+
32+
-**pkg/github** - GitHub API client (93.9% coverage)
33+
- `GetRepos(ctx, org)` - Fetch all org repositories with pagination
34+
- `GetVersion(ctx)` - GHES version checking
35+
- Automatic pagination (100 items per page)
36+
- URL encoding for org names
37+
- Bearer token authentication
38+
39+
-**pkg/ado** - Azure DevOps API client (88.0% coverage)
40+
- `GetTeamProjects(ctx, org)` - Fetch all team projects
41+
- `GetRepos(ctx, org, teamProject)` - Fetch all repos in a project
42+
- `GetEnabledRepos(ctx, org, teamProject)` - Filter enabled repos
43+
- `GetGithubAppId(ctx, org, githubOrg, teamProjects)` - Find GitHub App service connection
44+
- Basic auth with PAT token
45+
- URL encoding and proper error handling
46+
47+
-**pkg/bbs** - Bitbucket Server API client (91.1% coverage)
48+
- `GetProjects(ctx)` - Fetch all projects with automatic pagination
49+
- `GetRepos(ctx, projectKey)` - Fetch all repos with automatic pagination
50+
- Basic auth with username/password
51+
- Handles BBS pagination model (nextPageStart)
52+
- URL encoding for project keys
53+
54+
**In Progress:**
55+
- 🚧 **pkg/scriptgen** - PowerShell script generation
56+
57+
**Remaining Phase 2 Work:**
58+
- [ ] Create PowerShell script generation package with Go templates
59+
- [ ] Add comprehensive tests for script generation (85%+ coverage)
60+
- [ ] Add script validation tool to compare C# vs Go outputs
61+
- [ ] Document script generation templates and validation process
62+
2163
## Project Structure
2264

2365
```
@@ -27,19 +69,23 @@ gh-gei/
2769
│ ├── ado2gh/ # Azure DevOps to GitHub CLI
2870
│ └── bbs2gh/ # Bitbucket to GitHub CLI
2971
├── pkg/ # Public library code
30-
│ ├── app/ # DI container and app setup
31-
│ ├── logger/ # Structured logging
32-
│ ├── retry/ # Retry logic with exponential backoff
72+
│ ├── app/ # DI container and app setup (100.0% coverage)
73+
│ ├── logger/ # Structured logging (76.9% coverage)
74+
│ ├── retry/ # Retry logic with exponential backoff (96.2% coverage)
3375
│ ├── env/ # Environment variable access
3476
│ ├── filesystem/ # Filesystem operations
35-
│ ├── models/ # Data models (TBD)
36-
│ └── api/ # API clients (TBD in Phase 2)
37-
│ ├── github/
38-
│ ├── ado/
39-
│ ├── bbs/
40-
│ ├── azure/
41-
│ └── aws/
42-
├── internal/ # Private application code (TBD)
77+
│ ├── http/ # Shared HTTP client (75.5% coverage) ✅
78+
│ ├── github/ # GitHub API client (93.9% coverage) ✅
79+
│ ├── ado/ # Azure DevOps API client (88.0% coverage) ✅
80+
│ ├── bbs/ # Bitbucket Server API client (91.1% coverage) ✅
81+
│ └── scriptgen/ # PowerShell script generation 🚧
82+
├── testdata/ # Test fixtures and sample data
83+
│ ├── github/ # GitHub API test fixtures
84+
│ ├── ado/ # Azure DevOps API test fixtures
85+
│ └── bbs/ # Bitbucket Server API test fixtures
86+
├── scripts/ # Utility scripts
87+
│ └── validate-scripts.sh # Compare C# vs Go PowerShell outputs
88+
├── internal/ # Private application code (TBD Phase 3)
4389
│ ├── gei/
4490
│ ├── ado2gh/
4591
│ └── bbs2gh/
@@ -75,6 +121,10 @@ just go-test
75121
# Run tests with coverage
76122
just go-test-coverage
77123

124+
# Run specific package tests
125+
go test ./pkg/github/... -v
126+
go test ./pkg/http/... -v
127+
78128
# Run tests with race detector
79129
go test -race ./...
80130
```
@@ -141,6 +191,37 @@ err := policy.Execute(ctx, func() error {
141191
})
142192
```
143193

194+
### http
195+
196+
Shared HTTP client with built-in retry logic, SSL verification bypass, and context support.
197+
198+
```go
199+
import "github.com/github/gh-gei/pkg/http"
200+
201+
httpClient := http.NewClient(http.Config{
202+
Timeout: 30 * time.Second,
203+
RetryAttempts: 3,
204+
NoSSLVerify: false,
205+
}, log)
206+
207+
body, err := httpClient.Get(ctx, url, headers)
208+
```
209+
210+
### github
211+
212+
GitHub API client for interacting with GitHub.com and GitHub Enterprise Server.
213+
214+
```go
215+
import "github.com/github/gh-gei/pkg/github"
216+
217+
client := github.NewClient(github.Config{
218+
APIURL: "https://api.github.com",
219+
PAT: "ghp_...",
220+
}, httpClient, log)
221+
222+
repos, err := client.GetRepos(ctx, "my-org")
223+
```
224+
144225
### env
145226

146227
Provides access to environment variables. Equivalent to C# `EnvironmentVariableProvider`.
@@ -234,6 +315,116 @@ for _, tt := range tests {
234315
}
235316
```
236317

318+
## Migration Plan Overview
319+
320+
### Phase 1: Foundation ✅ (Complete)
321+
- Go module setup
322+
- Core packages (logger, retry, env, filesystem, app)
323+
- Build infrastructure
324+
- CI/CD setup
325+
- Test framework
326+
327+
### Phase 2: API Clients + Script Generation 🚧 (In Progress - 80% Complete)
328+
329+
**Completed:**
330+
- ✅ HTTP client infrastructure (75.5% coverage)
331+
- ✅ GitHub API client (93.9% coverage)
332+
- ✅ Azure DevOps API client (88.0% coverage)
333+
- ✅ Bitbucket Server API client (91.1% coverage)
334+
335+
**In Progress:**
336+
- 🚧 PowerShell script generation package
337+
338+
**Key Features:**
339+
- ✅ RESTful API clients for GitHub, ADO, and BBS
340+
- ✅ Automatic pagination support (all APIs)
341+
- ✅ Authentication (Bearer tokens for GitHub, Basic auth for ADO/BBS)
342+
- ✅ Retry logic with exponential backoff (integrated)
343+
- ✅ Context-aware operations with cancellation support
344+
- ✅ URL encoding and proper error handling
345+
- 🚧 PowerShell script generation using Go text/template
346+
- ✅ Comprehensive unit tests (80%+ coverage achieved for all API clients)
347+
- 🚧 Script validation tool for C# vs Go output comparison
348+
349+
### Phase 3: Commands Implementation (Planned - 3-4 weeks)
350+
351+
**Priority Order:**
352+
1. **`generate-script`** command (all 3 CLIs) - Week 1-2
353+
- Primary usage model: users generate scripts first
354+
- Requires: API clients + script generation package
355+
- Output: PowerShell scripts for migration workflows
356+
357+
2. **`migrate-repo`** command (all 3 CLIs) - Week 2-3
358+
- Most complex command
359+
- Requires: Archive creation, blob storage upload, migration API
360+
361+
3. **`wait-for-migration`** command (all 3 CLIs) - Week 3
362+
- Poll migration status with exponential backoff
363+
364+
4. **`download-logs`** command (GEI, ADO2GH) - Week 4
365+
- Fetch and save migration logs
366+
367+
5. **Additional commands** as needed
368+
369+
### Phase 4: Storage & Advanced Features (Planned - 2-3 weeks)
370+
- Azure Blob Storage client
371+
- AWS S3 client
372+
- Archive creation and upload
373+
- Multipart upload support
374+
- Remaining commands (lock-repo, disable-repo, etc.)
375+
376+
### Phase 5: Integration & Polish (Planned - 2 weeks)
377+
- Integration tests comparing C# vs Go outputs
378+
- Performance benchmarking
379+
- Documentation updates
380+
- Beta release preparation
381+
382+
## Important Note: GitHub API Client Strategy
383+
384+
**UPDATE:** The `gh` CLI provides a mature, well-tested API client library via `github.com/cli/go-gh/v2/pkg/api`.
385+
386+
**Plan Update:**
387+
- Phase 2: Keep current custom GitHub client for basic operations (already 93.9% complete)
388+
- Phase 3: During command implementation, evaluate switching to `go-gh/v2/pkg/api` for:
389+
- Authentication handling (already integrated with gh credentials)
390+
- GraphQL support (if needed)
391+
- Better GitHub.com API compatibility
392+
- Built-in rate limiting and retry logic
393+
394+
**Benefits of go-gh API client:**
395+
- Reuses existing `gh` authentication
396+
- Battle-tested by GitHub CLI team
397+
- Handles pagination, rate limiting, and retries
398+
- GraphQL and REST support
399+
- Better integration with GitHub ecosystem
400+
401+
**Decision Point:** After Phase 2 completes, we'll evaluate:
402+
1. Keep custom client (simpler, already working)
403+
2. Switch to go-gh (better long-term, more features)
404+
3. Hybrid approach (go-gh for complex operations, custom for simple ones)
405+
406+
## Script Generation Feature (Critical Path)
407+
408+
The primary usage model for GEI is:
409+
1. User runs `generate-script` command
410+
2. CLI generates a PowerShell script (`migrate.ps1`)
411+
3. User reviews/modifies the script
412+
4. User executes the script, which calls the CLI repeatedly
413+
414+
**Script Types:**
415+
- **Sequential**: Commands execute one-by-one, each waits for completion
416+
- **Parallel** (default): Queues all migrations, then waits for all to complete
417+
418+
**Script Structure:**
419+
```powershell
420+
#!/usr/bin/env pwsh
421+
# Version comment
422+
# Helper functions (Exec, ExecAndGetMigrationID)
423+
# Environment variable validation
424+
# Migration commands (or queue + wait)
425+
# Summary report (parallel only)
426+
```
427+
237428
## CI/CD
238429

239430
### GitHub Actions Workflow
@@ -257,18 +448,7 @@ During the transition period:
257448
- Both C# and Go CI workflows run
258449
- Both implementations tested against integration tests
259450
- Go version tagged as "beta" initially
260-
261-
## Next Steps: Phase 2 - API Clients
262-
263-
Phase 2 will implement the API clients:
264-
265-
- [ ] GitHub API client (`pkg/api/github/`)
266-
- [ ] Azure DevOps API client (`pkg/api/ado/`)
267-
- [ ] Bitbucket Server API client (`pkg/api/bbs/`)
268-
- [ ] Azure Blob Storage client (`pkg/api/azure/`)
269-
- [ ] AWS S3 client (`pkg/api/aws/`)
270-
- [ ] HTTP client infrastructure (retry, auth, logging)
271-
- [ ] Unit tests for all API clients
451+
- Integration tests compare C# vs Go script outputs
272452

273453
## Code Style
274454

@@ -279,13 +459,77 @@ Follow Go best practices:
279459
- Use `context.Context` for cancellation
280460
- Keep functions focused and testable
281461
- Document public APIs with godoc comments
462+
- Use `testdata/` for test fixtures
463+
464+
## Test Coverage Goals
465+
466+
- **Phase 1**: ✅ 44.9% initial coverage achieved
467+
- **Phase 2**: ✅ 80%+ achieved for all API client packages
468+
- pkg/app: ✅ 100.0%
469+
- pkg/http: ✅ 75.5%
470+
- pkg/github: ✅ 93.9%
471+
- pkg/ado: ✅ 88.0%
472+
- pkg/bbs: ✅ 91.1%
473+
- pkg/logger: ✅ 76.9%
474+
- pkg/retry: ✅ 96.2%
475+
- pkg/scriptgen: 🚧 Target 85%+
476+
- **Phase 3**: Maintain 75%+ overall coverage
477+
- **Phase 4**: Maintain 75%+ overall coverage
478+
479+
**Current Overall Coverage:** ~85% (packages with tests)
282480

283481
## Resources
284482

285483
- [Go Documentation](https://go.dev/doc/)
286484
- [Effective Go](https://go.dev/doc/effective_go)
287485
- [Cobra Documentation](https://cobra.dev/)
288-
- [Project Plan](GO_PORT_PLAN.md) (full migration plan)
486+
- [go-gh API Client](https://github.com/cli/go-gh)
487+
- [C# Source Code](src/) - Reference implementation
488+
- [CONTRIBUTING.md](CONTRIBUTING.md) - General contribution guidelines
489+
490+
## Current Sprint: Phase 2 Completion
491+
492+
**This Week's Goals:**
493+
1. ✅ Complete pkg/http with tests (75.5% coverage)
494+
2. ✅ Complete pkg/github with tests (93.9% coverage)
495+
3. ✅ Complete pkg/ado with tests (88.0% coverage)
496+
4. ✅ Complete pkg/bbs with tests (91.1% coverage)
497+
5. 🚧 Complete pkg/scriptgen with tests (target 85%+ coverage)
498+
6. 🚧 Add script validation tool
499+
500+
**Next Week's Goals (Phase 3 Start):**
501+
1. Implement `generate-script` command for GEI
502+
2. Implement `generate-script` command for ADO2GH
503+
3. Implement `generate-script` command for BBS2GH
504+
4. Add integration tests comparing C# vs Go script outputs
505+
5. Validate script equivalence in CI
506+
507+
## Script Validation
508+
509+
To ensure the Go port produces equivalent PowerShell scripts to the C# version, we've added a validation mechanism:
510+
511+
### Manual Validation
512+
513+
```bash
514+
# Generate scripts with both C# and Go versions
515+
dotnet run --project src/gei/gei.csproj -- generate-script --args... > csharp-script.ps1
516+
./dist/gei generate-script --args... > go-script.ps1
517+
518+
# Compare (ignoring version comments)
519+
diff -u --ignore-matching-lines="^# Generated by" csharp-script.ps1 go-script.ps1
520+
```
521+
522+
### Automated CI Validation
523+
524+
The CI workflow will automatically:
525+
1. Build both C# and Go versions
526+
2. Run `generate-script` with identical inputs
527+
3. Compare outputs (ignoring version metadata)
528+
4. Fail if scripts differ semantically
529+
530+
Script validation tests are located in:
531+
- `scripts/validate-scripts.sh` - Bash script for comparison
532+
- `.github/workflows/validate-scripts.yml` - CI integration
289533

290534
## Questions?
291535

0 commit comments

Comments
 (0)