APIHUB Frontend Development Guide - Netcracker/qubership-apihub-ui GitHub Wiki

DRAFT

Main Scenarios

Initial setup

Ask your team lead to provide access to appropriate repositories on GitHub.

Set up git to use this Git config.

We use Node.js version 20, make sure you have appropriate version installed.

Setup GitHub NPM registry.

Learn how to run APIHUB locally

Learn basic concepts and functionality of APIHUB

  • create private workspace
  • publish package via portal (e.g. publish APIHUB Backend API)
  • publish several versions of package
  • compare packages
  • see BWC analysis for the packages

Build components locally (at least APIHUB UI)

Learn how to run APIHUB UI from local sources using proxy development mode.

Learn how to run Playwright tests on APIHUB Portal (<TBD>).

Learn APIHUB Frontend branching and versioning strategy.

Familiarize yourself with the APIHUB Ticketing Guide

Working on a feature/bugfix

Create a branch from develop, named according to branching conventions. If there are changes required in several dependent components- create branch in each component, according to process described in Cross-cutting feature development

Work on implementation of required functionality/bugfix.

Run unit/screenshot/integration test as described in Testing.

Create a Pull Request to develop, assign to reviewers.

Make sure, you are following git messages conventions for commits and PRs

Iterate on the code to fix issues raised during review.

Branching Strategy

We use a classic Gitflow branching model with minor variations.

