Thank you for contributing to Zui!
Per common practice, please open an issue before sending a pull request. If you think your ideas might benefit from some refinement via Q&A, come talk to us on Slack as well.
Install these dependencies:
- Node - the version specified in the
.node-version
file at the root folder. - Yarn - a package manager for installing dependencies and starting Zui in dev mode.
- Go - to compile some Zed dependencies.
- Typical command line tools, such as
make
,unzip
, andcurl
Then clone the repo, install the node modules, and start the app.
git clone https://github.com/brimdata/zui
cd zui
yarn
yarn start
When a file is changed, it will be recompiled and the app will automatically reload.
On subsequent updates, git pull
and yarn
.
Zui is a TypeScript, React, Electron app.
- Electron - it's helpful to understand the main vs renderer processes
- TypeScript
- Prettier
- React
- Styled Components
- Redux Toolkit
- Jest
- Playwright
- Main process -
src/js/electron/main.ts
- Renderer process -
src/js/search.tsx
This directory structure is a work in progress. You will see many files not in the places described here. Please migrate what you can and follow this for any new code.
├── app (renderer code)
│ ├── core (generic shared code)
│ ├── features (larger app features)
│ ├── initializers (code run on startup)
│ ├── plugins (plugin code)
│ ├── routes (entry points for each url)
│ ├── state (ui state)
│ ├── window-a.tsx (window entry points)
│ └── window-b.tsx
├── electron (main process code)
└── ppl (licensed code)
Import Rule: Only import modules from /core
, /state
, or your own descendants. Components in /routes
can import modules from /features
.
We have a few different types of test suites.
- Unit test -
test/unit
- API tests -
test/api
- System tests -
test/system
- Integration tests
test/playwright
We use Jest Projects to organize the configuration for these.
Unit tests go right next to the file they are testing with a .test.js
suffix.
There are several ways to run unit tests.
# Run all
yarn jest --projects test/unit
# Run by name
yarn jest --projects test/unit -- name-of-test
System tests sit between unit tests and integration tests. To create one, instantiate a SystemTest
class at the top level of any test file.
const system = new SystemTest("name-of-test")
This will run the electron main process entry point, main.js
, which spins up a local Zed lake. You then mount the root <App />
component into the JSDOM testing environment and begin to simulate a user clicking buttons and asserting elements exist. This is done with @testing-library/react.
import {screen} from "@testing-library/react"
import {SystemTest} from "src/test/system/system-test"
const system = new SystemTest("my-test")
test("click the button", async () => {
system.mountApp()
const button = screen.getByRole("button", {name: "Submit"})
system.click(button)
await screen.findByText("Complete!")
})
All backend requests are made with Node and hit the local Zed lake. Any browser APIs that are not in JSDOM are mocked or polyfilled. The electron APIs are mocked as well. You can find them in test/shared/__mocks__/electron
.
The SystemTest
class comes with a few helper methods for commonly performed actions in the Zui app like .runQuery(q), .ingestFile(name), .navTo(path), and .render(jsx). It also re-exports some of the common userEvent methods like .click() and .rightClick()
They can be run like so:
# Run all
yarn jest --projects test/system
# Run by name
yarn jest --projects test/system -- name-of-test
Use the Styled Components library to style new components. Previously, we used scss files located in src/css
. Many of the components are styled with scss, and class names, but we recently committed to Styled Components. We also have a "theme" that holds all the common colors and styles used in our UI.
Because we persist state on a user's computer, if they upgrade Zui and we've changed the expected state, we need to migrate the old state. If any of the reducers in src/js/state
are changed, we need to write a migration. There is a tool we built to help with this. You can run, for example:
bin/gen migration addScrollPositionToViewer
This creates a file in src/js/state/migrations
with a function that can manipulate the persisted state from the previous version.
See the Adding Migrations page for a more detailed guide.
The Zed service is the daemon responsible for data ingestion and query execution. As a postinstall step, the zed
binary is downloaded and stored in the ./zdeps
directory. Zui will automatically execute and terminate the service when it starts and stops.
Our CI server checks for code format diffs, type errors, unit test failures, and integration test failures. You can check all these things locally before pushing your branch.
yarn format # Prettier format
yarn tsc # Check the types
yarn test # Unit tests with jest
yarn test:api # API tests
yarn test:system # System Tests
yarn test:playwright # Integration tests with jest & playwright
Releases with installable artifacts are created automatically by an Actions Workflow when a GA release is tagged.
You can installable artifacts based on your own checkout via:
yarn build
yarn release
Any platform artifacts created will be found under ./installers
.
This will create packages for the detected OS platform, e.g., .deb
and .rpm
packages if on Linux. Creation of your own macOS (.dmg
) and Windows (.exe
)
artifacts requires additional settings described in the following sections.
To create notarized
MacOS packages by hand, set the following environment variables before running
the yarn
commands shown above.
export APPLE_ID=<user>
export APPLE_TEAM_ID=<team-id>
export APPLE_ID_PASSWORD=<app-specific-password>
Where APPLE_ID
is the Apple ID user name (typically an email address), APPLE_TEAM_ID
is the Team ID from the user's Apple Developer Account page, and APPLE_ID_PASSWORD
is an app-specific password created for notarization (details here). This will also sign the contents of the package, which requires a Developer ID certificate to be present in your keychain.
Notarization can take some time to complete ("typically less than an hour"). If you want to check on the status of the notarization request, run:
xcrun notarytool history --apple-id <apple-user-id> --password <app-specific-password> --team-id <apple-team-id>
The changes in ballot CSC-17 from the CA/B Forum have made it such that GA Zui releases on Windows are currently only signed using a cloud service. PR zui/3050 provides details of how this is currently performed with SSL.com's eSigner. If you successfully sign Zui with another service or sign manually and have tips to share based on your experience, please contact us.
This repository contains source code that is licensed under either a BSD-3-Clause license or the Polyform Perimeter license - see the LICENSE.txt file for specifics.
If you make a contribution to this repository, whether to source code licensed under the BSD-3-Clause license or the Polyform Perimeter license, you agree that you are licensing your contribution under the terms of the BSD-3-Clause license found in LICENSE.txt, and you agree that you have the right to license your contribution under those license terms.
We want to prevent technology giants from using the Polyform Perimeter license covered code to create replacement offerings of our projects.
The overwhelming majority of Zui or Zed users and developers will not be restricted by this license, including those using Zui or Zed in commercial settings.
The use of the source-available Polyform Perimeter license prevents use cases like:
- Marketing a work as a “as-a-service” style offering for server components like Zed, while using material covered under the Polyform Perimeter license
- Marketing a work as a replacement for the Zui desktop application, while using material covered under the Polyform Perimeter license
We believe users and developers should have access to the source code for our project, and we need a sustainable business model to continue funding our work. Using the source-available Polyform Perimeter license on portions of the source code lets us realize both.
We appreciate your interest in improving Zui. If you've got questions that aren't answered here, please join our public Slack workspace and ask!