# IBC-Go Documentation

Welcome to the IBC-Go documentation! This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.

## Table of Contents

- [IBC-Go Documentation](#ibc-go-documentation)
    - [Table of Contents](#table-of-contents)
    - [Configuration](#configuration)
    - [Local Development and Deployment](#local-development-and-deployment)
        - [Installation](#installation)
        - [Local Development](#local-development)
        - [Build](#build)
        - [Serve](#serve)
    - [Updating the Documentation](#updating-the-documentation)
    - [Best practices](#best-practices)
        - [File and Directory Naming Conventions](#file-and-directory-naming-conventions)
        - [Code Blocks](#code-blocks)
        - [Links](#links)
            - [Multi-Documentation Linking](#multi-documentation-linking)
            - [Static Assets](#static-assets)
            - [Raw Assets](#raw-assets)
        - [Technical writing course](#technical-writing-course)
    - [Versioning](#versioning)
        - [Terminology](#terminology)
        - [Overview](#overview)
        - [Tagging a new version](#tagging-a-new-version)
        - [Adding a new version](#adding-a-new-version)
        - [Updating an existing version](#updating-an-existing-version)
        - [Deleting a version](#deleting-a-version)

## Configuration

Docusaurus configuration file is located at `./docusaurus.config.js`. This file contains the configuration for the sidebar, navbar, footer, and other settings. Sidebars are created in `./sidebars.js`.

## Local Development and Deployment

### Installation

```bash
npm install
```

### Local Development

```bash
npm start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. However, in the local development environment, some plugins like `@docusaurus/plugin-client-redirects`, will not work at all. This is why the landing page is an error page in the local development environment, and why you have to click on the correct docs version to see the documentation. This is not the case in the production environment. To view the production environment, you must [build](#build) and [serve](#serve) the website locally.

### Build

```bash
npm run build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Serve

```bash
npm run serve
```

This command starts a local production server and opens up a browser window.

### Lint

From the root of the repo:
```bash
make lint-docs
```

This command will run `markdownlint-cli2` (if you don't have it installed, see the [install docs](https://github.com/DavidAnson/markdownlint-cli2#install) and lint all markdown files in `./docs/docs` (i.e. it will not lint versioned docs).

### Check links

From the root of the repo:
```bash
make check-docs-link
```

This command will run `lychee` (if you don't have it, see the [install docs](https://lychee.cli.rs/installation/)) and check all links in `./docs/docs` (i.e. it will not check versioned docs).

Since a lot of our links are to github, this command easily gets rate limited, so it has been set up with a long retry sequence for links. You may need to run it multiple times to check all links.
The results (except rate limit responses) are cached for 1 week, so once you have run it, it will not keep checking the same links twice (this is primarly to help with rate limiting).

## Updating the Documentation

The documentation website is autogenerated from the markdown files found in [docs](./docs) directory. Each directory in `./docs/` represents a category to be displayed in the sidebar. If you create a new directory, you must create a `_category_.json` file in that directory with the following contents:

```json
{
  "label": "Sidebar Label",
  "position": 1, // position of the category in the sidebar
  "link": null
}
```

The `position` key above is used to order the categories in the sidebar. This position key pertains to the order of this category in the parent directory.

If you create a new markdown file within a category (`.docs/` directory is itself a category), you must add the following frontmatter to the top of the markdown file:

```yaml
---
title: Title of the file # title of the file in the sidebar
sidebar_label: Sidebar Label # title of the file in the sidebar
sidebar_position: 1 # position of the file in the sidebar
slug: /migrations/v5-to-v6 # the url of the file
---
```

The `link` key in `_category_.json` determines if the category has an introductory page that comes before any content pages. If `link` is `null`, then the category does not have an introductory page. If there is a markdown file you wish to link, you should do

```json
{
  "label": "Sidebar Label",
  "position": 1, // position of the category in the sidebar
  "link": { "type": "doc", "id": "intro" }
}
```

The `id` key can be defined in the frontmatter of the markdown file. Or, you can use the id tag as an extension to the url of the current page. For example, the following frontmatter on a markdown file in the same directory as the `_category_.json` file shown above will link to the markdown file:

```yaml
---
title: Title
sidebar_label: Sidebar Label
sidebar_position: 0 # should be zero for intro pages
slug: /ibc/upgrades/intro
---
```

## Best practices

- Check the spelling and grammar, even if you have to copy and paste from an external source.
- Use simple sentences. Easy-to-read sentences mean the reader can quickly use the guidance you share.
- Try to express your thoughts in a concise and clean way.
- Either Leave a space or use a `-` between the acronyms ADR and ICS and the corresponding number (e.g. ADR 008 or ADR-008, and ICS 27 or ICS-27).
- Don't overuse `code` format when writing in plain English.
- Follow Google developer documentation [style guide](https://developers.google.com/style).
- Check the meaning of words in Microsoft's [A-Z word list and term collections](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/accessibility-terms) (use the search input!).
- We recommend using RFC keywords in user documentation (lowercase). The RFC keywords are: "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL. They are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
- Lint the markdown files for documentation with [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli). Run `make docs-lint` (you will need to have `markdownlint-cli` installed, so please follow the [installation instructions](https://github.com/igorshubovych/markdownlint-cli#installation)).

### File and Directory Naming Conventions

Inside `/docs/docs/`:

- All files should be named in `kebab-case`.
- All files should have a two digit prefix, indicating the order in which they should be read and displayed in their respective categories. For example, `01-overview.md` should be read before `02-integration.md`. If this order changes, the prefix should be updated. Note that the ordering is enforced by the frontmatter and not the file name.
- **All files that end in `.template.md` will be ignored by the build process.**
- The prefix `00-` is reserved for root links of categories (if a category has a root link this should be defined in `_category_.json`). For example, see [`docs/01-ibc/05-upgrades/00-intro.md`](./docs/01-ibc/05-upgrades/00-intro.md) and [`docs/01-ibc/05-upgrades/_category_.json`](./docs/01-ibc/05-upgrades/_category_.json).
- All category directories should be named in `kebab-case`.
- All category directories must have a `_category_.json` file.
- All category directories should have a two digit prefix (except for the root `./docs` category), indicating the order in which they should be read and displayed in their respective categories. For example, contents of `./docs/01-ibc/03-apps/` should be read before `./docs/01-ibc/07-relayer.md`. If this order changes, the prefix should be updated. Note that the ordering is enforced by the frontmatter of the markdown files and `_category_.json` files, not the file name.
- The images for each documentation should be kept in the same directory as the markdown file that uses them. This will likely require creating a new directory for each new category. The goal of this is to make versioning easier, discourage repeated use of the image, and make it easier to find images.

### Code Blocks

Code blocks in docusaurus are super-powered, read more about them [here](https://docusaurus.io/docs/markdown-features/code-blocks). Three most important features for us are:

1. We can add a `title` to the code block, which will be displayed above the code block. (This should be used to display the file path of the code block.)
2. We can add a `reference` tag to the code block, which will reference github to create the code block. **You should always use hyperlinks in reference codeblocks.** Here is what a typical code block should look like:

````ignore
```go reference title="modules/apps/transfer/keeper/keeper.go"
https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/transfer/keeper/keeper.go#L19-L31
```
````

3. We can highlight lines in the code block by adding `// highlight-next-line` before the line we want to highlight. For example, we should use this to highlight diffs. Here is an example:

````ignore
```go
import (
  ...
  // highlight-next-line
+ ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint"
  ...
)
```
````

### Links

In docusaurus, there are three ways to link to other pages:

1. File Paths (relative or absolute)
2. URLs (relative or absolute)
3. Hyperlinks

In this section, we will discuss when to use each.

#### Multi-Documentation Linking

Technically, there are four docs being maintained in this repo:

1. Found in `docs/docs/` (this is the one displayed on the website in the "Documentation" tab)
2. Found in `docs/architecture/` (this is the one displayed on the website in the "Architecture Decision Records" tab)
3. Found in `docs/events/` (depreciated, this is not displayed on the website, but is hosted under `/events/` url)
4. Found in `docs/params/` (depreciated, this is not displayed on the website, but is hosted under `/params/` url)

When referencing a markdown file, you should use relative file paths if they are in the same docs directory from above. For example, if you are in `docs/docs/01-ibc` and want to link to `docs/docs/02-apps/01-transfer/01-overview.md`, you should use the relative link `../02-apps/01-transfer/01-overview.md`.

If the file you are referencing is in a different docs directory, you should use an absolute URL. For example, if you are in `docs/docs/01-ibc` and want to link to `docs/architecture/adr-001-coin-source-tracing.md`, you should use the absolute URL (not absolute file path), in this case `/architecture/adr-001-coin-source-tracing`. You can find the absolute URL by looking at the slug in the frontmatter of the markdown file you want to link to. If the frontmatter slug is not set (such as in `docs/architecture/adr-001-coin-source-tracing.md`), you should use the url that docusaurus generates for it. You can find this by looking at the url of the page in the browser.

Note that when referencing any file outside of the parent `docs/` directory, you should always use a hyperlink.

#### Static Assets

Static assets are the non-code files that are directly copied to the build output. They include **images**, stylesheets, favicons, fonts, etc.

By default, you are suggested to put these assets in the `static/` directory. Every file you put into that directory will be copied into the root of the generated build folder with the directory hierarchy preserved. E.g. if you add a file named `sun.jpg` to the static folder, it will be copied to `build/sun.jpg`.

These assets should be referenced using absolute URLs. For example, if you have an image in `static/img/cosmos-logo-bw.png`, you should reference it using `/img/cosmos-logo-bw.png`.

#### Raw Assets

If you want to link a raw file, you should link to it using `@site` + its base path. For example, if you want to link to the raw markdown file `/architecture/adr.template.md`, you should use the absolute URL `@site/architecture/adr.template.md`.

### Technical writing course

Google provides a free [course](https://developers.google.com/tech-writing/overview) for technical writing.

## Versioning

Versioning only applies to documentation and not the ADRs found in the `./architecture/` directory.

### Terminology

- Current version: The version placed in the `.docs/` folder. This version is the one that is displayed on the website by default, referred to as next.
- Latest version: This version is defined in `./docusaurus.config.js` file under the `lastVersion` key.

### Overview

A typical versioned doc site looks like below:

```ignore
docs/
├── sidebars.json          # sidebar for the current docs version
├── docs/                  # docs directory for the current docs version
│   ├── 01-foo/
│   │   └── 01-bar.md      # https://mysite.com/docs/next/01-foo/01-bar
│   └── 00-intro.md        # https://mysite.com/docs/next/00-intro
├── versions.json          # file to indicate what versions are available
├── versioned_docs/
│   ├── version-v1.1.0/
│   │   ├── 01-foo/
│   │   │   └── 01-bar.md  # https://mysite.com/docs/01-foo/01-bar
│   │   └── 00-intro.md
│   └── version-v1.0.0/
│       ├── 01-foo/
│       │   └── 01-bar.md  # https://mysite.com/docs/v1.0.0/01-foo/01-bar
│       └── 00-intro.md
├── versioned_sidebars/
│   ├── version-v1.1.0-sidebars.json
│   └── version-v1.0.0-sidebars.json
├── docusaurus.config.js
└── package.json
```

The `./versions.json` file is a list of version names, ordered from newest to oldest.

### Tagging a new version

It is possible to tag the current version of the docs as a new version. This will create the appropriate files in `./versioned_docs/` and `./versioned_sidebars/` directories, and modify the `./versions.json` file. To do this, run the following command:

```bash
npm run docusaurus docs:version v7.1.0
```

### Adding a new version

To add a new version:

1. Create a new directory in `./versioned_docs/` called `version-vX.Y.Z` where `X.Y.Z` is the version number. This directory should contain the markdown files for the new version.
2. Create a new file in `./versioned_sidebars/` called `version-vX.Y.Z-sidebars.json`. This file should contain the sidebar for the new version.
3. Add the version to the `./versions.json` file. The list should be ordered from newest to oldest.
4. If needed, make any configuration changes in `./docusaurus.config.js`. For example, updating the `lastVersion` key in `./docusaurus.config.js` to the latest version.

### Updating an existing version

You can update multiple docs versions at the same time because each directory in `./versioned_docs/` represents specific routes when published. Make changes by editing the markdown files in the appropriate version directory.

### Deleting a version

When a version is no longer supported, you can delete it by removing it from `versions.json` and deleting the corresponding files in `./versioned_docs/` and `./versioned_sidebars/`.
