Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Fixed

- `grant login` no longer hangs on WSL2; grant now detects WSL and forces the file-based keyring. A token stored in the OS keyring becomes invisible — re-run `grant login` if prompted

### Added

- End-to-end self-update tests that replace a real, running binary (`internal/selfupdate/e2e_test.go`, build tag `selfupdate_e2e`). They compile two fixture binaries from a dependency-free module, execute one, and swap it through grant's own apply path while a process is still running from that image — so the Windows file-locking semantics behind the two-rename swap are actually exercised, not just the bookkeeping. Success and rollback paths are both covered, and the rolled-back binary is asserted to still run. No network access is required
- CI runs the new self-update end-to-end tests on **both** `ubuntu-latest` and `windows-latest`, closing the gap left by the Windows CI leg added in 0.8.0, which only ran `go build` and `go test` and never exercised a binary replacing itself on Windows
- End-to-end self-update tests that replace a real, running binary, covering both the success and rollback paths (build tag `selfupdate_e2e`)
- CI runs the self-update end-to-end tests on both `ubuntu-latest` and `windows-latest`
- `grant revoke --output json` gains a per-session `outcome` field

### Fixed

- `grant revoke` now exits 1 when the service refused, returned an unrecognized status for, or returned no result at all for any requested session, instead of reporting success; accepted-but-`in_progress` revocations still exit 0, and `--output json` gains a per-session `outcome` field — check scripts relying on exit 0.
- `grant login` no longer hangs on WSL2; grant now detects WSL and forces the file-based keyring. A token stored in the OS keyring becomes invisible — re-run `grant login` if prompted
- `grant revoke` now exits 1 when any requested session was not accepted for revocation, instead of reporting success — check scripts relying on exit 0

## [0.8.0] - 2026-08-14

Expand Down
16 changes: 13 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Project
- **Language:** Go 1.25+
- **Module:** `github.com/aaearon/grant-cli`
- **Dependencies:** `github.com/cyberark/idsec-sdk-golang` is the primary dependency; zero-new-Go-module-deps is a goal, not an absolute rule. Documented exception: `github.com/minio/selfupdate` (+ its one transitive `aead.dev/minisign`) for `grant update`, adopted to remove the abandoned `rhysd/go-github-selfupdate` and advisory GO-2026-5932. Net effect: build graph (`go list -deps`) 39 -> 33 modules, `go.mod` requires 47 -> 39, full module graph (`go list -m all`) 110 -> 95
- **Dependencies:** `github.com/cyberark/idsec-sdk-golang` is the primary dependency; zero-new-Go-module-deps is a goal, not an absolute rule. Documented exception: `github.com/minio/selfupdate` (+ its one transitive `aead.dev/minisign`) for `grant update`, adopted to remove the abandoned `rhysd/go-github-selfupdate` and advisory GO-2026-5932. It was a net *reduction* in every dependency measure — the exception cost nothing. Measure with `go list -deps` / `go list -m all` if a current figure is needed; do not record one here

