# Contributing Thanks for improving gitlab-cli. This document covers building, testing, and submitting changes. This is a side project shared for AI tooling experimentation; maintainers do not provide commercial support or production guarantees — see the README disclaimer. ## Development setup - Go **1.25+** (see `go.mod`) - Optional: **Node.js 16+** if you work on the npm wrapper or platform-package scripts - Optional: **golangci-lint** (CI runs it on Linux) Clone and verify: ```bash git clone https://github.com/fatecannotbealtered/gitlab-cli.git cd gitlab-cli go mod download go test ./... go build -o bin/gitlab-cli ./cmd/gitlab-cli ./bin/gitlab-cli --help ``` If `go mod download` is slow, try a regional proxy, for example: ```bash # Example (China) set GOPROXY=https://goproxy.cn,direct ``` ## Commands | Goal | Command | |------|---------| | Run tests (race) | `go test -race ./...` | | Format | `gofmt -w .` | | Vet | `go vet ./...` | | Lint | `golangci-lint run ./...` (or `make lint` on Unix) | | Build with version | `make build` (Unix) or `go build -ldflags "-s -w -X github.com/fatecannotbealtered/gitlab-cli/cmd.version=dev" -o bin/gitlab-cli.exe ./cmd/gitlab-cli` (Windows) | | Local goreleaser snapshot | `make snapshot` | CI mirrors `.github/workflows/ci.yml`: tidy modules, gofmt check (Linux), golangci-lint, `go vet`, build, `go test -race`, and a `--help` smoke test on linux/macos/windows on the Go version pinned in `go.mod`. Local GitLab end-to-end tests (Docker Compose, 85 leaf commands): see [docs/E2E.md](docs/E2E.md) (**Windows / PowerShell** scripts; cross-platform notes inside). Run `go test -tags=integration ./e2e/...` after `scripts/e2e-up.ps1` on Windows. When adding commands, ensure `markWrite` / `markConfirm` / `markOutputType` annotations are set where applicable — they feed `gitlab-cli reference --compact`. ## Adding a new domain `gitlab-cli` is sliced by GitLab REST domain (e.g. `mr`, `issue`, `pipeline`). To add a new one: 1. **DTOs** → define them in `internal/api/.go` alongside the API methods (not in `types.go` — that file only contains the shared `User` type). 2. **API client** → create `internal/api/.go` with `type API struct{ client *Client }` and the methods you need; reuse `c.client.Get/Post/Put/Delete` and `EncodeProjectPath`. 3. **Wire into `Client`** → add a pointer field on `Client` in `internal/api/client.go` and instantiate it inside `NewClient`. Keep the field list alphabetical. 4. **Command** → create `cmd/.go` with a parent `Cmd` and one `Cobra` subcommand per action. In `init()`: - `parentCmd.AddCommand(childCmd)` for every subcommand. - Register flags on each subcommand's `.Flags()`. - For write commands, call `markWrite(cmd)` so they are recorded in audit logs. 5. **Tests** → - `internal/api/_test.go` using `httptest.Server`. - Add command-level behaviour tests to `cmd/cmd_test.go` (or split if it grows). 6. **AI Skill** → add detail to `skills/gitlab-cli/reference/.md`; keep `skills/gitlab-cli/SKILL.md` as a short index (progressive disclosure). Link new domains from the SKILL index table. 7. **Docs** → README.md / README_zh.md command list; add entries under `## [Unreleased]` in CHANGELOG.md (create the section when preparing the next release). 8. **Optional** → add a `FlatXxx` + `XxxToMap` in `internal/output/flatten_.go` if the JSON output should be flattened, and a `printXxxJSON` helper in your `cmd/.go` render path. `cmd/reference.go` walks the cobra tree automatically, so new commands appear in `gitlab-cli reference` without code changes. ## Functional contract coverage Release standard: **Functional Contract Coverage = 100%**. Every public behavior documented in README, Skill, `gitlab-cli reference`, `--help`, `context`, `doctor`, `changelog`, or `update` must have automated command-level tests. For each new or changed command, cover success, invalid arguments, config/auth/permission failure where applicable, upstream failure or timeout where applicable, JSON envelope shape, output schema, exit code, stdout/stderr boundary, and non-interactive behavior. Every bug fix that changes observable behavior needs a regression test. Numeric line coverage is tracked separately and may ratchet upward, but it does not replace missing contract tests. Release readiness is machine-readable: - `stable`: FCC is 100%, mock upstream/contract tests cover success and failure paths, and live smoke/E2E evidence is recorded for the release candidate. - `beta`: FCC is 100% and mock upstream/contract tests are complete, but live smoke/E2E evidence is missing or explicitly unavailable. - `unpublishable`: any public behavior lacks command-level tests, or mock upstream/contract tests cover only happy paths. Keep `gitlab-cli reference` `release_readiness` and `gitlab-cli doctor`'s `release_readiness` check honest when test evidence changes. ## Pull requests 1. **One logical change per PR** when possible. 2. **Tests**: add or update tests for behaviour changes. 3. **Docs**: update `README.md` / `README_zh.md` if user-facing flags change; add a line to `CHANGELOG.md` under `## [Unreleased]` when cutting the next version. 4. **Commits**: clear messages following Conventional Commits (`feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:`, `perf:`, `ci:`); no secrets or real tokens in code or docs. ## Security Do not open public issues for undisclosed security vulnerabilities. See [SECURITY.md](SECURITY.md).