diff --git a/README.md b/README.md index 81daeac34658294d4977fd0186b21bc9b9d3ad85..06aba995c84fa9c685b583739b1ed699ae56774c 100644 --- a/README.md +++ b/README.md @@ -1,137 +1,369 @@ -# inject-docs +# INJECT Exercise Platform – Documentation -This repository contains the documentation for the inject exercise platform. +This repository contains the documentation for the Inject Exercise Platform (IXP). ## Table of Contents - [Dependencies](#dependencies) -- [Usage (Local Server)](#usage-local-server) -- [Build GitLab Pages](#build-gitlab-pages) -- [Files Pulled from Other Repositories](#files-pulled-from-other-repositories) -- [Pipeline and Deployment](#pipeline-and-deployment) +- [Scripts](#scripts) +- [Deploying a Local Server](#deploying-a-local-server) +- [Rules and Conventions](#rules-and-conventions) +- [Updating the Documentation](#updating-the-documentation) +- [GitLab Pages](#gitlab-pages) +- [Deploying a New Version of Documentation](#deploying-a-new-version-of-documentation) ## Dependencies - [Python](https://www.python.org/downloads/) version 3.10 - [Poetry](https://python-poetry.org/docs/) version 1.8.0 and higher -## Usage (local server) +## Scripts + +For the convenient usage of documentation and its versioning the following scripts are present: + +### 1. update-files.sh + +This script is responsible for downloading the correct versions of files that are drown from another repositories: + +- (example) `file name` - source repository path -> documentation path +- `README.md` - _/backend/definitions/_ -> _/docs/tech/architecture/definitions/_ +- `CHANGELOG.md` - _/backend/definitions/_ -> _/docs/tech/architecture/definitions/_ +- `openapi.yml` - _/backend/_ -> _/docs/tech/api/_ +- `definition.zip` - _/showcase-definition/assets/_ -> _/files-from-repos/showcase-definition.zip_ +- `definition.zip` - _/introductory-definition/assets/_ -> _/files-from-repos/intro-definition.zip_ + +The script takes argument `-v` (or verbose `--version`) followed by a version (in format: `vX.0.0`) for which we want the files. +If no argument is provided it pulls the newest files from every repository. + +#### Usage Examples + +- We created the new branch for the new release from the main. +- Backend and Definitions repositories are ready and appropriate commits are tagged (or the latest commits contain the wanted content). +- We run the following script if Backend and Definition repositories contain the wanted tag (e.g., v4.0.0): + ```bash + poetry run ./update-files.sh -v v4.0.0 + ``` +- If the Backend and Definition repositories do not contain a tag, but we know that latest content is wanted, we simply run: + ```bash + poetry run ./update-files.sh + ``` + This will use the newest commits/content from all repositories. + +### 2. update-links.sh + +This script serves for correcting all links pointing to version specific files (mostly definitions zip archives). +It is a simple sed (stream editor) script for changing the urls/paths. + +It takes `-n` (or `--name`) argument followed by a name of the branch (of the given release). +For example: + +- We created new branch from the main (e.g., `dux`). +- We want every link to point on the file located on this branch. +- We use: + ```bash + poetry run ./update-links.sh -n dux + ``` +- We should see modified files by the script via diff. + +## Deploying a Local Server To set up and run a local server for the documentation: 1. Install dependencies: + ```bash poetry install ``` -2. Run the utilities script to set up the necessary environment: +2. _(If needed)_ Run the utilities scripts to update (or downgrade) files pulled from other repositories: + ```bash - poetry run ./utilities.sh + # (substitute 'X' for actual version number, e.g. v3.0.0) + poetry run ./update-files.sh -v vX.0.0 + + # (substitute 'releaseName' for actual release name, e.g. dux) + poetry run ./update-links.sh -n releaseName ``` 3. Start the local MkDocs server: + ```bash poetry run mkdocs serve ``` -4. Access the documentation at [http://localhost:8000](http://localhost:8000). If port 8000 is taken by another service, you can change the default port using the `-a` or `--dev-addr` option: +4. Access the documentation at [http://localhost:8000](http://localhost:8000). + If port 8000 is taken by another service, you can change the default port using the `-a` or `--dev-addr` option: ```bash poetry run mkdocs serve -a <IP:PORT> ``` -## Build GitLab Pages +## Rules and Conventions + +In order to prevent potential problems, the following rules and conventions should be complied with. + +### Conventional Commits + +To keep the commit history of documentation repository clean and readable, the following prefixes of the names of commits should be used: + +- **docs: title** - general documentation changes/updates (usually less technical texts), structure change +- **feat: title** - describing behavior of new feature or technology +- **fix: title** - correction of information +- **ops: title** - changes in devops instructions/requirements +- **style: title** - formatting +- **release: title** - work needed to be done when creating new release (updating .gitlab-ci.yml, updating dropdown menus) +- **internal: title** - updates of the documentation infrastructure (e.g., CI/.gitlab-yml, README.md, scripts) + +### Feature Branches and Merge Requests + +When making changes to the documentation, feature branches with merge requests (MRs) should be used to provide well documented history of changes with possible comments and discussions in the MRs. + +Merge requests must have always assigned a reviewer. +In most cases it would be Jan V. and Martin H., but others who can provide feedback for the given MR can be assigned too. + +Before merging the MR, above the **merge** button there is option to **Edit commit message**. Click on it and edit the first line in the **Squash commit message** section to contain conventional commit and _concise description_ (e.g., feat: add description for using the editor). + +A **good merge** request should: + +- **contain related changes** (single purpose) +- **have a clear description** +- **be complete but minimal** (avoid adding unnecessary refactoring, unrelated fixes, or multiple features – this should be split into multiple MRs!) + +## Updating the Documentation + +The following situations can happen depending on where are the updates/changes wanted. + +### 1. Apply updates only to release branch + +This is straight forward: + +1. Create feature branch from the given release branch. + ```bash + git switch <release-branch-name> + git pull + git switch -c <feature-branch-name> + ``` +2. Apply changes (commits) to the given feature branch. +3. Create MR _(feature-branch -> release-branch)_. + +### 2. Apply updates only to main branch + +This is straight forward: + +1. Create feature branch from the main branch. + ```bash + git switch main + git pull + git switch -c <feature-branch-name> + ``` +2. Apply changes (commits) to the given feature branch. +3. Create MR _(feature-branch -> main)_. + +### 3. Apply updates to both main and release branch. + +1. Firstly, use the **[1. Apply updates only to release branch](#1-apply-updates-only-to-release-branch)** process. +2. Wait until the changes are approved and merged. + Then pick either manual or automatic guide (either step **3a** or **3b**) to propagate changes to main branch. + +#### 3a – Automatic copy of the updates. + +1. Open the commit history of the release branch (where you merged the MR). +2. On the top you should see the latest commit. + It should be the one created by your MR. + Open the pipeline of the commit (gear wheel icon left to the commit hash).You should have option to run the `copy_to_main` stage – run it. +3. This action will create new branch from main with name `COPY-<commit-hash>` and tries to apply the wanted changes. +4. Two situations can happen: + + - **Success** – If the appliance of changes can be done automatically, the merge request (and the created branch) will contain the applied commit and MR will inform you in its description that commit was applied successfully. + Ping someone for approve and merge it. The branch will delete itself. + + - **Fail** – If the appliance cannot be done automatically (due to merge conflicts), the merge request will contain no commits and it will contain message that appliance of the commit cannot be done. You will need to: + 1. Update your local repository (since new branch was created on the remote). + ``` + git fetch + ``` + 2. Switch to the created branch (the name can be seen in the MR – `COPY-<commit-hash>`) + ``` + git switch COPY-<commit-hash> + ``` + 3. Try to apply the commit yourself + ``` + git cherry-pick <commit-hash> + ``` + 4. This should end with error: + ``` + CONFLICT: Merge conflict + error: could not apply <commit-hash> + ``` + You will have the files with merge conflicts edited with sections looking like this: + ``` + <<<<<<< HEAD + Changes introduced by mainline + ====== + Changes added by the cherry-picked commit + >>>>>>> <commit-hash> + ``` + Edit them manually to contain the correct changes. + 5. Add your conflict resolution and push it. + ``` + git add . + git commit -m "fix: resolve merge conflict" + git push + ``` + 6. Now, the merge request should contain the wanted changes. + Ping someone for approve and merge it. The branch will delete itself. + +#### 3b – Manual copy of the updates. + +1. Create temporary branch from the main. + ```bash + git switch main + git pull + git switch -c <temporary-branch-name> + ``` +2. Apply the commits from the release branch to this temporary branch (via git cherry-picking). + This can be done via enumeration of the commit hashes (this command will apply commits with the given hashes to the current, release, branch): + + ```bash + git cherry-pick <commit1-hash> <commit2-hash> <commit3-hash> + ``` + + Or alternatively (if the commits are consecutive): + + ```bash + git cherry-pick <oldest-commit-hash>^..<newest-commit-hash> + ``` + + By one of this command the changes are added to the current branch (temporary-branch-name). + It is possible that conflicts occur during this step. + In such case, they will need to be locally resolved. + +3. After successful addition of the wanted commits from main to the feature branch push the changes to remote repository: + + ``` + git push --set-upstream origin <temporary-branch-name> + ``` + +4. Create a MR _temporary-branch-name -> main_. + This MR should have in title: _[COPY-commit_name]_ to show that these changes were already approved on a different branch. + For this reason, you can request anyone for the approve. + +## GitLab Pages The documentation is built and deployed to GitLab Pages. The hosted documentation is available at: [https://inject.pages.fi.muni.cz/inject-docs](https://inject.pages.fi.muni.cz/inject-docs) -## Files Pulled from Other Repositories +### Pipeline -The `utilities.sh` script pulls several essential files from other repositories to ensure centralized updates. These files include: +Deployment of the documentation to GitLab Pages is managed through a CI/CD pipeline defined in the `.gitlab-ci.yml` file. +GitLab CI/CD will automatically run the pipeline, which includes the following stages. +You can also manually trigger the pipeline if needed: -- `backend/definitions/README.md`: Documentation on the definition files structure. -- `backend/openapi.yml`: OpenAPI documentation for the API. -- `frontend/docker/nginx-deployment/README.md`: Documentation on the Nginx deployment setup. -- `showcase-definition/assets/definition.zip`: A showcase definition file. +- Setup: Install necessary dependencies. +- Build Documentation: Use MkDocs to build the site. +- Deploy Pages (manual stage): Deploy the built documentation to GitLab Pages. -Additionally, the GitLab pipeline pulls and zips the following files: +The deployment of the documentation is available via running the manual stage - Deploy Pages - to GitLab Pages upon successful completion of all previous stages. +Most importantly the _Build Documentation_ must be successful. -- `frontend/docker/nginx-deployment`: This directory is zipped (excluding `compose-from-monorepo.yml`) and saved as `deployment-files.zip` in the `files-from-repos` directory. +### Parallel Pages and Branches -## Pipeline and Deployment +The documentation supports the deployment of multiple pages for different versions. +This is done via [GitLab Parallel Deployments](https://about.gitlab.com/blog/2024/09/23/gitlab-pages-features-review-apps-and-multiple-website-deployment/). -Deployment of the documentation to GitLab Pages is managed through a CI/CD pipeline defined in the .gitlab-ci.yml file. GitLab CI/CD will automatically run the pipeline, which includes the following stages. You can also manually trigger the pipeline if needed: +The way these parallel pages are to be deployed is as follows. -* Setup: Install necessary dependencies and run the utilities.sh script to set up directories and copy files. -* Commit Zip: Optionally commit the zipped deployment files and showcase definition to the repository. -* Build Documentation: Use MkDocs to build the site. -* Deploy Pages: Deploy the built documentation to GitLab Pages. +1. The main branch of the project is always the newest, not-yet-published page. + Here we can slowly keep adding more and more content. +2. The main branch should never be deployed. +3. For that, we are going to create a new branch named after the release name, and this new branch is what we are going to release. + **The main page is always the newest published release branch.** -**Important**: Certain parts of the pipeline, including the commit and deploy stages, are only run on the `main` branch. This ensures that only finalized and approved changes are deployed to the live documentation site. +The main difference between the main page of docs (the newest release) and parallel (older releases) is that the parallel has a postfix in the URL and thus, it is not the primary site. +When setting up the version, you need to make a few adjustments to the gitlab-ci.yml. -The pipeline will automatically build and deploy the documentation to GitLab Pages upon successful completion of all stages. +## Deploying a New Version of Documentation -## Versioning +To create a new page for the documentation of the newest release you need to follow these steps: -The documentation supports the deployment of multiple pages for different versions. This is done via parallel deployments. -The way these parallel pages are to be deployed is as follows. -The main branch of the project is always the newest, not-yet-published page. Here we can slowly keep adding more and more content. -This branch should never be deployed. Only upon new release can we deploy this new page. -For that, we are going to create a new branch named after the release name, and this new branch is what we are going to release. -**The main page is always the newest published branch.** +### 1. Detach from main -The main difference between the main page of docs and paraller is that paraller has a postfix in the URL and is thus not the primary site. -When setting up the version, you need to make a few adjustments to the gitlab-ci.yml. +Important note!\ +When _detaching_ from _main_, the content of the release (the state of the main branch) should be _revised_ and _checked_. +If mistakes and discrepancies are found after detaching, it is needed to fix them _both in the detached release branch and main_ (this can be done by following [this guide](#3-apply-update-to-both-main-and-release-branch)). +For this reason it is advised to detach from the main branch _as late as possible_. -### 1. Parallel page setup from the main page +Create a branch whose content will be used when publishing a new page of the new release. -In the file `gitlab-ci.yml` the following lines need to be added under the `pages` stage when creating a new parallel page from the main page: +```bash +git switch -c <new-release-branch-name> ``` + +### 2. New main page creation + +Since, as mentioned in the [Parallel Pages and Branches](#parallel-pages-and-branches) section, the newest release is the main page -> we need to modify the `.gitlab-ci.yml` the following way: + +```yml +pages: +[...] + # add following: pages: - path_prefix: "$CI_PIPELINE_ID" + path_prefix: "" expire_in: never +[...] ``` -This means that this new page will have a postfix in the link that is the same as the name of the release. -This means that a new page will be generated under the URL: https://inject.pages.fi.muni.cz/{release-name} +This means that this new page will not have any prefix (respectively postfix in the context of the URL). -You also need to specify the expiration time of this deployment since, by default, they are set to expire in a set amount of time. +Push this change to the new release branch. -### 2. Setup shared for all versions +### 3. Update older releases -Another part that needs to be adjusted for each page upon new release is the menu for switching versions. -It's located in `overrides/partials/header.html`. Here you can find the lines: -``` - <!-- Dropdown Menu for Page Versions --> - <div class="md-header__dropdown"> - <select onchange="window.location.href=this.value;"> - <option value="#">Citadel</option> - <option value="/bastion/">Bastion</option> - <option value="/aegis/">Aegis</option> - </select> - </div> -``` +Another part that needs to be adjusted for each page upon new release is the menu for switching versions. +It's located in `overrides/partials/header.html` where you can find the following section. + +On the newest release it could look like this: -On a parallel page, it looks like: +```html +<!-- Dropdown Menu for Page Versions --> +<div class="md-header__dropdown"> + <select onchange="window.location.href=this.value;"> + <option value="#">Currently-newest-released-release</option> + <option value="/bastion/">Bastion</option> + <option value="/aegis/">Aegis</option> + </select> +</div> ``` - <!-- Dropdown Menu for Page Versions --> - <div class="md-header__dropdown"> - <select onchange="window.location.href=this.value;"> - <option value="#">Bastion</option> - <option value="/">Citadel</option> - <option value="/aegis/">Aegis</option> - </select> - </div> + +On a parallel page (for example _bastion_): + +```html +<!-- Dropdown Menu for Page Versions --> +<div class="md-header__dropdown"> + <select onchange="window.location.href=this.value;"> + <option value="#">Bastion</option> + <option value="/">Currently-newest-released-release</option> + <option value="/aegis/">Aegis</option> + </select> +</div> ``` -When adding a new page, you will need to add a new option to this list. A few things to mention are: -* value="#" points to the page where the user is currently -* value="/" points to the main page from the parallel page -* value="/{branch-name}/" points to a parallel page +When adding a new page, you will need to add a new option to this list. +The explanation of the tags `#`, `/`, and `/{name}`: + +- value="#" points to the page where the user is currently (meaning each dropdown menu of each older release branches should have there its own name) +- value="/" points to the main page from the parallel page (this points to the newest release) +- value="/{branch-name}/" points to an older parallel page release -### 3. Finishing touches +### 4. Hand brake removal -To avoid accidental publishing, the tag `only:` should always be set to the name of the branch where it is located. -Also, the main branch should never have a valid gitlab-ci.yml that can publish pages. +To avoid accidental publishing, the tag `only:` should always be set to the name of the branch where it is located. +Also, the main branch should never have a valid gitlab-ci.yml that can publish pages. For that reason the tag `only:` on the main branch of the project should be set to a different name other than the main branch. -On the main branch, the tag is set to `change-me`, you need to change all of the occurrences of this tag to the current branch name. \ No newline at end of file +On the main branch, the tag is set to `change-me`, you need to change all of the occurrences of this tag to the current branch name. + +### 5. Publishing + +When all of the previous steps are done, you can run the manual stage `pages`, which deploys the newest changes. +It is needed to redeploy the older releases as well (due to change in the dropdown menu). +This can be done in the GitLab section `Build` -> `Pipelines` or by `Code` -> `Commits` -> and clicking on the green tick of the latest commit that should be deployed.