Skip to main content

Fork and branch workflow

1

Fork the repository

Create your fork on GitHub:
https://github.com/Constellation-Labs/tessellation/fork
2

Clone and add the upstream remote

git clone https://github.com/<your-github-account>/tessellation
cd tessellation
git remote add upstream https://github.com/Constellation-Labs/tessellation
3

Create a feature branch

Create a branch for your work. Use a descriptive name, optionally prefixed with a GitHub issue number:
git checkout -b 747-update-contrib
4

Keep your branch in sync

Rebase against upstream/develop regularly to avoid merge conflicts:
git fetch upstream
git rebase upstream/develop
5

Run the linter before committing

Format your code with scalafmt and apply scalafix rules before every commit:
sbt runLinter
This auto-formats code and organizes imports. The CI pipeline enforces the same checks and will fail if formatting is not applied.
6

Push and open a pull request

Rebase with upstream one final time, then push your branch:
git push -u origin 747-update-contrib
Open a pull request from your fork via the GitHub UI.

Commit message format

Conventional Commits are required and enforced by commitlint using the conventional-changelog-conventionalcommits preset. Format:
type: description
Rules enforced by commitlint:
  • type must be lowercase
  • type must be one of the allowed values (see below)
  • description must not be empty and must not end with a period
  • description must not use sentence-case, start-case, pascal-case, or upper-case
  • Header line maximum length: 100 characters
  • Body lines maximum length: 100 characters
Allowed types:
TypeWhen to use
featA new feature
fixA bug fix
refactorCode change that is neither a feature nor a fix
testAdding or updating tests
docsDocumentation only changes
choreMaintenance tasks
buildChanges to build system or dependencies
ciCI configuration changes
perfPerformance improvements
styleFormatting changes (no logic change)
revertRevert a previous commit
Examples:
feat: add new validation endpoint
fix: resolve race condition in consensus
refactor: simplify block processing logic
test: add property-based tests for transaction validator
docs: update contributing guide

Code style

Code formatting is handled automatically by sbt runLinter, which runs both scalafmt and scalafix.
version=3.5.8
runner.dialect = scala213

preset = default
align.preset = some
maxColumn = 140
indent.defnSite = 2
indent.callSite = 2

rewrite.rules = [
  AvoidInfix
  RedundantBraces
  RedundantParens
  AsciiSortImports
  PreferCurlyFors
]
rules = [
    OrganizeImports,
    NoSetSum,
    NoSetMap,
    NoMapConcat
]
Imports are organized into groups: javax?, cats, scala, io.constellationnetwork, then everything else.
Always run sbt runLinter before pushing. The check-scala-code.yml CI workflow runs scalafixAll --check and scalafmtCheckAll and will fail the build if formatting or import ordering does not match.

How to add new features

The following guides map common extension tasks to the relevant files and modules. For full file-level details, see the Codebase Map.
  1. Define the type in modules/shared/src/main/scala/io/constellationnetwork/schema/
  2. Add Kryo and JSON serialization in shared/kryo/ and shared/json/
  3. Update validators in modules/node-shared/domain/transaction/
  4. Add processing logic in dag-l0/infrastructure/snapshot/
  1. Define the route in modules/{module}/http/routes/
  2. Wire it into modules/{module}/modules/HttpApi.scala
  3. If it is a P2P endpoint, add a client in http/p2p/clients/
  1. FSM state definitions live in node-shared/infrastructure/consensus/state/
  2. Phase logic is in node-shared/infrastructure/consensus/engine/
  3. Declarations are in node-shared/infrastructure/consensus/declaration.scala
  1. Extend CurrencyL0App or CurrencyL1App
  2. Override the relevant extension points: dataApplication, rewards, transactionValidator, or customArtifacts
  3. Use the sdk module as a dependency with provided scope for stable API access

Build docs developers (and LLMs) love