Here are the differences:

  • only one release branch named release (we do not have several releases happening simultaneously)
  • only one hotfix branch named hotfix (again, there are no use cases for several hotfixes being prepared simultaneously)
  • topic branches could be named either feature/* or bugfix/*

Regular development and bugfix mainly happens in develop and topic branches (i.e. feature/* or bugfix/*). Make sure you understand flows around those.

Versioning Strategy

We use Semantic Versioning.

Version core changes

Package version in the main branch is set to release version (e.g. 2.10.0) during Release version assignment and Release finish steps of the release process. Package version in the develop branch is set during Release finish step of the release process.

You do not need to change package version manually at any other time.

Pre-release suffixes

Versions for packages published from development branches will have both version core part (e.g. 2.10.1) and pre-release suffix. Pre-release suffix is added automatically by CI process during build.

You do not need to add or modify pre-release suffix in development branches manually.

NPM dist-tag assignment

When package version is published from some branch, it will have corresponding NPM dist-tag assigned automatically. These should be used to specify dependencies between packages in development branches. See details in Cross-cutting feature development

Branch Version Example NPM Dist-tag
develop 2.10.1-dev.20250317141223 dev
feature/my-feature 2.10.1-feature-my-feature.20250317141223 feature-my-feature
release 2.10.1-next.20250317141223 next
hotfix 2.10.1-hotfix.20250317141223 hotfix

Release Process

We are using Gitflow branching model, make sure you have an understanding of corresponding release process.

APIHUB frontend consists of a number of dependent components. It is convenient to use dependencies diagram to determine order in which components should be released.

Instruction below assumes the use of npm-gitflow scripts release-start and release-finish during release.

Release is initiated from the develop branch.

Release Start

Compose list of components for release

As a first step of release you need to compose a list of components that should be released. Start with last components in dependency graph (ui and build-task-consumer), see if they have any changes in develop branch since the last release. If they have dependencies with dist-tag dev in develop branch- it means that corresponding components should also be released. Continue this process backwards over dependency graph.

Initiate release

Go over components that should be released one by one in the order defined by dependency graph, starting from base components. For each component

  1. (for the components after the base ones) Make sure CI has completed the build from the release branch you initiated previously.
  2. Initiate release for the component using npx release-start. When using npm-gitflow, dependencies to dev dist-tag version will be automatically replaced with dependencies to next dist-tag version.

Pro tip: if you have a large number of components to release- start with chain leading to the ui component. While api-doc-viewer and apispec-view are building- you will be able to release components in a chain leading to build-task-consumer in parallel.

After completing this phase, you should have a release branch for each component you are releasing, corresponding package versions published with next dist-tag and eventually Docker images with tag next for the ui and build-task-consumer.

Release version assignment

Review the changes since the last release. Decide what version part should be incremented according to Semantic Versioning. Set corresponding version for the component in a release branch. If necessary, you can update version in a release branch while release is in progress (this is mainly to be able to correct mistakes, not to abuse it adding last-minute features while release is in progress).

Use npm to set version for component which do not use lerna

npm version <version> --allow-same-version --no-git-tag-version

Use lerna to set version for components which use lerna (these are api-doc-viewer, apispec-view and ui)

npx lerna version <version> --force-publish --no-git-tag-version --no-private --no-push --yes

Pro tip: review the changes since the last release before initiating release for the component and you can assign version during release start npx release-start <version>

Applying fixes during release

Bug fixes for bugs found during next version testing should be applied to the release branch.

We do not have cascade rebuild for the components currently, so, keep in mind that if change was applied to one of base components, you should manually initiate rebuild of release branch for all dependent components one by one, according to dependency graph. Make sure to wait for the base component to complete build before initiating rebuild for dependent components.

Release finish

You should already have a list of components which are part of release from Release start step. If for some reason you don't, you can collect all repositories with existing release branch.

Release finish releases state of the release branch.

Go over components that should be released one by one in the order defined by dependency graph, starting from base components. For each component:

  1. Change dependencies version in package.json from next to the specific release version for the corresponding component. Keep a list of components which are part of current release and their release versions. Make sure you have waited for the completion of release CI jobs for the base components before proceeding to dependent component.
  2. Execute npm install to update lock file with corresponding versions.
  3. Build the component npm run build to make sure everything is OK.
  4. Finish the release npx release-finish. The script will merge changes from release branch to main, create git tag with corresponding version, merge changes from main branch to develop and increment patch component of the version to prepare for further development.

Release notes

We use GitHub releases functionality to capture release notes.

After release process is finished, make sure to create GitHub releases for all released component.

Go over released components one by one starting from base components and create a GitHub releases.

Typical sections:

  • Breaking changes
  • Features and improvements
  • Bug fixes
  • Dependency changes

You can use this sample release as a reference.

Cancel release

We assume only one release happens at a time. You can not initiate a new release if one is already in progress.

release branch exists only for the duration of release and serves as an indicator that a release is in progress.

If you need to cancel current release for some reason- you need to delete release branch- both local an remote.

Release troubleshooting

If any of the npm-gitflow release scripts fail for some reason- do not hesitate to look at the scripts sources. Eliminate the underlying problem in the component you are releasing and complete necessary steps manually using git/npm/lerna commands as necessary.

Hotfix process

Hotfix process is the same as release with the exception that it happens in hotfix branch, is initiated from main branch and corresponding versions/Docker images are labeled with hotfix tag. See Release process description.

Use npx hotfix-start and npx hotfix-finish npm-gitflow commands to prepare hotfix.

Git config

git config --global core.autocrlf false
git config --global core.longpaths true
git config --global pull.rebase merges

Issues and PRs

Pull Requests

Link PR to issue in a dedicated section. Do not just mention PR in a comment.

Create single PR per component per issue. I.e. if an issue requires changes to several components- it is OK to create PR for each component and link them to single issue, but do not create several different branches/PRs for the same component.

git messages conventions

Use Conventional Commits conventions for commit messages and PR titles.

Running APIHUB locally

There's a Docker Compose file that allows to run APIHUB locally from Docker images.

Release Docker images are published with tags corresponding to version (e.g. 2.9.0) or you could use one of Docker image tags for development branches:

Branch Name Docker Image Tag
develop dev
feature/my-feature feature-my-feature
release next

You can always look-up packages available for the repository in the Packages section, e.g. here are APIHUB UI Docker Images.

Using proxy development mode

It is useful to be able to run UI build from sources locally and connect to some APIHUB instance (it could be cloud instance or it could be APIHUB instance spin up on localhost). You can test and debug your latest changes without rebuilding the UI Docker image.

Running UI in proxy development mode allows to do just that.

  • open vite.config.ts file of the package you want to run (e.g. Portal)
  • specify the instance you want to connect to in proxyServer const (e.g. `http://localhost:8081/)
  • run proxy NPM script from corresponding (e.g. for Portal)
  • open login page in the browser http://localhost:8081/login and login using credentials for the instance

Package manager

All APIHUB Frontend repositories are using NPM as a package manager.

GitHub NPM Registry

We use GitHub NPM Registry for publishing packages.

GitHub NPM registry requires authentication for installing packages from it. So, create a Personal Access Token (classic) with a read:packages scope on a GitHub and specify it in per-user (or global) .npmrc file.

//npm.pkg.github.com/:_authToken="<GITHUB_PAT>"

Publishing Packages

All packages should be published by CI processes which are set up for the repositories.

Do not publish NPM packages manually.

Testing

APIHUB frontend components could have a unit tests, screenshot tests and E2E tests or combination of thereof.

Make sure existing tests are green and new tests of appropriate type are added before submitting PR.

Unit testing

We use Jest for unit testing.

Use NPM script test to run unit tests.

Screenshot testing

Several APIHUB UI components have screenshot (also called snapshot) tests.

These are

Use NPM script screenshot-test:docker to run screenshot tests locally.

Note, that you need to setup WSL with Podman Desktop in order to be able to run screenshot tests locally.

End to end testing

We use Playwright for E2E testing.

E2E tests are run automatically for Pull Requests in UI repository. If E2E tests failed, you can download reports from run artefacts to understand what went wrong.

You can run E2E tests manually on any APIHUB Docker images available in GitHub Packages repository via workflow in qubership-apihub repository.

If you want to run Playwright tests locally on you PC- see instructions in ui-tests.

Setup WSL with Podman Desktop

<TBD>, move from https://github.com/Netcracker/qubership-apihub/issues/36

Architecture

APIHUB frontend repositories list

Auxiliary components

API Specification Processing Stack

API Specification Rendering Stack

UI

Cross-cutting feature development

Branch naming

When doing cross-cutting feature development, use the same branch names in all related repositories, e.g. feature/my-feature or bugfix/my-bugfix. It simplifies managing a set of related changes across different repositories and is required to (future) automation scripts.

NPM link

Specify dependencies

Specify required components version as NPM dist-tag (e.g. feature-my-feature). This will ensure up-to-date specific version will always be retrieved during build from development branches on CI and you can easily get up-to-date dependencies versions locally.

Do not specify exact version as a dependency (e.g. 2.10.1-feature-my-feature.20250317141223)

Publishing to NPM registry

Lock file management

Use update-lock-file NPM script to get up to date versions for dependencies with @netcracker scope locally. The script updates lock file and install dependencies with scope @netcracker, for which version is specified as NPM dist-tag.

CI process updates these dependencies automatically during components build from development branches.

Do not commit lock file changes for components with scope @netcracker and NPM dist-tag dependencies in development branches- it does not make sense (by nature, dependencies to dist-tag versions should always be updated in development branches), and only creates potential merges conflicts.

Lock file changes due to updates to release versions of dependencies (both @netcracker scoped and other 3rd-party libraries) could and should be commited in development branches. Changes to lock file due to updates to releases version for components with scope @netcracker are usually commited during Release finish step of the release process.

Code Style

Linting

APIHUB VSCode extension

Technical Debt Management

NPM Scripts

Storybook

Code Review Process

GitHub Workflows

UI Development

Shared components

⚠️ **GitHub.com Fallback** ⚠️