# Development

## Workflows

Ledger provides [reusable workflows running on GitHub actions](https://github.com/ledgerhq/ledger-app-workflows), which
builds, analyzes or tests the code, checks the application's metadata and more. Some of these workflows are mandatory.

> **Warning:** <ul>
>   <li>
>     The following workflows are required on every device app repository, and must run without error.
>   </li>
>
>   <li>
>     Ledger will not deploy an application if these workflows are not integrated and green.
>   </li>
> </ul>

- The [guidelines enforcer workflow](https://github.com/LedgerHQ/ledger-app-workflows/blob/master/.github/workflows/reusable_guidelines_enforcer.yml)
  (example its usage on boilerplate [here](https://github.com/LedgerHQ/app-boilerplate/blob/master/.github/workflows/guidelines_enforcer.yml))
- The [build workflow](https://github.com/LedgerHQ/ledger-app-workflows/blob/master/.github/workflows/reusable_build.yml)
  (example of its usage on boilerplate [here](https://github.com/LedgerHQ/app-boilerplate/blob/master/.github/workflows/build_and_functional_tests.yml#L21-L25))

## Manifest

Some high-level application metadata must be declared in a `ledger_app.toml` manifest file, stored at the root of the
application repository.

The format of this manifest is described [here](https://github.com/LedgerHQ/ledgered/blob/master/doc/utils/manifest.md),
along with the tool which can be used to check the validity of the manifest.
You can also use [the manifest in Boilerplate](https://github.com/LedgerHQ/app-boilerplate/blob/master/ledger_app.toml)
as a living example

Most of our workflows (including the mandatory ones) use this manifest to infer environment data (like the SDK language,
or the build directory) so the validity of the manifest can be checked through these.

> **Warning:** Ledger will not deploy an application without a correct `ledger_app.toml` manifest.

## Tests

The application repository must have a `tests` folder that contains at least functional tests using the
[Speculos](../../references/tools#speculos) emulator. These tests must be triggered by the CI and running without error.

> **Warning:** Ledger will not deploy an application without tests or with failing tests.

For Python tests, Ledger provides the [`Ragger` library](https://github.com/ledgerhq/ragger), which can be easily
integrated with `Pytest` in the GitHub action with the [Ragger workflow](https://github.com/LedgerHQ/ledger-app-workflows/blob/master/.github/workflows/reusable_ragger_tests.yml)
(example of its usage on boilerplate [here](https://github.com/LedgerHQ/app-boilerplate/blob/master/.github/workflows/build_and_functional_tests.yml#L27-L32))

Unit tests are highly recommended, especially for critical functions like parsers - preferably relying on a standard framework like [cmocka](https://cmocka.org/). These tests must be automated using GitHub actions the [unit tests workflow](https://github.com/LedgerHQ/app-boilerplate/blob/master/.github/workflows/unit_tests.yml) of the Boilerplate application can act as a reference.

## Nice to have

On top of that, we also encourage the following practices:

- Linting helps improving code quality and ensuring consistent coding style and resolving basic coding errors.
- Developing a fuzzer (example of its usage on boilerplate [here](https://github.com/LedgerHQ/app-boilerplate/tree/master/fuzzing)).
- Integration with the Coverity static code analysis tool helps finding security issues and software defects.
