|
| 1 | +# gh-ext--issue-sync |
| 2 | + |
| 3 | +GitHub CLI extension that syncs issues to local markdown files with YAML |
| 4 | +frontmatter. |
| 5 | + |
| 6 | +## Project Structure |
| 7 | + |
| 8 | +- `main.go` — Entry point |
| 9 | +- `cmd/` — Cobra command definitions (root, pull, push, status) |
| 10 | +- `cmd/cmd_test.go` — Command tests using mock client |
| 11 | +- `internal/sync/` — Core sync logic, Client interface, and GHClient (gh CLI) |
| 12 | +- `internal/sync/client.go` — Client interface (abstraction for testability) |
| 13 | +- `internal/sync/github.go` — GHClient: real implementation using `gh` CLI |
| 14 | +- `internal/sync/push.go` — Push logic with milestone title-to-number resolution |
| 15 | +- `internal/sync/issue.go` — Issue and IssueFrontmatter types |
| 16 | +- `internal/frontmatter/` — Generic YAML frontmatter marshal/unmarshal |
| 17 | +- `mise/tasks/` — Build, test, lint tasks (bash scripts with `#MISE` pragmas) |
| 18 | +- `.github/workflows/` — CI (build+test+lint) and release (precompile on tag) |
| 19 | + |
| 20 | +## Development |
| 21 | + |
| 22 | +- **Build**: `mise run build` or `go build ./...` |
| 23 | +- **Test**: `mise run test` or `go test -cover ./...` |
| 24 | +- **Lint**: `mise run lint` (go vet + prettier) |
| 25 | +- **All checks**: `mise run check` |
| 26 | + |
| 27 | +## Conventions |
| 28 | + |
| 29 | +- Go code uses standard `go vet` linting |
| 30 | +- Non-Go files use prettier for formatting |
| 31 | +- Mise tasks are the source of truth for all build/lint/test logic |
| 32 | +- CI workflows are thin wrappers around mise tasks |
| 33 | +- Commit messages follow conventional commits (`feat:`, `fix:`, `chore:`, |
| 34 | + `docs:`) |
| 35 | + |
| 36 | +## Architecture Decisions |
| 37 | + |
| 38 | +- **Client interface** (`sync.Client`): All GitHub operations go through this |
| 39 | + interface. The real `GHClient` shells out to `gh` CLI. Tests use a mock |
| 40 | + client. This keeps commands testable without network access. |
| 41 | +- **Frontmatter is generic**: The `frontmatter` package knows nothing about |
| 42 | + GitHub. It just serializes/deserializes YAML frontmatter + markdown body. |
| 43 | +- **Pull requests are filtered**: GitHub's issues API returns PRs too. We filter |
| 44 | + them out via the `pull_request` field. |
| 45 | +- **Milestone resolution**: Push resolves milestone titles to numbers via the |
| 46 | + milestones API. Status compares milestone titles directly. |
| 47 | +- **Label/assignee comparison is order-independent**: Status sorts before |
| 48 | + comparing to avoid false positives from API ordering. |
0 commit comments