|
| 1 | +--- |
| 2 | +title: Versioning documentation |
| 3 | +intro: '{% data variables.product.prodname_docs %} uses YAML frontmatter and liquid operators to support multiple versions of {% data variables.product.company_short %} with a single-source approach.' |
| 4 | +product: '{% data reusables.contributing.product-note %}' |
| 5 | +versions: |
| 6 | + feature: 'contributing' |
| 7 | +--- |
| 8 | + |
| 9 | +On {% data variables.product.prodname_docs %}, we provide versions of our documentation that reflect the differences in UI and functionality across {% data variables.product.company_short %}'s major product offerings. Contributors can use versioning syntax to scope content to a specific product offering. |
| 10 | + |
| 11 | +Versioning syntax allows the reader to manually choose the version of the documentation that applies to the product they're using. {% data variables.product.prodname_docs %}' URLs can also include versioning information, which allows links from {% data variables.product.prodname_dotcom_the_website %}, {% data variables.product.prodname_ghe_server %}, and {% data variables.product.prodname_ghe_managed %} to send the reader directly to documentation for the product they're using. |
| 12 | + |
| 13 | +## How and where to version |
| 14 | + |
| 15 | +Versioning for content on {% data variables.product.prodname_docs %} is single-source to avoid repetition and keep prose [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). For articles, you apply versioning to an individual Markdown file with YAML metadata, then use conditional statements within the file's prose to instruct the site which text to display depending on the version the reader selects. Single-sourcing contrasts to the creation of separate files that reflect each version of the content. |
| 16 | + |
| 17 | +There are two types of versioning syntax for {% data variables.product.prodname_docs %}. |
| 18 | + |
| 19 | +- YAML: Used most often in YAML front matter within Markdown files in `content/`, but also in many types of YAML files in `data/`. Indicates the versioning for an entire piece of content. |
| 20 | + |
| 21 | + ```yaml |
| 22 | + versions: |
| 23 | + PRODUCT: 'VERSIONS' |
| 24 | + PRODUCT: 'VERSIONS' |
| 25 | + ... |
| 26 | + ``` |
| 27 | + |
| 28 | + The following example shows content versioned for {% data variables.product.prodname_dotcom_the_website %}, and all versions of {% data variables.product.prodname_ghe_server %}. |
| 29 | + |
| 30 | + ```yaml |
| 31 | + versions: |
| 32 | + fpt: * |
| 33 | + ghes: * |
| 34 | + ``` |
| 35 | + |
| 36 | +- Liquid: Used within Markdown files in `content/` and `data/reusables/`, variable strings within YAML files in `data/variables/`, or strings within `data/glossaries/external.yml`. Indicates which text should appear when a reader chooses a version for content that has multiple versions defined by YAML front matter. |
| 37 | + |
| 38 | + - Product-based versioning: |
| 39 | + |
| 40 | + ```javascript |
| 41 | + {% raw %}{% ifversion SHORT-PRODUCT-NAME %} ... {% endif %}{% endraw %} |
| 42 | + ``` |
| 43 | + |
| 44 | + - Feature-based versioning: |
| 45 | + |
| 46 | + ```javascript |
| 47 | + {% raw %}{% ifversion FEATURE-NAME %} ... {% endif %}{% endraw %} |
| 48 | + ``` |
| 49 | + |
| 50 | +## About the different versions of {% data variables.product.company_short %} |
| 51 | + |
| 52 | +We provide versioned documentation for users of {% data variables.product.prodname_dotcom_the_website %} plans including {% data variables.product.prodname_ghe_cloud %}, {% data variables.product.prodname_ghe_server %}, and {% data variables.product.prodname_ghe_managed %}. If multiple versions of a page exist on the site, readers can choose the version from the version picker at the top of the page. |
| 53 | + |
| 54 | +### {% data variables.product.prodname_dotcom_the_website %} |
| 55 | + |
| 56 | +Documentation for {% data variables.product.prodname_dotcom_the_website %} has two possible versions: |
| 57 | + |
| 58 | +#### Free, Pro, or Team plans |
| 59 | + |
| 60 | +For Free, Pro, or Team plans on {% data variables.product.prodname_dotcom_the_website %}, use `free-pro-team@latest`. The short name is `fpt`. |
| 61 | + |
| 62 | +#### {% data variables.product.prodname_ghe_cloud %} |
| 63 | + |
| 64 | +For {% data variables.product.prodname_ghe_cloud %}, use `enterprise-cloud@latest`. The short name is `ghec`. |
| 65 | + |
| 66 | +### {% data variables.product.prodname_ghe_server %} |
| 67 | + |
| 68 | +Documentation for {% data variables.product.prodname_ghe_server %} has multiple versions and can be divided into two types: documentation for _supported releases_ (we support four at any one time), and documentation for _deprecated releases_ (we do not link to these on the Docs site but we support a "frozen" snapshot of these docs in perpetuity, so they can still be accessed if you know the URLs). See [`lib/enterprise-server-releases.js`](https://github.com/github/docs/blob/main/lib/enterprise-server-releases.js) for a list. |
| 69 | + |
| 70 | +The versions are named `enterprise-server@<release>`. The short name is `ghes`. In Liquid conditionals, we can specify ranges, like `ghes > 3.0`. For more information, see "[Versioning with Liquid conditional operators](#versioning-with-liquid-conditional-operators)." |
| 71 | + |
| 72 | +### {% data variables.product.prodname_ghe_managed %} |
| 73 | + |
| 74 | +Versioning for {% data variables.product.prodname_ghe_managed %} uses the `github-ae@latest` version. The short name is `ghae`. |
| 75 | + |
| 76 | +## Versioning in the YAML frontmatter |
| 77 | + |
| 78 | +You can use the `versions` property within the file's frontmatter to define which products an entire page applies to. For example, the following YAML frontmatter will version an article for {% data variables.product.prodname_ghe_server %} 2.20 and above and Free, Pro, or Team. |
| 79 | + |
| 80 | +```yaml |
| 81 | +title: About your personal dashboard |
| 82 | +versions: |
| 83 | + fpt: '*' |
| 84 | + ghes: '>=2.20' |
| 85 | +``` |
| 86 | + |
| 87 | +The following example will version an article for all supported versions of {% data variables.product.prodname_ghe_server %}: |
| 88 | + |
| 89 | +```yaml |
| 90 | +title: Downloading your license |
| 91 | +versions: |
| 92 | + ghes: '*' |
| 93 | +``` |
| 94 | + |
| 95 | +You can also version a page for a range of releases. The following example will version the page for {% data variables.product.prodname_dotcom_the_website %}, and {% data variables.product.prodname_ghe_server %} versions 2.22 and 3.0 only: |
| 96 | + |
| 97 | +```yaml |
| 98 | +versions: |
| 99 | + fpt: '*' |
| 100 | + ghec: '*' |
| 101 | + ghes: '>=2.22 <3.1' |
| 102 | +``` |
| 103 | + |
| 104 | +## Versioning with Liquid conditional operators |
| 105 | + |
| 106 | +We use the [Liquid template language](https://shopify.github.io/liquid/basics/introduction/) (specifically, [this Node.js port](https://github.com/harttle/liquidjs)) and a custom `{% raw %}{% ifversion ... %}{% endraw %}` tag to create versions of our documentation. |
| 107 | + |
| 108 | +If you define multiple products in the `versions` key within a page's YAML frontmatter, you can use the conditional operators `ifversion`/`else` (or `ifversion`/`elsif`/`else`) in the Markdown to control how the site renders content on the page for a particular product. For example, a feature may have more options on {% data variables.product.prodname_dotcom_the_website %} than on {% data variables.product.prodname_ghe_server %}, so you can version the content appropriately via the `versions` frontmatter, and use Liquid conditionals to describe the additional options for {% data variables.product.prodname_dotcom_the_website %}. |
| 109 | + |
| 110 | +{% note %} |
| 111 | + |
| 112 | +**Notes:** |
| 113 | + |
| 114 | +- Use `ifversion` for product-based versioning and [feature-based versioning](#feature-based-versioning). |
| 115 | +- Do not use `if` or `unless`. |
| 116 | +- Make sure to use `elsif` and not `else if`. Liquid does not recognize `else if` and will not render content inside an `else if` block. |
| 117 | + |
| 118 | +{% endnote %} |
| 119 | + |
| 120 | +### Comparison operators |
| 121 | + |
| 122 | +For versions that don't have numbered releases (like `fpt` and `ghae`), you have two options: |
| 123 | + |
| 124 | +- `{% raw %}{% ifversion ghae %}{% endraw %}` |
| 125 | +- `{% raw %}{% ifversion not ghae %}{% endraw %}` |
| 126 | + |
| 127 | +For versions that have numbered releases (currently only `ghes`), you can do the same for content that is either available in all of the releases or not available in any of the releases: |
| 128 | + |
| 129 | +- `{% raw %}{% ifversion ghes %}{% endraw %}` |
| 130 | +- `{% raw %}{% ifversion not ghes %}{% endraw %}` |
| 131 | + |
| 132 | +If you need to denote content that is only available (or not available) in certain releases, you can use the following operators: |
| 133 | + |
| 134 | +|Operator | Meaning| Example |
| 135 | +|--|--|--| |
| 136 | +|`=`| Equal to| `{% raw %}{% ifversion ghes = 3.0 %}{% endraw %}` |
| 137 | +|`>`| Newer than| `{% raw %}{% ifversion ghes > 3.0 %}{% endraw %}` |
| 138 | +|`<`| Older than| `{% raw %}{% ifversion ghes < 3.0 %}{% endraw %}` |
| 139 | +|`!=`| Not equal to| `{% raw %}{% ifversion ghes != 3.0 %}{% endraw %}` (don't use `not` in ranges) |
| 140 | + |
| 141 | +The Liquid operators `==`, `>=`, and `<=` are not supported in the {% data variables.product.prodname_docs %}. |
| 142 | + |
| 143 | +### Logical operators |
| 144 | + |
| 145 | +When all operands must be true for the condition to be true, use the operator `and`: |
| 146 | + |
| 147 | +``` |
| 148 | +{% raw %}{% ifversion ghes > 2.21 and ghes < 3.1 %}{% endraw %} |
| 149 | +``` |
| 150 | + |
| 151 | +When at least one operand must be true for the condition to be true, use the operator `or`: |
| 152 | + |
| 153 | +``` |
| 154 | +{% raw %}{% ifversion fpt or ghes > 2.21 %}{% endraw %} |
| 155 | +``` |
| 156 | + |
| 157 | +Do not use the operators `&&` or `||`. Liquid does not recognize them, and the content will not render in the intended versions. |
| 158 | + |
| 159 | +## About feature-based versioning |
| 160 | + |
| 161 | +When you document any new change or feature, use feature-based versioning. |
| 162 | + |
| 163 | +A small minority of features and changes will only ever apply to one product. The majority of features come to {% data variables.product.prodname_dotcom_the_website %} and eventually reach all products. In general, changes "flow" from {% data variables.product.prodname_dotcom_the_website %} (including {% data variables.product.prodname_ghe_cloud %}) [to {% data variables.product.prodname_ghe_server %}](/enterprise-server@latest/admin/overview/about-upgrades-to-new-releases), and then [to {% data variables.product.prodname_ghe_managed %}](/github-ae@latest/admin/overview/about-upgrades-to-new-releases). |
| 164 | + |
| 165 | +Feature-based versioning provides named "feature flags" that simplify the maintenance and versioning of documentation. You can use a single feature name (or "flag") to group and version prose throughout content. When a feature comes to additional products, you only need to make a change to the YAML versioning in the file within `data/features/`. |
| 166 | + |
| 167 | +### Managing features |
| 168 | + |
| 169 | +Each feature is managed through individual YAML files in `data/features/`. |
| 170 | + |
| 171 | +{% note %} |
| 172 | + |
| 173 | +**Note**: Do not delete `data/features/placeholder.yml` because it is used by tests. |
| 174 | + |
| 175 | +{% endnote %} |
| 176 | + |
| 177 | +To create a new feature, first create a new YAML file with the feature name you want to use in this directory. For a feature named `meow`, that would be `data/features/meow.yml`. |
| 178 | + |
| 179 | +Add a `versions` block to the YAML file with the short names of the versions the feature is available in. For example: |
| 180 | + |
| 181 | +```yaml |
| 182 | +versions: |
| 183 | + fpt: '*' |
| 184 | + ghec: '*' |
| 185 | + ghes: '>3.1' |
| 186 | + ghae: '*' |
| 187 | +``` |
| 188 | + |
| 189 | +The format and allowed values are the same as the frontmatter versions property. For more information, see "[Versions](https://github.com/github/docs/tree/main/content#versions)" in the `github/docs` repository README. |
| 190 | + |
| 191 | +### Liquid conditionals |
| 192 | + |
| 193 | +Now you can use `{% raw %}{% ifversion meow %} ... {% endif %}{% endraw %}` in content files! |
| 194 | + |
| 195 | +### Frontmatter |
| 196 | + |
| 197 | +You can also use the feature in frontmatter in content files: |
| 198 | + |
| 199 | +```yaml |
| 200 | +versions: |
| 201 | + fpt: '*' |
| 202 | + ghec: '*' |
| 203 | + ghes: '>3.1' |
| 204 | + feature: 'meow' |
| 205 | +``` |
| 206 | + |
| 207 | +You cannot use `feature:` to specify multiple concurrent versions, as this is not supported. Alternatively, you could create a new feature-based versioning file with the required versioning. |
| 208 | + |
| 209 | +### Schema enforcement |
| 210 | + |
| 211 | +The schema for validating the feature versioning lives in [`src/content-linter/lib/feature-versions-schema.js`](https://github.com/github/docs/blob/main/src/content-linter/lib/feature-versions-schema.js) and is exercised by [`tests/linting/lint-versioning.js`](https://github.com/github/docs/blob/main/tests/linting/lint-versioning.js). |
| 212 | + |
| 213 | +## Versioning for {% data variables.product.prodname_ghe_managed %} |
| 214 | + |
| 215 | +{% data variables.product.prodname_docs %} shows only the documentation for the latest version of {% data variables.product.prodname_ghe_managed %}. For more information, see "[About the displayed version of {% data variables.product.prodname_ghe_managed %} documentation](#about-the-displayed-version-of-github-ae-documentation)." |
| 216 | + |
| 217 | +You can version documentation to appear in the current {% data variables.product.prodname_ghe_managed %} documentation set in two ways: |
| 218 | + |
| 219 | +- In Liquid syntax, use `ghae` or <code>ghae > VERSION</code>. |
| 220 | + |
| 221 | + - For example, if you want documentation to be visible for {% data variables.product.prodname_ghe_managed %} 3.6 and later, use `ghae > 3.5`. |
| 222 | + - If you're confident that the change is available in the latest public release of {% data variables.product.prodname_ghe_managed %} and you want documentation to appear immediately on {% data variables.product.prodname_docs %}, you can always just use `ghae`. |
| 223 | +- In YAML front matter or [feature-based versioning files](#feature-based-versioning), use <code>ghae: '> VERSION'</code>. |
| 224 | + |
| 225 | + - For example, if you want documentation to be visible for {% data variables.product.prodname_ghe_managed %} 3.6 and later, use `ghae: '> 3.5'`. |
| 226 | + - If you're confident that the change is available in the latest public release of {% data variables.product.prodname_ghe_managed %} and you want documentation to appear immediately on {% data variables.product.prodname_docs %}, you can always use `ghae: '*'`. |
| 227 | + |
| 228 | +### About the displayed version of {% data variables.product.prodname_ghe_managed %} documentation |
| 229 | + |
| 230 | +We display one version of {% data variables.product.prodname_ghe_managed %} documentation on {% data variables.product.prodname_docs %}: the latest. We define "latest" in the site's source, within [`all-versions.js`](https://github.com/github/docs/blob/main/lib/all-versions.js#L58). In almost all cases, this value is a safe place to determine the latest public release of {% data variables.product.prodname_ghe_managed %}. |
| 231 | + |
| 232 | +"Latest" corresponds with the latest version of {% data variables.product.prodname_ghe_managed %} that we've deployed to the first customer using the product in production. Generally, {% data variables.product.company_short %} upgrades all production customers on {% data variables.product.prodname_ghe_managed %} to the latest version around the same time, so Product considers only showing the latest documentation an acceptable compromise. |
| 233 | + |
| 234 | +Product notifies Docs Content of new releases via release issues in `github/releases`. |
| 235 | + |
| 236 | +## Best practices |
| 237 | + |
| 238 | +Versioned content impacts the reader, but also impacts anyone who contributes to or reviews the content. Here are a few tips to improve the writing, reading, and reviewing experience for versioning syntax. None of these practices are mandatory and you will find edge and corner cases, but they're intended as useful heuristics to help you think through versioning. |
| 239 | + |
| 240 | +### Avoid unnecessary versioning |
| 241 | + |
| 242 | +For the reader, gaining a general understanding is more important than reading details that precisely reflect the differences between particular products or plans. In conceptual or procedural content, try to describe features or portions of the UI in a general way that doesn't require versioning syntax. In addition to being easier for us to maintain, this strengthens understanding for readers who refer to documentation for multiple products. |
| 243 | + |
| 244 | +- Do ask yourself, "can I write this content in a way that applies to all products without any versioning?" |
| 245 | +- Do try to avoid versioning screenshots if you can, given the effort required to create them. Minor differences between UI copy may not affect understanding. If product-specific text or UI elements exist, but the screenshot still provides helpful context, ask yourself whether versioning the screenshots would affect understanding to a meaningful degree. |
| 246 | +- Don't version prose if you can explain a concept or walk the reader through a procedure without versioning for specific products. |
| 247 | + |
| 248 | +### When modifying an existing content file, review existing versioning early and often |
| 249 | + |
| 250 | +Staying cognizant of existing versioning will help ensure that you write relevant versioning statements, and can help remind you to version new content accurately. |
| 251 | + |
| 252 | +- Do review the entire page's versioning in the front matter as soon as you begin editing. |
| 253 | +- Do review the versioning around content that you're editing. |
| 254 | +- Do review the rendered version of changes that you're making, and switch to each available version for the page as part of your self-review. |
| 255 | + |
| 256 | +### Avoid repetition as much as possible |
| 257 | + |
| 258 | +Use versioning syntax within a sentence or paragraph to differentiate prose for two different plans or products. A contributor can edit just one paragraph with versioning statements, instead of needing to consider larger blocks of versioned text and modify similar but differently versioned prose in two places. A reviewer can suggest a change once, instead of needing to leave the same suggestion in multiple places. But if the behavior differs dramatically or versioning within the sentence or paragraph becomes complicated or difficult for a contributor to parse, consider repeating yourself to make the prose easier to maintain. |
| 259 | + |
| 260 | +- Do use versioning syntax inline within paragraphs to avoid repeating sentences or entire paragraphs. |
| 261 | + |
| 262 | + > You can do {% raw %}{% ifversion fpt %}something{% elsif ghec %}something else{% endif %}{% endraw %}. |
| 263 | + |
| 264 | +- Do use your judgment: for prose that would be complicated to write or read without lots of versioning syntax within a sentence or paragraph, consider repeating the entire paragraph in a version block for each relevant product. |
| 265 | + |
| 266 | + > {% raw %}{% ifversion fpt %} |
| 267 | + > |
| 268 | + > If you use a Free, Pro, or Team plan, you can do something. Here's more information about the things you can do with a Free, Pro, or Team plan... |
| 269 | + > |
| 270 | + > {% elsif ghec %} |
| 271 | + > |
| 272 | + > If you use GitHub Enterprise Cloud, you can do something else. Here's more information about the things you can do with GitHub Enterprise Cloud... |
| 273 | + > |
| 274 | + > {% endif %}{% endraw %} |
| 275 | + |
| 276 | +### Be explicit, not implicit |
| 277 | + |
| 278 | +If you know exactly which products the content describes, version explicitly for those products. Syntax like `not`, and `else` in particular, can be imprecise. The end result of `not` and `else` depend on each article's front matter, so a contributor must do more investigation to understand prose with this versioning. This creates the potential for errors. The complexity of implicit versioning increases in reusables, where articles that reference the reusable may have different versioning, and thus different evaluations of `not` or `else`. We also occasionally introduce a new version to {% data variables.product.prodname_docs %} when {% data variables.product.company_short %} introduces a new product, which changes the end result of `not` and `else` when we add the new version to existing articles. |
| 279 | + |
| 280 | +- Do remember that {% data variables.product.company_short %} offers four products, and remember that {% data variables.product.prodname_docs %} can display documentation for eight total versions at any given time. |
| 281 | +- Do review an entire article's versioning in the front matter when you begin editing, as this can help you understand how `not` and `else` will behave in Liquid statements, or change when you enable new versions in the front matter. |
| 282 | + |
| 283 | +### Verify and communicate versioning as you work through content design and creation |
| 284 | + |
| 285 | +Sometimes a change isn't included in the release it was originally intended for. You can save time for reviewers and ensure more accurate content by confirming versioning throughout content design and creation, for both releases and improvements. |
| 286 | + |
| 287 | +- Do consider versioning in content design, and do double-check the versioning when you request stakeholder reviews for content creation. |
| 288 | +- Do make the review easier for other writers and stakeholders: point out differences between versions in your request for review, linking to specific rendered versions of the content if necessary. |
| 289 | +- Do trust, but verify. |
| 290 | + |
| 291 | +### Test, test, and test again |
| 292 | + |
| 293 | +Whether you're writing the content or reviewing the content, pay attention to the content design plan and affected products, and check the rendered content in a staging or development environment to ensure that the content describes each product accurately. |
0 commit comments