mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
0256e1da7d
I am making this change for two reasons: * We expect to upgrade to GHC 9.2.7 imminently, which is not available on the nixos-22.11 branch. * We need to upgrade unixODBC, which has stagnated on nixos-22.11. While we expect a new NixOS release in a month or two, we can't really afford to wait that long. In addition, we might need to upgrade GHC again soon after that. I removed `hpack` because we don't actually use it any more. PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8483 GitOrigin-RevId: 9a7ef1a97599a218e34dfde1ad4f6a7279d2ba0e
305 lines
11 KiB
Markdown
305 lines
11 KiB
Markdown
# Contributing
|
||
|
||
This guide explains how to set up the graphql-engine server for development on your own machine and how to contribute.
|
||
|
||
## Pre-requisites
|
||
|
||
- [GHC](https://www.haskell.org/ghc/) 9.2.5 and [cabal-install](https://cabal.readthedocs.io/en/latest/)
|
||
- There are various ways these can be installed, but [ghcup](https://www.haskell.org/ghcup/) is a good choice if you’re not sure.
|
||
- There are few system packages required like `libpq-dev`, `libssl-dev`, etc. The best place to get the entire list is from the [Dockerfile](../packaging/graphql-engine-base/ubuntu.dockerfile)
|
||
- Additional Haskell tools (expected versions can be found in _VERSIONS.json_):
|
||
- [HLint](https://github.com/ndmitchell/hlint), for linting Haskell code
|
||
- [Ormolu](https://github.com/tweag/ormolu), for formatting Haskell code
|
||
- [Docker](https://www.docker.com/get-started/)
|
||
- [Docker Compose](https://docs.docker.com/compose/install/)
|
||
|
||
For running the test suite:
|
||
|
||
- [node.js](https://nodejs.org/en/) (see [.nvmrc](../.nvmrc) for the version), and the bundled NPM version
|
||
- Python >= 3.9 with pip3 and virtualenv
|
||
|
||
For building the Console:
|
||
|
||
- node.js, as above
|
||
|
||
Additionally, you will need a way to run a PostgreSQL database server. The `dev.sh` script (described below) can set up a PostgreSQL instance for you via [Docker](https://www.docker.com), but if you want to run it yourself, you’ll need:
|
||
|
||
- [PostgreSQL](https://www.postgresql.org) >= 10
|
||
- [postgis](https://postgis.net)
|
||
|
||
### Installing tooling with Nix
|
||
|
||
Simply [install Nix](https://nixos.org/download.html) and type `nix develop`.
|
||
|
||
If you don't want to start a new shell each time, you can also use [direnv](https://direnv.net/) and [nix-direnv](https://github.com/nix-community/nix-direnv), then create a _.envrc.local_ file with the contents:
|
||
|
||
```bash
|
||
#!/usr/bin/env bash
|
||
|
||
use flake
|
||
```
|
||
|
||
### Installing tooling with direnv
|
||
|
||
This project contains scripts for installing project dependencies automatically with [direnv](https://direnv.net/). For more information, see the `.envrc` file in the root.
|
||
|
||
## Development workflow
|
||
|
||
You should fork the repo on github and then `git clone https://github.com/<your-username>/graphql-engine`.
|
||
After making your changes
|
||
|
||
### Compile
|
||
|
||
...console assets:
|
||
|
||
$ cd frontend
|
||
$ nvm use
|
||
$ npm ci
|
||
$ npm run server-build:ce
|
||
$ cd ..
|
||
|
||
...and the server:
|
||
|
||
$ ln -s cabal/dev.project cabal.project.local
|
||
$ cabal new-update
|
||
$ cabal new-build graphql-engine
|
||
|
||
To set up the project configuration to coincide with the testing scripts below, thus avoiding recompilation when testing locally, rather use `cabal/dev-sh.project.local` instead of `cabal/dev.project`:
|
||
|
||
$ ln -s cabal/dev-sh.project.local cabal.project.local
|
||
|
||
#### Compiling on MacOS
|
||
|
||
If you are on MacOS, or experiencing any errors related to missing dependencies on MacOS, please try [this alternative setup guide](COMPILING-ON-MACOS.md), or try Nix (as above).
|
||
|
||
### IDE Support
|
||
|
||
You may want to use [hls](https://github.com/haskell/haskell-language-server)/[ghcide](https://github.com/haskell/ghcide) if your editor has LSP support. A sample configuration has been provided which can be used as follows:
|
||
|
||
```
|
||
ln -s sample.hie.yaml hie.yaml
|
||
```
|
||
|
||
If you have to customise any of the options for ghcide/hls, you should instead copy the sample file and make necessary changes in `hie.yaml` file. Note that `hie.yaml` is gitignored so the changes will be specific to your machine.
|
||
|
||
```
|
||
cp sample.hie.yaml hie.yaml
|
||
```
|
||
|
||
### Run and test via `run-new.sh`
|
||
|
||
The `run-new.sh` scripts are an active work in progress, and will eventually replace the `dev.sh` option below.
|
||
|
||
Run the Python integration tests with `./server/tests-py/run-new.sh`.
|
||
|
||
Filter on specific test files with `./server/tests-py/run-new.sh -- create_async_action_with_nested_output_and_relation.py`
|
||
|
||
If you have any issues with `run-new.sh`, please create a [GitHub issue](https://github.com/hasura/graphql-engine/issues/new/choose) and run and test via `dev.sh` instead.
|
||
|
||
### Run and test via `dev.sh`
|
||
|
||
The `dev.sh` script in the top-level `scripts/` directory is a turnkey solution to build, run, and
|
||
test `graphql-engine` using a Docker container to run a Postgres database. **Docker is necessary to
|
||
use `dev.sh`.**
|
||
|
||
To use `dev.sh`, first launch a new postgres container with:
|
||
|
||
$ scripts/dev.sh postgres
|
||
|
||
Then in a new terminal launch `graphql-engine` in dev mode with:
|
||
|
||
$ scripts/dev.sh graphql-engine
|
||
|
||
This command also starts the GraphQL Engine console, which you can access at http://localhost:8181/console.
|
||
|
||
The `dev.sh` will print some helpful information and logs from both services
|
||
will be printed to screen.
|
||
|
||
You can run the test suite with:
|
||
|
||
$ scripts/dev.sh test
|
||
|
||
This should run in isolation. The output format is described in the [pytest documentation](https://docs.pytest.org/en/latest/usage.html#detailed-summary-report). Errors and failures are indicated by `F`s and `E`s.
|
||
|
||
Optionally, launch a new container for alternative (MSSQL) backend with:
|
||
|
||
$ scripts/dev.sh mssql
|
||
|
||
Tests can be run against a specific backend (defaulting to Postgres) with the `backend` flag, for example:
|
||
|
||
$ scripts/dev.sh test --integration -k TestGraphQLQueryBasicCommon --backend (bigquery|citus|mssql|postgres)
|
||
|
||
### Run and test manually
|
||
|
||
If you want, you can also run the server and test suite manually against an instance of your choosing.
|
||
|
||
#### Run
|
||
|
||
The following command can be used to build and launch a local `graphql-engine` instance:
|
||
|
||
```
|
||
$ cabal new-run -- exe:graphql-engine \
|
||
--database-url='postgres://<user>:<password>@<host>:<port>/<dbname>' \
|
||
serve --enable-console --console-assets-dir=frontend/dist/apps/server-assets-console-ce
|
||
```
|
||
|
||
This will launch a server on port 8080, and it will serve the console assets if they were built with `npm run server-build:ce` as mentioned above.
|
||
|
||
#### Test
|
||
|
||
`graphql-engine` has several test suites, among them:
|
||
|
||
1. A small set of unit tests and integration tests written in Haskell, in `server/src-test`.
|
||
|
||
2. A new integration test suite written in Haskell, in `server/lib/api-tests`.
|
||
|
||
3. An extensive set of end-to-end tests written in Python, in `server/tests-py`.
|
||
|
||
All sets of tests require running databases:
|
||
|
||
- some unit tests hit the database, and running the unit test suite requires passing in a postgres connection string,
|
||
- the Haskell integration test suite requires databases to run (they can be started via the docker command listed below),
|
||
- the Python integration test suite also requires databases AND the engine to be running, which can be started via either the `dev.sh` script, or manually.
|
||
|
||
##### Running py tests
|
||
|
||
The easiest way to run the Python integration test suite is by running:
|
||
|
||
```sh
|
||
$ scripts/dev.sh test --integration
|
||
```
|
||
|
||
For more details please check out the [README](./tests-py/README.md).
|
||
|
||
##### Running the Haskell test suite
|
||
|
||
There are three categories of unit tests:
|
||
|
||
- unit tests
|
||
- PostgreSQL integration tests (requires a PostgreSQL instance)
|
||
- MS SQL Server integration tests (requires a MS SQL Server instance)
|
||
|
||
The easiest way to run these tests is through `make`, which will automatically spin up and shut down Docker containers for the databases:
|
||
|
||
```
|
||
$ make test-unit
|
||
$ make test-integration-postgres
|
||
$ make test-integration-mssql
|
||
```
|
||
|
||
If you want to limit to a specific set of tests, use `HSPEC_MATCH`:
|
||
|
||
```
|
||
$ make test-unit HSPEC_MATCH='Memoize'
|
||
```
|
||
|
||
Alternatively, you can use Cabal directly (though you'll have to start the databases yourself):
|
||
|
||
```
|
||
$ cabal run -- graphql-engine:test:graphql-engine-tests
|
||
$ HASURA_GRAPHQL_DATABASE_URL='postgres://<user>:<password>@<host>:<port>/<dbname>' \
|
||
cabal run -- graphql-engine:test:graphql-engine-test-postgres
|
||
```
|
||
|
||
##### Running the Haskell integration test suite
|
||
|
||
Run `make test-backends`. This effectively runs the following two commands:
|
||
|
||
```
|
||
$ docker compose up --detach --wait
|
||
$ cabal run api-tests:exe:api-tests
|
||
```
|
||
|
||
For more details please check out the [README](./lib/api-tests/README.md).
|
||
|
||
##### Running unit tests and recompiling
|
||
|
||
While working on features, you might want to add unit tests and work through
|
||
getting them to pass. This is generally a slow process, but there is a
|
||
workaround to allow loading both the `graphql-engine` library and the unit
|
||
testing library in `ghcid` at the same time:
|
||
|
||
```sh
|
||
$ ghcid -a -c "cabal repl graphql-engine-tests -f -O0 -fghci-load-test-with-lib" --test Main.main
|
||
```
|
||
|
||
This assumes you already have `HASURA_GRAPHQL_DATABASE_URL` and `HASURA_MSSQL_CONN_STR`
|
||
exported as environment variables.
|
||
|
||
If you just want to run all unit tests, you can add ` --setup ":set args unit"`
|
||
to the command line above. If you want to run specific test(s), you can instead
|
||
do `--setup ":set args unit --match name_of_test(s)"`.
|
||
|
||
#### Building with profiling
|
||
|
||
To build with profiling support, you need to both enable profiling via `cabal`
|
||
and set the `profiling` flag. E.g.
|
||
|
||
```
|
||
$ cabal build exe:graphql-engine -f profiling --enable-profiling
|
||
```
|
||
|
||
### Create Pull Request
|
||
|
||
- Make sure your commit messages meet the [guidelines](../CONTRIBUTING.md).
|
||
- If you changed the versions of any dependencies, run
|
||
`scripts/cabal-freeze-update.sh --all` to update the freeze file.
|
||
- Create a pull request from your forked repo to the main repo.
|
||
- Every pull request will automatically build and run the tests.
|
||
|
||
## Code conventions
|
||
|
||
The following conventions help us maintain a uniform style for all committers:
|
||
make sure your contributions are in line with them.
|
||
|
||
We enforce these by means of CI hooks which will fail the build if any of these
|
||
are not met.
|
||
|
||
- No compiler warnings: Make sure your code builds with no warnings (adding
|
||
`-Werror` to `ghc-options` in your `cabal.project` is a good way of checking
|
||
this.)
|
||
- No lint failures: Use [hlint](https://github.com/ndmitchell/hlint) with our
|
||
custom config to validate your code, using `hlint --hint=../.hlint.yaml`.
|
||
- Consistent formatting: Use [ormolu](https://github.com/tweag/ormolu) to
|
||
format your code. `ormolu -ei '*.hs'` will format all files with a `.hs`
|
||
extension in the current directory.
|
||
- Consistent style: Consider the [style guide](./STYLE.md) when writing new code.
|
||
|
||
## Testing
|
||
|
||
Please see [testing-guidelines](./testing-guidelines.md) for details on how to add tests.
|
||
|
||
## Local hoogle instance
|
||
|
||
[Hoogle](https://github.com/ndmitchell/hoogle) is a Haskell API search engine. The server at
|
||
[hoogle.haskell.org](https://hoogle.haskell.org/) provides a version of Hoogle that enables
|
||
searching through all packanges available in [Stackage](https://www.stackage.org/). Following
|
||
instructions help in setting up a local hoogle server that enables searching through `graphql-engine` server code.
|
||
|
||
### Step 1: Installing hoogle
|
||
|
||
Installing `hoogle` is fairly simple with `cabal`.
|
||
|
||
```bash
|
||
$ cabal install hoogle
|
||
```
|
||
|
||
### Step 2: Generating hoogle database
|
||
|
||
A Hoogle database is a prebuilt index of a set of packages. The `hoogle.sh` script in the
|
||
top-level `scripts/` directory helps in generating the hoogle database for GraphQL Engine server
|
||
code and store it in `dist-newstyle/` directory.
|
||
|
||
$ scripts/hoogle.sh generate
|
||
|
||
### Step 3: Running hoogle instance
|
||
|
||
Running the following `hoogle.sh` script command starts a local hoogle server with the database
|
||
generated in `Step 2`.
|
||
|
||
$ scripts/hoogle.sh serve
|
||
|
||
Use `--port` option to specify custom port to start hoogle server.
|
||
|
||
$ scripts/hoogle.sh serve --port 8181
|