fj/CHANGELOG.md
sid 0069198ca6
Some checks failed
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled
CI / test (push) Has been cancelled
CI / functional (push) Has been cancelled
chore: bump version to 0.4.0
CHANGELOG.md updated with the audit-driven hardening pass spanning
13 findings across cmd/ and internal/. Adds CLAUDE.md documenting
dev workflow, codex review pattern, release process, and homebrew
tap update steps.
2026-05-02 16:05:15 -06:00

13 KiB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.4.0] - 2026-05-02

Audit-driven hardening pass. Three reviewers (Codex + two Claude agents with non-overlapping focuses) found 13 issues across cmd/ and internal/; this release ships fixes for all 13.

BREAKING

  • --json=fields syntax removed. The flag was a string with NoOptDefVal=" " sentinel — --json alone meant "everything", --json=fields projected. That produced --json string[=" "] in --help and required a literal = because --json fields was parsed as the bare flag plus a positional. Migration: --json=fields--json-fields fields. Bare --json still means "all fields as JSON". --json and --json-fields are mutually exclusive; --jq composes with either.

Added

  • fj api --json / --json-fields / --jq — projection and jq filtering for raw API responses. Routes through the same addJSONFlags helpers as the other list commands. Closes the inconsistency where fj api was the only command returning raw JSON without these knobs.
  • fj api --paginate — follows RFC 5988 Link: rel="next" headers and concatenates JSON array pages, gh-compatible. Validates same-origin before forwarding the bearer token to the next URL.
  • cmd/paginate.go — generic paginateGitea[T any] helper. Applied to repo list, pr list, issue list. Previously only release list walked pages; the others passed PageSize: limit directly to the gitea SDK, which silently caps PageSize at 50, so --limit > 50 was truncated without warning.
  • CLAUDE.md — guide for Claude Code sessions: layout, codex review pattern, release process, homebrew tap update steps.

