Make sure you comply with our coding guidelines
Always aim at 100% code coverage for your tests. Don't deliver your code unless it has at least 75% coverage. For a deeper explanation, check this blog post
Check your code with all the available tools: xref, dialyzer and elvis. You can use gadget but don't just rely on it. Use the tools in your local environment as well.
Exported functions in all your modules and the modules themselves, specially for open-source projects, should be documented using edoc comments.
All erlang projects, specially open-source libraries, should comply to these rules:
The project must use rebar3, for that, you will need a rebar.config
.
The following lines are an example of rebar.config
:
%% -*- mode: erlang;erlang-indent-level: 2;indent-tabs-mode: nil -*-
%% ex: ts=4 sw=4 ft=erlang et
%% == Erlang Compiler ==
%% Erlang compiler options
{erl_opts, [ warn_unused_vars
, warn_export_all
, warn_shadow_vars
, warn_unused_import
, warn_unused_function
, warn_bif_clash
, warn_unused_record
, warn_deprecated_function
, warn_obsolete_guard
, strict_validation
, warn_export_vars
, warn_exported_vars
, warn_missing_spec
, warn_untyped_record
, debug_info
]}.
{profiles, [
{test, [
{deps, [
{test_dep, {git, "https://github.com/inaka/test_dep.git", {tag, "0.0.1"}}}
]}
]},
{shell, [
{deps, [
%% Sync don't have releases so we use this stable version
{sync, {git, "https://github.com/rustyio/sync.git", {ref, "9c78e7b"}}}
]}
]}
]}.
%% == Common Test ==
{ct_compile_opts, [ warn_unused_vars
, warn_export_all
, warn_shadow_vars
, warn_unused_import
, warn_unused_function
, warn_bif_clash
, warn_unused_record
, warn_deprecated_function
, warn_obsolete_guard
, strict_validation
, warn_export_vars
, warn_exported_vars
, warn_missing_spec
, warn_untyped_record
, debug_info
]}.
{ct_opts, []}.
%% == Cover ==
{cover_enabled, true}.
{cover_opts, [verbose]}.
%% == Dependencies ==
{deps, [ sumo_db % latest version of package
, {zipper, "1.0.0"} % version 1.0.0 of a package
]}.
%% == Dialyzer ==
{dialyzer, [
{warnings, [ unmatched_returns
, error_handling
]},
{get_warnings, true},
{plt_apps, top_level_deps},
{plt_extra_apps, []},
{plt_location, local},
{base_plt_apps, [stdlib, kernel]},
{base_plt_location, global}
]}.
%% == Shell ==
{shell, [{apps, [sync]}]}.
For more information, you can check out the official documentation or the full example.
All deps used in the default
profile should use the packages in hex.pm. For deps used in other profiles, etc. it's a nice to have, but not mandatory.
The project should include an updated elvis.config
file. Both test
and src
folders and their subfolders must be checked.
The project must include meta testing, using katana-test.
To do that, add these lines to rebar.config
:
{profiles, [
{test, [
{deps, [
{katana_test, {git, "https://github.com/inaka/katana-test.git", {tag, "THE MOST RECENT VERSION"}}},
{mixer, {git, "https://github.com/inaka/mixer.git", {tag, "THE MOST RECENT VERSION"}}}
]}
]}
]}.
Then add a your_app_meta_SUITE.erl
file to the project's test
folder:
-module(your_app_meta_SUITE).
-include_lib("mixer/include/mixer.hrl").
-mixin([{ktn_meta_SUITE
, [ all/0
, xref/1
, dialyzer/1
, elvis/1
]
}]).
-export([init_per_suite/1]).
-type config() :: [{atom(), term()}].
-spec init_per_suite(config()) -> config().
init_per_suite(Config) -> [{application, your_app} | Config].
And now, before we can run the meta testing
suite, we need to generate the PLT
(required for Dialyzer test case) using the following command:
$ rebar3 dialyzer
Now you can run:
$ rebar3 ct
The project's app.src file should include the following tuples:
{maintainers,["Inaka"]},
{licenses,["Apache 2.0"]},
{links,[ {"Github", "https://github.com/inaka/your_app"},
{"Docs", "http://inaka.github.io/your_app/"}, % Unless you publish the docs directly on hex.pm
{"Blog", "http://inaka.net/blog/…"}, % If there is one
{"Example", "https://github.com/inaka/your_app/tree/master/example"} % If there is one
]},
{build_tools,["erlang.mk"]}
We use rebar3 & relx.
To generate the release you have to run:
$ rebar3 release
- Increase the version number inside the project's
*.app.src
file. - In the project's root directory, execute the script:
github_changelog_generator -t [YOUR_ACCESS_TOKEN] --future-release [NAME OF FUTURE RELEASE]
.- If you don't have a GitHub access token already, create a new one.
- Commit those changes and create a pull request to get them merged into
master
. - Create the new release in Github (this automatically creates the tag).
- To do this go to the project's home page,
Releases
and press theDraft a new release
button. - Use
[NAME OF FUTURE RELEASE]
as its name. - Add
To see what's new check the [CHANGELOG](CHANGELOG.md)
as the change's description.
- To do this go to the project's home page,
- Optionally, publish the project to hex.pm using
hexer
- 💥