From 587381f06c0817085a0f123072ba36fc450560dc Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Tue, 26 May 2026 14:01:46 -0600 Subject: [PATCH 1/5] Add CLI-specific details to CONTRIBUTING.md Signed-off-by: Adam Wolfe Gordon --- CONTRIBUTING.md | 115 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54aac40..b6cc206 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1,114 @@ -See Crossplane's [contributing](https://github.com/crossplane/crossplane/tree/main/contributing). +# Contributing to the Crossplane CLI + +Welcome to the Crossplane CLI, and thank you for your interest in contributing. + +Please start by reading the [Crossplane contributing document]. The Crossplane +CLI follows the same guidelines and policies as the core Crossplane project, +including coding style. We also use a similar Nix-based development environment. + +The CLI maintainers primarily communicate in the [#sig-cli] channel on Slack. + +Topics specific to CLI development are covered below. + +## The Command Tree + +The Crossplane CLI's command tree follows a noun-first structure. This means all +top-level commands are nouns (`cluster`, `composition`, `dependency`) rather +than verbs (`get`, `list`, `generate`). New commands should be added under the +relevant noun, or a new noun if needed. Please feel free to ask on Slack or +propose a new command in an issue if you aren't sure where a new command should +go. + +## kong + +We use [kong] as our CLI framework. Each command is defined as a struct, in +which fields become subcommands, positional arguments, or flags. Kong's [struct +tags] can be used to control many behaviors, including validation, +auto-completion, and documentation. + +## Command Maturity Levels + +We have three maturity levels for commands: + +- Generally Available (GA): Stable commands that will not be removed or have + breaking changes made without considerable notice. +- Beta: Commands that are relatively stable and unlikely to be removed, but may + have breaking changes made in a subsequent minor version. +- Alpha: Experimental commands that may change significantly or be removed at + any time. + +Alpha and beta commands are marked as such using a custom kong struct tag, +`maturity:"alpha"` or `maturity:"beta"`. These struct tags control two things: + +1. Alpha commands are hidden from the help output by default. Users must enable + showing alpha commands in their CLI configuration file. +2. Alpha and beta commands automatically have notes added to their help text + indicating the maturity level and what it means. + +Note that in the past alpha and beta commands were put under separate command +trees (`crossplane alpha` and `crossplane beta`). We have moved away from this +scheme in order to help keep the command tree and codebase more stable as +commands mature. + +## Embedded Documentation + +The CLI is self-documenting. Short descriptions for commands and flags should be +added using kong struct tags. Longer help should be returned by each command's +`Help()` method. This help should be formatted using markdown, which we render +in the console using the [glamour] library. + +The `crossplane generate-docs` command is used to generate CLI reference +documentation for [docs.crossplane.io]. Markdown returned by each command's +`Help()` is embedded nearly verbatim into this documentation. Please observe the +following guidelines in order to make the docs look as good as possible: + +- Don't put a top-level heading on your Markdown-formatted detailed help. An + appropriate heading will be added automatically in both terminal usage and + docs generation. +- Use level 2 headings (`##`) and below for sections in your help text. These + will render correctly in the terminal, and be adjusted as needed by the + `generate-docs` command to ensure the documentation page is properly + structured. +- Use inline code and code blocks for commands, flags, arguments, etc. This + looks good when rendered, and avoids spelling and grammar false positives. + +If in doubt about whether your help will look good, you can easily check your +work by cloning the [crossplane/docs](https://github.com/crossplane/docs) repo, +running `crossplane generate-docs -o content/master/cli/command-reference.md` to +update the CLI reference section, and then running `hugo serve` to preview it +locally. + +### The `vale` Linter + +The Crossplane documentation uses [vale] to enforce spelling and style +guidelines. This repository includes a CI check that generates documentation and +runs `vale` using the configuration from [crossplane/docs] to ensure that our +generated documentation does not trigger any warnings or errors. + +It is sometimes unavoidable to have help text that triggers vale warnings or +errors. For example, the heading for the help section about the `crossplane +config` command includes the word "config" outside a code block, causing vale to +suggest that we replace it with "configuration". For these situations, it is +possible to temporarily disable specific vale rules in two ways: + +1. If the problem is in detailed Markdown help, use [vale Markdown comments]. +2. If the problem is in help generated by kong (command names, flag + descriptions, etc.), use our custom `novale:"..."` kong tag. This will result + in a Markdown comment of the form `` being generated at + the top of the relevant command's documentation section with a matching `= + YES` comment at the bottom. + +In both cases, please scope vale overrides as tightly as possible and ensure all +rules are re-enabled after the problematic section. Prefer to disable specific +matches rather than whole rules, and rules rather than whole styles. + + + +[Crossplane contributing document]: https://github.com/crossplane/crossplane/tree/main/contributing +[#sig-cli]: https://crossplane.slack.com/archives/C08V9PMLRQA +[kong]: https://pkg.go.dev/github.com/alecthomas/kong +[struct tags]: https://pkg.go.dev/github.com/alecthomas/kong#readme-supported-tags +[glamour]: https://pkg.go.dev/github.com/charmbracelet/glamour +[docs.crossplane.io]: https://docs.crossplane.io/latest/cli/command-reference/ +[vale]: https://vale.sh +[vale Markdown comments]: https://vale.sh/docs/formats/markdown#comments From 70b49c2a26f9872f7ec3a587f113d967f68d47ae Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Wed, 27 May 2026 15:47:38 -0600 Subject: [PATCH 2/5] Add installation instructions and a docs link to the README Signed-off-by: Adam Wolfe Gordon --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index 908c32a..09d1802 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,37 @@ platforms on top of Crossplane and working with Crossplane clusters. Crossplane is a [Cloud Native Computing Foundation][cncf] project. +## Installation + +The Crossplane CLI is a single binary, which we build for macOS, Linux, and +Windows. You can download the latest version using the install script: + +```shell +curl -sfL "https://cli.crossplane.io/install.sh" | sh +``` + +The script detects your operating system and CPU architecture and downloads the +appropriate binary to the current directory. Note that it does not attempt to +place the binary in your shell's `$PATH`, so you may want to move it. + +To install a different version of the CLI, set `XP_VERSION` when running the +install script: + +```shell +curl -sfL "https://cli.crossplane.io/install.sh" | XP_VERSION=v2.3.1 sh +``` + +To install the latest build from our main branch, set `XP_CHANNEL=master`: + +```shell +curl -sfL "https://cli.crossplane.io/install.sh" | XP_CHANNEL=master sh +``` + +## Reference Documentation + +Command reference documentation for the CLI can be found on +[docs.crossplane.io](https://docs.crossplane.io/latest/cli/command-reference/). + ## License Crossplane is under the Apache 2.0 license. From f46a668890191b8d16a3a3db97184d20dff09b81 Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Thu, 28 May 2026 13:46:25 -0600 Subject: [PATCH 3/5] contributing: Clarify maturity levels and docs testing Signed-off-by: Adam Wolfe Gordon --- CONTRIBUTING.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b6cc206..02feac0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,6 +45,11 @@ Alpha and beta commands are marked as such using a custom kong struct tag, 2. Alpha and beta commands automatically have notes added to their help text indicating the maturity level and what it means. +If a command is not tagged with a maturity level, it will inherit from its +parent in the command tree. This means that if you're introducing a whole tree +of commands into beta, only the parent needs to be tagged. Commands without a +maturity level anywhere in their tree are considered GA. + Note that in the past alpha and beta commands were put under separate command trees (`crossplane alpha` and `crossplane beta`). We have moved away from this scheme in order to help keep the command tree and codebase more stable as @@ -73,10 +78,19 @@ following guidelines in order to make the docs look as good as possible: looks good when rendered, and avoids spelling and grammar false positives. If in doubt about whether your help will look good, you can easily check your -work by cloning the [crossplane/docs](https://github.com/crossplane/docs) repo, -running `crossplane generate-docs -o content/master/cli/command-reference.md` to -update the CLI reference section, and then running `hugo serve` to preview it -locally. +work by generating the docs locally: + +```shell +# Clone the docs repository. +git clone https://github.com/crossplane/docs.git +cd docs + +# Generate the docs. +crossplane generate-docs -o content/master/cli/command-reference.md + +# Build the docs serve them locally for preview. +hugo serve +``` ### The `vale` Linter @@ -112,3 +126,4 @@ matches rather than whole rules, and rules rather than whole styles. [docs.crossplane.io]: https://docs.crossplane.io/latest/cli/command-reference/ [vale]: https://vale.sh [vale Markdown comments]: https://vale.sh/docs/formats/markdown#comments +[crossplane/docs]: https://github.com/crossplane/docs From 76454f0e66068061618d414fe9e247760b6b5d62 Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Fri, 29 May 2026 14:42:21 -0600 Subject: [PATCH 4/5] contributing: Add missing 'and' Signed-off-by: Adam Wolfe Gordon --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 02feac0..1bfef47 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -88,7 +88,7 @@ cd docs # Generate the docs. crossplane generate-docs -o content/master/cli/command-reference.md -# Build the docs serve them locally for preview. +# Build the docs and serve them locally for preview. hugo serve ``` From 0e2d422897fff6a59acf43dca6415ed6a0249d3b Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Fri, 29 May 2026 14:44:35 -0600 Subject: [PATCH 5/5] ci: Show generated docs if vale fails, for debugging Signed-off-by: Adam Wolfe Gordon --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6770d70..2d3bfe1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -213,3 +213,8 @@ jobs: fail_on_error: true reporter: local filter_mode: nofilter + + - name: Show generated docs on failure + if: ${{ failure() }} + run: | + cat ./docs/content/master/cli/command-reference.md