Changed

  • --json flag rebuilt as a plain Bool. --json-fields keeps comma-separated projection. Both registered via addJSONFlags and marked MutuallyExclusive.
  • cmd/actions.gorun and workflow subtrees converted from package-level vars to factory functions (newRunCmd, newWorkflowCmd, ...). cmd/aliases.go shrank from 142 → 17 lines and now calls those same factories with a parentLabel parameter that disambiguates the alias variant. Result: diff of fj run list --help flags vs fj actions run list --help flags is now empty. Drift between the two paths is structurally impossible.
  • fj api now uses internal/api.SharedHTTPClient (30s timeout, pooled connections) instead of a zero-value &http.Client{} with no timeout. A hung Forgejo no longer pins the CLI indefinitely.
  • fj api response body bounded by io.LimitReader at 64 MB to prevent OOM-on-self.
  • cmd/auth.go removed redundant local --hostname declarations on three subcommands. The persistent flag on rootCmd is now the only declaration; previously local declarations shadowed it, so fj --hostname=X auth login and fj auth login --hostname=X went through different code paths.
  • --token on auth login emits a stderr warning when used (visible in ps auxe and shell history). Flag not removed; just discoverable.
  • Error handling: Hint is now a structured field on CLIError. JSON-error consumers get clean structure; the human renderer still appends \nHint: .... Dropped substring matching of "401"/"403" against rendered error strings (would match issue #403); now relies exclusively on typed *api.APIError.
  • Network errors (no such host, connection refused, i/o timeout) return a structured CLIError with code ErrNetworkError and a hint.
  • Config dir created with mode 0700 instead of 0755.

Fixed

  • --config <path> now actually honored. Previously fed only into Viper; every command that touched config went through internal/config.Load() / Save() which always read the default path. So fj --config other.yaml auth login writes to other.yaml now.
  • fj run list --json, fj workflow list --json, fj wiki view --json now produce JSON. cmd/aliases.go registered --json as Bool but handlers called wantJSON() which does GetString("json") — pflag returned a type-error that wantJSON silently swallowed. cmd/wiki.go had the inverse bug (GetBool against an addJSONFlags-registered string flag). Both routed through addJSONFlags/wantJSON/outputJSON consistently now.
  • migrateConfigDir opens dst with O_TRUNC. Previously a partially- pre-existing dst file would have legacy contents overwrite a prefix and leave stale tail bytes — silent YAML/token corruption. Refactored close handling into copyOneConfigFile.

Security

  • fj api endpoint path traversal closed. fj api '/../admin/users' previously normalized through http.NewRequest to https://host/admin/users — silently sending authenticated traffic to non-API paths. Endpoint is now parsed via url.Parse, .. segments rejected, then JoinPath onto the /api/v1 base. URL-encoded %2E%2E is also caught because Go decodes before our split.
  • fj api --paginate validates same-origin before forwarding the bearer token to a Link: rel="next" URL. Refuses to reattach Authorization if the next URL's scheme isn't https or its host doesn't match the configured one.
  • initConfig warns on stderr if the resolved config file is world or group readable (mode & 0o077 != 0).

0.3.0c - 2026-03-21

Added

Label Management

  • fj label list - List repository labels
  • fj label create - Create a label with color and description
  • fj label edit - Edit label name, color, or description
  • fj label delete - Delete a label

Milestone Management

  • fj milestone list - List milestones with state filtering
  • fj milestone view - View milestone details
  • fj milestone create - Create a milestone with description and due date
  • fj milestone edit - Edit milestone title, description, due date, or state
  • fj milestone delete - Delete a milestone

Wiki Management

  • fj wiki list - List wiki pages
  • fj wiki view - View wiki page content
  • fj wiki create - Create a wiki page from flag or file
  • fj wiki edit - Edit a wiki page
  • fj wiki delete - Delete a wiki page

Issue Dependencies

  • fj issue edit --add-dependency <number> - Add issue dependency
  • fj issue edit --remove-dependency <number> - Remove issue dependency

0.3.0b - 2026-03-21

Added

Repository Management

  • fj repo edit - Edit repository settings (visibility, description, homepage, default branch)

Fixed

  • fj repo create --public flag was defined but never read; now properly wired up

0.3.0a - 2026-03-21

Added

Raw API Access

  • fj api <endpoint> - Make authenticated REST API requests to any Forgejo/Gitea endpoint
    • HTTP method selection (--method/-X), auto-switches to POST when fields are provided
    • JSON field assembly (--field/-f) with type inference (bool, int, float, null, string)
    • Raw string fields (--raw-field/-F)
    • Request body from file or stdin (--input)
    • Custom headers (--header/-H)
    • Path interpolation ({owner}, {repo}) from git context
    • Response header display (--include/-i)

Pull Request Management

  • fj pr diff <number> - View the diff for a pull request
    • Colorized output (--color auto/always/never)
    • Changed file names only (--name-only)
    • Diffstat summary (--stat)
  • fj pr comment <number> - Add a comment to a pull request
    • Body from flag (--body/-b) or file (--body-file, - for stdin)
    • JSON output (--json)
  • fj pr review <number> - Submit a review on a pull request
    • Approve (--approve/-a), request changes (--request-changes/-r), or comment (--comment/-c)
    • Body from flag or file
    • JSON output (--json)

Agentic / Machine-Readable Output

  • --json-errors global flag for structured JSON error output on stderr
    • Error codes: auth_required, not_found, api_error, invalid_input, git_detection_failed, network_error
    • HTTP status code and detail included when available
    • Automatic mapping of API errors (401/403 → auth_required, 404 → not_found)

0.3.0 - 2026-03-13

Added

Forgejo Actions

  • fj actions run watch <run-id> - Poll a run until completion
  • fj actions run rerun <run-id> - Trigger a rerun of a workflow run
  • fj actions run cancel <run-id> - Cancel an in-progress workflow run
  • fj actions workflow enable <workflow> - Enable a workflow
  • fj actions workflow disable <workflow> - Disable a workflow

Repository Management

  • fj repo create <name> - Create a new repository with full option set: --private/--public, --description, --add-readme, --gitignore, --license, --homepage, --clone, --team

Issue Management

  • fj issue create -l <label> - Assign labels when creating an issue
  • fj issue edit --add-label / --remove-label - Add or remove labels on existing issues
  • fj issue close -c <comment> - Close an issue with an optional comment

Workflow Management

  • fj actions workflow list/view/run - List, view, and trigger workflows

Auth Helpers

  • fj auth token - Print the stored token for the current host
  • fj auth logout - Remove authentication for a host

Shell Completions and Man Pages

  • fj completion [bash|zsh|fish|powershell] - Generate shell completion scripts
  • fj manpages --dir <path> - Generate man pages for all commands

JSON Output

  • --json flag for all list and view commands: PRs, issues, releases, workflow runs, workflows

Fixed

  • Respect $XDG_CONFIG_HOME for config file location (was always using ~/.config)

0.2.0 - 2026-01-09

Added

Release Management

  • fj release list - List releases for a repository
  • fj release view - View details of a specific release (supports "latest" keyword)
  • fj release create - Create new releases with optional asset uploads
  • fj release upload - Upload assets to existing releases with optional clobber support
  • fj release delete - Delete releases (preserves Git tags)

Issue Management

  • fj issue edit - Edit existing issues with support for updating title, body, and labels

Pull Request Management

  • fj pr create --assignee - Assign users when creating pull requests

Repository Detection

  • Automatic hostname detection from git remote URLs
  • Improved multi-instance support with auto-detection from git context

Improved

  • Enhanced documentation with AUR and Homebrew installation instructions
  • Added functional tests for release management and issue editing
  • Added Makefile install target for easier local installation
  • Added .editorconfig for consistent code formatting

Development

  • CI: Added nightly builds for continuous testing
  • Expanded functional test coverage for new features

0.1.0 - 2025-12-16

Added

Core Features

  • Initial release of fj - Forgejo CLI tool
  • Multi-instance support for any Forgejo/Gitea instance
  • Automatic repository detection from git context (optional -R flag)
  • Secure authentication with personal access tokens
  • Configuration management via ~/.config/fj/config.yaml

Pull Request Management

  • fj pr list - List pull requests with filtering by state
  • fj pr view - View detailed pull request information
  • fj pr create - Create new pull requests
  • fj pr merge - Merge pull requests with configurable merge methods

Issue Management

  • fj issue list - List issues with state filtering
  • fj issue view - View detailed issue information
  • fj issue create - Create new issues
  • fj issue comment - Add comments to issues
  • fj issue close - Close issues

Repository Operations

  • fj repo view - View repository details
  • fj repo list - List user repositories
  • fj repo clone - Clone repositories with protocol selection (HTTPS/SSH)
  • fj repo fork - Fork repositories

Forgejo Actions Support

  • fj actions run list - List workflow runs with status and metadata
  • fj actions run view - View detailed run information, jobs, and logs
    • Support for --verbose, --log, --log-failed, and --job flags
  • fj actions secret list - List repository secrets
  • fj actions secret create - Create repository secrets
  • fj actions secret delete - Delete repository secrets
  • fj actions variable list - List repository variables
  • fj actions variable get - Get variable values
  • fj actions variable create - Create repository variables
  • fj actions variable update - Update repository variables
  • fj actions variable delete - Delete repository variables

Authentication

  • fj auth login - Interactive authentication with Forgejo instances
  • fj auth status - Check authentication status
  • Environment variable support (FJ_HOST, FJ_TOKEN)

Development

  • Comprehensive unit test suite
  • Functional end-to-end tests
  • CI/CD pipeline with automated testing
  • Code quality checks and linting

Technical Details

  • Built with Go 1.23+
  • Uses Gitea SDK for API interactions
  • Cobra framework for CLI structure
  • Viper for configuration management