We welcome contributions that enhance the project and improve the overall quality of our codebase. While we appreciate the effort that goes into making contributions, we kindly ask that contributors focus on the following types of changes:
- **Feature Enhancements:** Substantial improvements or new features that add significant value to the project.
- **Bug Fixes:** Fixes for known bugs or issues that impact functionality.
- **Documentation Improvements:** Comprehensive updates to documentation that clarify usage, installation, or project structure.
- **Performance Improvements:** Changes that enhance the performance or efficiency of the application.
Please note that we accept contributions for newly submitted issues or those labeled "Available for contribution" - all other issues are reserved for the core team of the project.
2. Optionally, clone `.env.example` and name it `.env.secrets`. Fill it with necessary secrets for integrating with [external services](./ENVS.md#external-services-configuration). Include only secrets you need.
4. Open your browser and navigate to the URL provided in the command line output (by default, it is `http://localhost:3000`).
B. Pre-defined configuration:
1. Optionally, clone `.env.example` file into `configs/envs/.env.secrets`. Fill it with necessary secrets for integrating with [external services](./ENVS.md#external-services-configuration). Include only secrets your need.
2. Choose one of the predefined configurations located in the `/configs/envs` folder.
1. First and foremost, document variable in the [/docs/ENVS.md](./ENVS.md) file; provide short description, its expected type, requirement flag, default and example value; **do not skip this step** otherwise the app will not receive variable value at run-time
2. Make sure that you have added a property to React app config (`configs/app/index.ts`) in appropriate section that is associated with this variable; do not use ENV variable values directly in the application code; decide where this variable belongs to and place it under the certain section:
- `services` - some 3rd party service integration which is not related to one particular feature
3. If a new variable is meant to store the URL of an external API service, remember to include its value in the Content-Security-Policy document header. Refer to `nextjs/csp/policies/app.ts` for details.
4. For local development purposes add the variable with its appropriate values to pre-defined ENV configs `configs/envs` where it is needed
5. Add the variable to CI configs where it is needed
6. If your variable is meant to receive a link to some external resource (image or JSON-config file), extend the array `ASSETS_ENVS` in `deploy/scripts/download_assets.sh` with your variable name
7. Add validation schema for the new variable into the file `deploy/tools/envs-validator/schema.ts`
8. Check if modified validation schema is valid by doing the following steps:
- add your variable into `./test/.env.base` test preset or create a new test preset if needed
- if your variable contains a link to the external JSON config file:
- add example of file content into `./test/assets` directory; the file name should be constructed by stripping away prefix `NEXT_PUBLIC_` and postfix `_URL` if any, and converting the remaining string to lowercase (for example, `NEXT_PUBLIC_MARKETPLACE_CONFIG_URL` will become `marketplace_config.json`)
- in the main script `index.ts` extend array `envsWithJsonConfig` with your variable name
- run `yarn test` command to see the validation result
Every feature or bugfix should be accompanied by tests, either unit tests or component visual tests, or both, except from trivial fixes (for example, typo fix). All commands for running tests you can find [below](./CONTRIBUTING.md#command-list).
If your changes are only related to the logic of the app and not to its visual presentation, then try to write unit tests using [Vitest](https://vitest.dev/) framework and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/). In general these tests are "cheaper" and faster than Playwright ones. Use them for testing your utilities and React hooks, as well as the whole components logic.
Place your test suites in `.spec.ts` or `.spec.tsx` files. You can find or add some mocks or other helpful utilities for these tests purposes in the `/vitest` folder.
*Note*, that we are using custom renderer and wrapper in all tests for React components, so please do not import package `@testing-library/react` directly in your test suites, instead use imports from `vitest/lib` utility.
For changes associated with the UI itself write components visual tests using [Playwright](https://playwright.dev/) framework and its *experimental* [Components test library](https://playwright.dev/docs/test-components). Please be aware of known [issues and limitations](https://playwright.dev/docs/test-components#known-issues-and-limitations) of this library.
Your tests files should have `.pw.tsx` extension. All configs, mocks, fixtures and other utilities for these tests live in `/playwright` folder.
We have 3 pre-configured projects. You can run your test with the desired project by simply adding its [tag](https://playwright.dev/docs/test-annotations#tag-tests) to the test name:
- `default` - default project for all test, uses desktop Chrome desktop device; don't need to specify its tag, instead use `-@default` tag to skip test run with this project
- `mobile` - project for testing on mobile devices, uses Safari mobile browser; add tag `+@mobile` to run test with this project
- `dark-color-mode` - project for testing app in the dark color mode, uses desktop Chrome desktop device with forced dark color mode; add tag `+@dark-mode` to run test with this project.
*Note* that, since we are developing not on the same operating system as our CI system, we have to use Docker to generate or update the screenshots. In order to do that use `yarn test:pw:docker <path-to-file> --update-snapshots` command. Please **do not commit** any screenshots generated via `yarn test:pw:local` command, their associated tests will fail in the CI run.
> This will add the original repository as a "remote" called "upstream," Then
> fetch the git information from that remote, then set your local `main` branch
> to use the upstream main branch whenever you run `git pull`. Then you can make
> all of your pull request branches based on this `main` branch. Whenever you
> want to update your version of `main`, do a regular `git pull`.
2. Create a branch for your PR with `git checkout -b <your-branch-name>`; we do not follow any branch name convention just yet
3. Commit your changes. Commits should be one logical change that still allows all tests to pass. Prefer smaller commits if there could be two levels of logic grouping. The goal is to allow contributors in the future (including your future self) to determine your reasoning for making changes and to allow them to cherry-pick, patch or port those changes in isolation to other branches or forks. Again, there is no strict commit message convention, but make sure that it clear and fully describes all changes that were made
4. If during your PR you reveal a pre-existing bug, try to isolate the bug and fix it on an independent branch and PR it first
5. Where possible, please provide unit tests that demonstrate new functionality or bug fix is working
1. Push your changes and create a Pull Request. If you are still working on the task, please use "Draft Pull Request" option, so we know that it is not ready yet. In addition, you can add label "skip checks" to your PR, so all CI checks will not be triggered.
2. Once you finish your work, remove label "skip checks" from PR, if it was added before, and publish PR if it was in the draft state
6. After code review is done, we merge pull requests by squashing all commits and editing the commit message if necessary using the GitHub user interface.
*Note*, if you Pull Request contains any changes that are not backwards compatible with the previous versions of the app, please specify them in PR description and add label ["breaking changes"](https://github.com/blockscout/frontend/labels/breaking%20changes) to it.
There are some predefined tasks for all commands described above. You can see the full list by pressing <kbd>cmd + shift + P</kbd> and using command `Task: Run task`