Contribute to development

This guide describes how to contribute a code change to Snapcraft.

It requires familiarity with Python, Git, and GitHub.

Set up your work environment

Snapcraft development and documentation use the same build and test environment. If you’ve already set up your local machine to document Snapcraft, skip to the next section.

For security, you must sign your commits. If you haven’t already, configure Git to sign with your GPG or SSH key.

Create a personal fork of the repository on GitHub.

Next, clone your fork onto your local machine:

If you authenticate your GitHub account with SSH, run:

git clone git@github.com:<username>/snapcraft --recurse-submodules
cd snapcraft
git remote add upstream git@github.com:canonical/snapcraft
git fetch upstream

If you don’t authenticate with SSH, clone with HTTPS instead:

git clone https://github.com/<username>/snapcraft --recurse-submodules
cd snapcraft
git remote add upstream https://github.com/canonical/snapcraft
git fetch upstream

Inside the project directory, set up the development environment:

make setup
make lint
make test-fast

If these commands complete without error, your environment is ready.

Choose a task

Every task must be tracked as a GitHub issue. If your task isn’t tracked, create an issue for it.

Tasks come in different sizes and complexity. It’s important to choose a task that you have the capacity to finish. It’s also important to check whether the task is already planned. You might save time and effort by checking for prior work.

Simple tasks

For obvious tasks that need no explanation, like fixing a lint failure, volunteer for its GitHub issue. A maintainer will review your request and assign it to you.

Complex tasks

For complex tasks, like a new module or class, propose your solution in its GitHub issue. Describe an implementation, tests, and documentation. If your plan is feasible, a Snapcraft maintainer will assign the issue to you.

For very complex tasks, like refactors, contact the team in the Snapcraft Matrix channel.

For tasks that require coordination with the Snap Store or snapd, create a post on the Snapcraft forum, which serves as a central point for all teams working on snaps.

Draft your work

Create a branch

Before you begin your work, sync your local copy of the Snapcraft code and create a new branch.

Always start by syncing against the branch and the dependencies you’re basing your changes on:

If you’re contributing to a current release, run:

git fetch upstream
git switch -c <new-branch-name> upstream/hotfix/<current-release>
make setup

If you’re contributing to multiple releases or the next major release, run:

git switch main
git pull upstream main
git switch -c <new-branch-name>
make setup

Format your branch name as <ticket-id>-<description>. For example, if you’re working on GitHub issue #235, and it’s about adding a string sanitizer, you’d name your branch issue-235-add-string-sanitizer.

Develop

Snapcraft has conventions for its code style and testing. They are detailed in the related links on this page. If you’re looking for a way to develop something that isn’t covered by a convention, explore the existing codebase.

The Snapcraft codebase is large. You might be tempted to tweak related behavior or fix tangential inconsistencies in addition to your task. Don’t. Stay focused on your task and keep its scope narrow.

Most development tasks involve adding or changing algorithms or business logic. The architecture, meaning the organization of the code and the design of its structures, changes much less often. If in your work you need to change structures or reorganize the code, consult the team first.

Snapcraft has 10-year long-term support (LTS) commitments. One of our most important reliability principles is that a snap on an LTS core, if unaltered, must rebuild without intervention for the duration of the LTS period. All changes you make to Snapcraft must be backward-compatible unless stated otherwise in the issue.

All nontrivial changes must be accompanied by new or updated tests. The Snapcraft test suite includes both pytest unit tests and Spread integration tests. When adding unit tests, follow the arrange-act-assert-cleanup pattern from pytest. Tests are rarely perfect on the first try. Additional tests can always be added during the review process.

Snapcraft is amenable to code generated with LLM assistance. Generated code takes less effort, but like all code it needs testing and careful review. An LLM doesn’t absolve you of responsibility – you are ultimately responsible for the code in your work.

Test

As you develop, test all your changes in the local test suite. If a test breaks, it usually means your code made a breaking change. Diagnose what went wrong and why, and iterate until it passes.

For low-complexity changes that require basic testing, run the fast suite, which takes a few seconds:

make test-fast

For complex work, run the full test suite, which takes several minutes:

make test

When iterating and testing, it’s a good practice to clean the local temporary files that the tests generate:

make clean

In rare instances, tests can fail in unpredictable ways, regardless of the state of your code. If that happens, delete your virtual environment and start over:

rm -rf .venv
make clean
make setup

Document your work

Add all changes and fixes to the upcoming release notes.

Small changes usually require updates to the pages that describe the feature’s behavior. Make any necessary changes to how-to guides and references that cover the feature.

Major changes require new documentation describing the feature’s usage and specifications. For example, if you implement a new CLI command, describe its usage in one of the how-to guides and add reference information for its options and flags.

The documentation contribution guide shows how to:

Commit

Register the changes to your branch with a Git commit:

git add -A
git commit

Format the commit message as a conventional commit. For example, a new feature would be written as:

feat: <description of new feature>

Keep the message short, at 80 characters or less, so other contributors and the project maintainers can see the gist of what you did.

Commit early and often. It’s normal to make multiple commits for a single piece of work, especially when you come back to review it later. It’s a good habit that keeps your changes safe.

Committing triggers the pre-commit hook, which runs autoformatters. If any files were autoformatted, re-add them and redo the commit.

Complex commits

It might be difficult to choose a conventional commit type for a commit message. It could mean that your change is too complex, and should be split into smaller commits. A commit shouldn’t, for example, refactor code and fix a bug.

In some cases, multiple types could be appropriate because of the nature of the commit. This happens often with thee test and docs types.

If you decide to make a complex commit, select the highest-ranked type that fits:

  • ci

  • build

  • feat

  • fix

  • perf

  • refactor

  • style

  • test

  • docs

  • chore

Review with the team

Send for review

When you’ve committed your draft and you’re ready to have it reviewed, push it to your fork:

git push -u origin <branch-name>

Then, open a pull request (PR) for it on GitHub. Give the PR a title using the same message format as the commit. If your branch has more than one commit, reuse the message from the first.

If you used an LLM to generate code, explain which parts are synthetic in the PR description.

Address quality concerns

Before the PR is merged, it must pass all automatic checks, and it needs separate approvals from two maintainers.

If there are any issues in your branch that your local testing didn’t catch, then the automatic checks will fail. To address these issues, review the logs in the failed checks. The error messages in the logs will have remedies and hints for what needs fixing.

When the maintainers review the PR, they may suggest improvements. Address them in follow-up commits to your branch, the same way you committed and pushed changes while drafting. If you feel a particular point should go in a different direction than what they suggest, discuss it with the maintainer in the PR. They’ll be happy to explore alternatives.

Wrap up the review

Once all suggestions are addressed, both maintainers will approve the PR. After the PR is approved, there may be a delay before merge. The maintainers might need time to coordinate the PR with other active developments.

After approval, don’t force-push to your branch. It’s difficult for the maintainers to see whether any additional changes mixed into the push.

Once the PR is merged, your work is complete.

Get help and support

Open source contribution can be difficult. Even the most experienced developers become tangled or have moments of uncertainty.

If you’re stuck, or need more information about a task, ask the issue creator or a maintainer. If you need hands-on help, ask in the Snapcraft Matrix channel.