## SDK Import Conventions
```go
Expand Down Expand Up @@ -125,7 +125,7 @@ Custom `SCAAccessService` follows SDK conventions:
- `internal/ui/tty.go` — `IsTerminalFunc` (overridable), `IsInteractive()`, `ErrNotInteractive`
- All interactive prompts (`SelectTarget`, `SelectSessions`, `ConfirmRevocation`, `SelectGroup`, `uiUnifiedSelector.SelectItem`, `surveyNamePrompter.PromptName`) fail fast with `ErrNotInteractive` when stdin is not a TTY
- Error messages suggest the appropriate non-interactive flag (e.g., `--target/--role`, `--all`, `--yes`, `--group`, `--favorite`)
- `go-isatty` v0.0.20 is a direct dependency (promoted from indirect via survey)
- `go-isatty` is a direct dependency (promoted from indirect via survey); see `go.mod` for the pinned version

## JSON Output
- `--output` / `-o` persistent flag on root command: `text` (default) or `json`
Expand Down Expand Up @@ -191,7 +191,7 @@ Custom `SCAAccessService` follows SDK conventions:

## Lint
- Config: `.golangci.yml` (golangci-lint v1 format)
- 20 linters enabled: defaults (errcheck, gosimple, govet, ineffassign, staticcheck, unused) + bodyclose, errorlint, noctx, gosec (G101 excluded), errname, gocritic, misspell, revive, gocognit (threshold 40), perfsprint, unconvert, usetesting, gofmt (`simplify: true`)
- Linters enabled (`disable-all: true`, so this list is exhaustive): defaults (errcheck, gosimple, govet, ineffassign, staticcheck, unused) + bodyclose, errorlint, noctx, gosec (G101 excluded), errname, gocritic, misspell, revive, gocognit (threshold 40), perfsprint, unconvert, usetesting, gofmt (`simplify: true`)
- Test files excluded from gosec, gocognit, bodyclose — `gofmt` has no exclusion, formatting is universal
- Run `gofmt -s -w .` before committing; `gofumpt` was rejected because the codebase is not gofumpt-clean
- `revive/unused-parameter` and `revive/exported` disabled (Cobra signatures, established API names)
Expand All @@ -208,6 +208,8 @@ make lint # Run linter (golangci-lint)
make clean # Clean build artifacts
```
- `-trimpath` used in both `Makefile` and `.goreleaser.yaml` for reproducible builds
- `VERSION ?= dev` (`Makefile:2`) is injected as `-X ...cmd.version=$(VERSION)` (`Makefile:5-8`), so a plain `make build` stamps `version=dev`. `runUpdate` refuses `""`/`"dev"` (`cmd/update.go:38-39`, "cannot update a dev build"), so `grant update` can never succeed on a default local build
- To exercise `grant update` locally: `make build VERSION=0.7.0`, then `./grant update`. Use a version *older* than the latest release so an update is actually found
- `.goreleaser.yaml` uses `CommitDate` (not build date) and `mod_timestamp` for reproducibility

## CI
Expand All @@ -219,6 +221,14 @@ make clean # Clean build artifacts
- Tests must be OS-portable. Never assert POSIX permission bits without a `runtime.GOOS == "windows"` skip: Go synthesizes `0666`/`0777` for Windows files and `os.Chmod` there only toggles the read-only attribute. Current skips: `internal/config/config_test.go` (`TestLoadConfig_PermissionError`, `TestConfigDir_Error` — chmod 0000 and `HOME`) and `internal/cache/cache_test.go` (`TestSet_FilePermissions`)
- Prefer a portable construction over a skip where one exists. To force a write failure, point at a path whose parent component is an existing regular file (`MkdirAll` fails with ENOTDIR on POSIX and ERROR_DIRECTORY on Windows) rather than a hardcoded `/dev/null/...` path, which is an ordinary writable location on Windows

## CHANGELOG Style
Entries are short and concise. This applies to `[Unreleased]` and everything added from now on; already-released sections are published history and are not rewritten.
- One line per entry — a single sentence, ideally under ~120 characters.
- Say WHAT changed and, where it isn't obvious, the user-visible effect. Not the mechanism, not the root cause, not measurements, not `file:line` references.
- Rationale, evidence, benchmarks, dependency counts and advisory analysis go in the PR description. Durable architecture and policy go in CLAUDE.md.
- Keep the Keep-a-Changelog section headings: `Added` / `Changed` / `Fixed` / `Security`.
- A breaking or behaviour-changing entry may add a short second clause naming the impact. Brevity must never hide a behavioural break from someone skimming before an upgrade.

## Release Process
1. Move `[Unreleased]` entries in `CHANGELOG.md` to a new `[X.Y.Z] - YYYY-MM-DD` section (leave `[Unreleased]` header empty)
2. Commit: `docs: prepare CHANGELOG for vX.Y.Z release`
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ make test-all # All tests
make lint # Lint (golangci-lint)
```

`make build` stamps the version as `dev`, and `grant update` refuses to update a dev build. To try `grant update` locally, build with an explicit version older than the latest release: `make build VERSION=0.7.0`.

## Contributing

Contributions welcome! Please follow existing patterns, write tests (TDD preferred), update docs, and use conventional commits.
Expand Down
Loading