doc/development/documentation/cli_styleguide.md
These guidelines define the required structure, content, and language conventions
for the glab CLI reference documentation.
It extends the documentation style guide with rules
specific to the Markdown files generated by make gen-docs in the gitlab-org/cli project.
Use these guidelines when you:
glab command to gitlab-org/cli.CLI documentation is generated from Go source files in
gitlab-org/cli.
The generator (make gen-docs) produces one Markdown file per command and writes
the output to docs/source/. The generated files are the source of truth for the
GitLab CLI (glab) documentation.
[!note] Do not edit files in
docs/source/directly. All content must be authored in the Go source. Changes to the generated files are overwritten the next timemake gen-docsruns.
If you change Go source strings that affect the generated output, run make gen-docs
and commit the updated files as part of your merge request. The check_docs_update
CI/CD job runs make gen-docs and fails if it detects uncommitted changes to the
generated files.
To catch documentation issues before pushing your commits, run make bootstrap to install Lefthook.
The pre-commit hook regenerates documentation when command files change and blocks
the commit until the updated files are staged.
For more information, see Git hooks with Lefthook.
Every generated CLI documentation page must include the following sections, in this order:
The following table shows the mapping between each page section and the Go source field that generates it:
| Page section | Go source |
|---|---|
| Title | Full command path from the CommandPath() method. |
| Short description | Short field of cobra.Command. |
| Synopsis | Long field of cobra.Command. |
| Usage line | UseLine() method of cobra.Command. |
| Aliases | Aliases field of cobra.Command. |
| Examples | Example field of cobra.Command. |
| Options | Flag definitions (cmd.Flags() and cmd.PersistentFlags()). |
| Options inherited from parent commands | Parent command's persistent flags. |
| Subcommands | Subcommand names registered with cmd.AddCommand(). |
The title is the full command invocation, formatted as inline code. For example:
title: '`glab mr create`'
The title is generated from the Go source command name. Do not edit it manually.
The short description is generated from the Short field of the Go command definition. It is a single sentence that describes what the command does.
Create a new merge request.(EXPERIMENTAL) after the sentence.
For example: Create a new stacked diff. (EXPERIMENTAL)All new commands must include a Synopsis. The Synopsis is generated from the Long
field of the Go command definition and provides extended context that cannot fit in
the short description. For example, when a command:
Use lists for multiple constraints or input types. Do not repeat information already in the short description.
The usage line appears in the Synopsis section and in the --help output.
Use the following conventions for positional arguments:
| Argument type | Convention | Example |
|---|---|---|
| Required | <arg> | glab mr view <id> |
| Optional | [<arg>] | glab ci trace [<job-id>] |
| One of several, required | <id | branch | url> | glab mr checkout <id | branch | url> |
| One of several, optional | [<id | branch>] | glab mr note list [<id | branch>] |
Two constants are defined in internal/text/text.go for marking features that are
not yet ready for production use:
text.ExperimentalString: for features that are experimental.text.BetaString: for features that are in beta.Append text.ExperimentalString or text.BetaString to the Long field. The
correct pattern depends on how the Long field is defined:
heredoc.Doc or heredoc.Docf with concatenation: Both functions strip
trailing whitespace from the template, so ExperimentalString's own leading
newline provides the separator. No explicit "\n" is needed:
Long: heredoc.Doc(`
Your command description here.
`) + text.ExperimentalString,
heredoc.Docf with a %s placeholder: Pass the constant as a format
argument. The leading newline in the constant provides the separator:
Long: heredoc.Docf(`
Your command description here.
%s`, text.ExperimentalString),
Raw string literal: The literal is not stripped, so end it with an explicit newline before the closing backtick:
var longString = `Your command description here.
` + text.ExperimentalString
If the raw string does not end with a newline, add an explicit "\n" separator:
Long: `Your command description here.` + "\n" + text.ExperimentalString,
This produces the following text in the Synopsis section of the generated documentation:
This feature is an experiment and is not ready for production use.
It might be unstable or removed at any time.
For more information, see
https://docs.gitlab.com/policy/development_stages_support/.
For beta commands, use text.BetaString in the same way. This produces:
This feature is in beta and might not be ready for production use.
It might be unstable and breaking changes can occur outside of major releases.
For more information, see
https://docs.gitlab.com/policy/development_stages_support/.
Do not copy these strings manually into the Long field. Always use the constants
so that any future changes to the wording are applied consistently across all commands.
When only an individual flag is experimental (not the whole command), add a brief Synopsis note to indicate this. For example:
The --publish-to-catalog flag is experimental and requires the
`ci_release_cli_catalog_publish_option` feature flag to be enabled for your project.
If a feature requires a feature flag to be enabled, document this requirement in the Synopsis.
Experimental features can be modified or removed without a breaking change. When a feature moves from experimental to generally available (GA):
(EXPERIMENTAL) from the short description.text.ExperimentalString (or text.BetaString) from the Long field.(EXPERIMENTAL) from any flag descriptions.make gen-docs and commit the updated files.List any aliases for the command. This section is generated automatically from the
Aliases field of the Go command definition. Do not edit it manually.
The Examples section is generated from the Example field of the Go command definition.
Every command must include at least one example that demonstrates real-world usage.
Do not use examples that only repeat the usage line.
# Comment text format.For example:
# Create a merge request and assign it to yourself
glab mr create -a @me -t "Fix the login bug"
# Create a draft merge request from the current branch
glab mr create --draft --fill
The Options section lists all flags specific to the command. This section is generated from the Go source flag definitions.
When writing flag descriptions in Go source:
Start with a capital letter.
End with a period.
Use angle-bracket placeholders for user-supplied values.
For example: <username>, <branch>.
For boolean flags with a true default, pflag automatically appends (default true) in the
generated Markdown output. Do not add it manually. No default annotation is required for boolean
flags with a false default.
Use standard metavars for common value types:
| Value type | Metavar |
|---|---|
| Username | username |
| Branch name | string |
| File path | string |
| Integer ID | int |
| Output format | string |
For output format flags, use -F, --output [text | json] as the canonical form.
Some commands use a different short flag due to naming conflicts with other flags
in the same command.
When a flag is experimental, prepend (EXPERIMENTAL) to its description. For example:
--publish-to-catalog (EXPERIMENTAL) Publish the release to the GitLab CI/CD catalog.
Also add a Synopsis note explaining the experimental status and any feature flag requirements. For more information, see experimental and beta features.
This section lists flags available to all subcommands in a group,
such as --help and --repo. It is generated automatically from the parent
command's inherited flags. Do not edit it manually. Changes to inherited flags
must be made in the parent command's Go source.
The Subcommands section appears only on parent command index pages (_index.md).
For example, in the glab ci and glab mr pages.
It is generated automatically as a bulleted list of links to each subcommand page.
Do not edit it manually.
MR titles are validated by the commit-lint CI job. Because squash on merge is
enabled by default, the MR title becomes the commit message when the MR is merged.
The title must follow the conventional commits format defined in the project's
contributing guidelines.
Every generated page includes front matter. The stage and group values are
hardcoded in the generator (cmd/gen-docs/docs.go) to Create and
Code Review for all commands. Do not edit these values in the generated files.
They are overwritten each time make gen-docs runs.
The canonical reference for all environment variables that affect glab behavior
is the environment variables section of the gitlab-org/cli README.
This includes GitLab access variables (such as GITLAB_TOKEN and GITLAB_HOST),
glab configuration variables (such as BROWSER, NO_PROMPT, and GLAMOUR_STYLE),
and their config.yml equivalents and defaults.
Environment variables that affect glab behavior globally are documented on the
root command page, generated from the help:environment annotation in the Go source.
Do not duplicate the full variable list in individual command pages.
When a specific command's behavior is also affected by an environment variable, reference it in the Synopsis. List the variable in inline code, followed by a description of its effect in the context of that command. For example:
If `GITLAB_TOKEN`, `GITLAB_ACCESS_TOKEN`, or `OAUTH_TOKEN` are set,
they take precedence over the stored credentials.
When you deprecate a flag with MarkDeprecated, Cobra prepends a fixed prefix to your message:
Flag --<flag> has been deprecated, <your message>
Cobra's prefix ends in a comma. Start your message as a sentence continuation with
a lowercase first letter and end with a period.
For example, use --output instead. produces:
Flag --output-format has been deprecated, use --output instead.
When the deprecated flag has a direct replacement, end the message with use --<replacement> instead..
When there is no replacement, describe the resulting behavior. For example, tracking is enabled by default..
Avoid time-relative words like now or currently in deprecation messages.
This convention parallels the REST API deprecation guidance, adapted for Cobra's wrapper.
glab officially supports GitLab 16.0 and later. If a command or flag requires
a more recent version of GitLab to work correctly, document this requirement in
the Synopsis. For example:
This command requires GitLab 17.0 or later.
glab follows SemVer. The versioning rules have direct
implications for how you document commands and flags:
| Change type | Version bump | Documentation note |
|---|---|---|
| Delete a command, change its behavior, or add a required flag | MAJOR | Clearly describe the breaking change in the Synopsis and in the MR description. |
| Add a new command or optional flag | MINOR | No special documentation treatment required. |
| Fix a bug | PATCH | No special documentation treatment required. |
[!note] Experimental and beta features are not guaranteed to be stable and can be modified or removed without a breaking change.