This directory is managed as a monorepo that is composed of several NPM packages. The primary sub-package is apps/platform with the StackRox Kubernetes Security Platform Web UI.
The root directory and its package.json
file serves as an entry point for any
interactions with the applications and packages. Any "outsider" tool isn't
expected to know the details of monorepo structure and packages inside it. E.g.
CI only uses Makefile
and looks for artifacts (like test results) in the root
directory, never looking into packages
/ apps
subdirectories.
Packages live in the packages
directory. It's implied that every package is
published to the
private NPM registry from where it
can be consumed by other StackRox projects.
While working on a particular package, treat it as an independent NPM package, e.g. it shouldn't assume that any of the dependencies will be provided by the monorepo root package. Inner source model describes the intent well.
There is a contract that root package has with the monorepo NPM packages. This
contract defined through the scripts that NPM packages should have defined in
their package.json
files:
clean
- can be used to ensure a clean state before executing another script that might produce transient artifacts like build files etc. Can be omitted if running consecutive invocation of any scripts will never collide.lint
- run lint and static code analysis, should fail in case of errors.build
- run production optimized build.start
- build dev optimized version and possibly hot-rebuild on changes to the sources by listening to them.test
- run unit / integration tests. If env varTEST_RESULTS_OUTPUT_DIR
defined, package should place JUnit reports into${TEST_RESULTS_OUTPUT_DIR}/reports
dir, and any artifacts to be stored by CI into${TEST_RESULTS_OUTPUT_DIR}/artifacts
.test-e2e
- run end-to-end tests. If env varTEST_RESULTS_OUTPUT_DIR
defined, package should place JUnit reports into${TEST_RESULTS_OUTPUT_DIR}/reports
dir, and any artifacts to be stored by CI into${TEST_RESULTS_OUTPUT_DIR}/artifacts
.prepublishOnly
- recommended for preparing the package before publishing, e.g. it can in turn run thebuild
step.
Note that not having a particular script defined will simply mean that this
package will be skipped when the corresponding script is run on the monorepo
root level. E.g. if the package doesn't have test
script, then when CI runs
unit tests step for this monorepo, no tests will be executed for that package.
Ensure the following fields are correctly set in package.json
:
"name": "@stackrox/{package-name}",
"repository": {
"type": "git",
"url": "https://github.com/stackrox/rox.git",
"directory": "ui/packages/{package-dir-name}"
},
"license": "UNLICENSED"
Note that the package should be scoped to @stackrox
and no "publishConfig"
defined in package.json
as publishing configuration is defined on the monorepo
root level.
Finally, make build modifications:
- update .ossls.yml to include package's
node_modules
dir;
If you need to add a dependency on @stackrox/package-a
to
@stackrox/package-b
, on the monorepo root level run the command
yarn lerna add @stackrox/package-a --scope @stackrox/package-b
(add --dev
to add @stackrox/package-a
as a dev dependency).
- Create a new branch you'll use to create a PR for versions bump.
- Run
yarn lerna:version
that will ask you to pick new versions for the packages. - Commit the changes to the
package.json
files, push the branch and create a PR. - Once the PR is merged, CI will automatically publish new versions to GitHub Packages NPM registry.
As we're not using conventional commits, use your best judgement for the version increase, considering semantic versioning best practices.
Applications live in the 'apps' directory. They're never published to any registry. They serve as entry points for the builds to produce a final set of static assets to be included into the Docker image etc.
Same as packages, they still should be treated as independent NPM packages w/o an implicit dependencies on the packages provided by the monorepo root.
It's an unlikely event a new application is needed, like if the product has two offerings with one being a functional slimmed down version of the main one.
In this case ensure the following fields are correctly set in package.json
:
"name": "@stackrox/{app-name}",
"version": "0.0.0",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/stackrox/rox.git",
"directory": "ui/apps/{app-dir-name}"
},
"license": "UNLICENSED"
If you need to add a dependency on @stackrox/package-a
to @stackrox/my-app
,
on the monorepo root level run the command
yarn lerna add @stackrox/package-a --scope @stackrox/my-app
(add --dev
to add @stackrox/package-a
as a dev dependency).
Once the command succeeds, find @stackrox/package-a
dependency in the
package.json
file of @stackrox/my-app
and change the version to "*"
so
it's
"@stackrox/package-a": "*"
The reason is that the app is never published therefore it should always depend
on the version of the package in the same monorepo. Yet when
updating package versions the
lerna:version
script will not touch any package.json
files with
"private": true
, potentially leaving the application to depend on an older
version of a package.
If you are developing only StackRox UI, then you don't have to install all the build tooling described in the parent README.md. Instead, follow the instructions below.
- Docker
- Node.js version compatible with the
"engine"
requirements in the package.json file (It's highly recommended to use the latest LTS version. If you're managing multiple versions of Node.js on your machine, consider using nvm) - Yarn v1.x
Before starting, make sure you have the above tools installed on your machine
and you've run yarn install
to download dependencies.
The front end development environment consists of a CRA-provided dev server to serve static UI assets and deployed StackRox Docker containers that provide backend API.
Set up your environment as follows:
Note: Similar instructions apply when using Minikube.
-
Docker for Mac - Make sure you have Kubernetes enabled in your Docker for Mac and
kubectl
is pointing todocker-desktop
(see docker docs). -
Deploy - Run
yarn deploy-local
(wraps../deploy/k8s/deploy-local.sh
) to deploy the StackRox k8s app. Make sure that your git working directory is clean and that the branch that you're on has a corresponding tag from CI (see Roxbot comment for a PR branch). Alternatively, you can specify the image tag you want to deploy by setting theMAIN_IMAGE_TAG
env var. Ifyarn deploy-local
fails, see this Knowledge Base article for debugging instructions. -
Start - Start your local dev server by running
yarn start
. This will build all monorepo packages in watch mode. To build and watch only the main UI and to see available options toyarn start
, first ensure thatyarn build
has been run from the top level and then refer to the README.md in theapps/platform
directory.
Note: to redeploy a newer version of StackRox, delete existing app using
teardown
script from the workflow
repo, and repeat the steps above.
To develop the front-end platform locally, but use a remote Central, please refer to the detailed instructions in the how-to article Use remote Central for local front-end dev
This project is IDE agnostic. For the best dev experience, it's recommended to add / configure support for ESLint and Prettier in the IDE of your choice.
Examples of configuration for some IDEs:
- Visual Studio Code: Install plugins
ESLint
and
Prettier,
then add configuration to
settings.json
:
"eslint.alwaysShowStatus": true,
"eslint.codeAction.showDocumentation": {
"enable": true
},
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
- IntelliJ IDEA /
WebStorm /
GoLand: Install and configure
ESLint plugin. To apply
autofixes on file save add
File Watcher
to watch JavaScript files and to run ESLint program
rox/ui/node_modules/.bin/eslint
with arguments--fix $FilePath$
.
For better development experience it's recommended to use Google Chrome Browser with the following extensions installed: