Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Project best practices" page #1760

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
9 changes: 9 additions & 0 deletions docs/open-source/_toc.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@
"url": "https://github.com/Qiskit/qiskit/blob/main/MAINTAINING.md"
}
]
},
{
"title": "Creating a Qiskit-based project",
frankharkins marked this conversation as resolved.
Show resolved Hide resolved
"children": [
{
"title": "Best practices for your project",
"url": "/open-source/best-practices"
}
]
}
]
}
132 changes: 132 additions & 0 deletions docs/open-source/best-practices.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
---
title: Project setup and best practices
description: Testing, packaging, and code quality best practices for your Python project.
frankharkins marked this conversation as resolved.
Show resolved Hide resolved
---

# Best practices for your project

If you have an idea for a Qiskit-based project, you'll often want to share it
with the community. Putting your code online is a good start, but if a user
can't work out how to install or use your project, they'll give up and move on.
This page covers licensing, packaging, testing, and documenting your project,
all of which improve your users' experience. If you're releasing research code,
following best practices will also help others reproduce your results.

Once you've polished it up, consider adding your project to the [Qiskit
frankharkins marked this conversation as resolved.
Show resolved Hide resolved
ecosystem](https://www.ibm.com/quantum/ecosystem).

## GitHub

Most Qiskit projects are hosted on [GitHub](https://github.com/), a source-code
hosting platform. GitHub is based on [Git](https://git-scm.com/) (a version
control system) and provides a large set of tools to help collaborate on your
project and keep it to a high quality. See [Github
frankharkins marked this conversation as resolved.
Show resolved Hide resolved
skills](https://skills.github.com/) to get up to speed on GitHub quickly.

Some key features are:

* **Issues and Pull requests**
frankharkins marked this conversation as resolved.
Show resolved Hide resolved

Users can use GitHub to report bugs in your project or request changes to it.
Your team and external contributors can use pull requests to propose and
review changes to your project's code.

If you want to accept contributions from others, make sure to add a
[contributing
guide](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/setting-guidelines-for-repository-contributors)
and a [code of
conduct](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-code-of-conduct-to-your-project).

* **GitHub actions**
frankharkins marked this conversation as resolved.
Show resolved Hide resolved

Copy link
Collaborator

@Eric-Arellano Eric-Arellano Aug 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Software projects benefit from using continuous integration (CI) and continuous deployment (CD):
* [Continuous integration](https://www.atlassian.com/continuous-delivery/continuous-integration): automating the integration of changes to your code, including through the use of automated tests to ensure your changes do not break the project.
* [Continuous deployment](https://www.ibm.com/topics/continuous-deployment): automation of your deployment/release process. Often, continuous deployment can be semi-automated, such as requiring a human to initiate the deployment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good idea to name-drop CI/CD so users can read about it more, but given the target audience, I think it's better as a "further reading" link at the end of the paragraph. Added in a7d02c7.

This feature runs scripts when certain events happen in your GitHub repo. For
frankharkins marked this conversation as resolved.
Show resolved Hide resolved
example, you can run your [test suite](#test-your-project) when you push new
code or automatically [publishing your package](#package-your-project) when
frankharkins marked this conversation as resolved.
Show resolved Hide resolved
you tag a commit.

* **Security features**

GitHub supports features to keep your projects secure. These include:

* [Dependabot](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates)
– a tool to automatically update your dependencies.
* [Trusted publishing to PyPI](https://docs.pypi.org/trusted-publishers/) –
to reduce the risk of a malicious actor gaining control of your package.
* [Branch
protection](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches)
– to make sure code meets some criteria before being pushed to certain
branches.

The rest of this page will assume you have your project hosted on GitHub.
frankharkins marked this conversation as resolved.
Show resolved Hide resolved

## Choose a license

If you want others to use your project, you *must* choose an appropriate
license. Otherwise, your grant no permission for others to use it. Most
projects in the [Qiskit ecosystem](https://www.ibm.com/quantum/ecosystem) use
the Apache 2.0 or MIT licenses. Visit GitHub's
[choosealicense.com](https://choosealicense.com) to decide which license is
best for you.
frankharkins marked this conversation as resolved.
Show resolved Hide resolved

Add your license to the top level of your repository in a text file named
`LICENSE`. When you create a new repository, GitHub will give you the option to
automatically add a standard license.

## Dependency management

If you don't clearly specify your project's dependencies, users (including your
frankharkins marked this conversation as resolved.
Show resolved Hide resolved
future self) will struggle to install and use it.

The simplest way to list your requirements is to put the Python version you're
using in your `README` and include a
[`requirements.txt`](https://pip.pypa.io/en/stable/reference/requirements-file-format/)
file in your repository. However, this means you must manually identify your
requirements and keep the file in sync.

Tools such as [Poetry](https://python-poetry.org/) solve this problem by
managing dependencies for you, which means they can keep track of everything
you've installed. Installing a dependency through Poetry will add it to a
"lock" file, which keeps track of the exact versions of each package you have
installed. Users can use the lockfile to replicate your environment.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The simplest way to list your requirements is to put the Python version you're
using in your `README` and include a
[`requirements.txt`](https://pip.pypa.io/en/stable/reference/requirements-file-format/)
file in your repository. However, this means you must manually identify your
requirements and keep the file in sync.
Tools such as [Poetry](https://python-poetry.org/) solve this problem by
managing dependencies for you, which means they can keep track of everything
you've installed. Installing a dependency through Poetry will add it to a
"lock" file, which keeps track of the exact versions of each package you have
installed. Users can use the lockfile to replicate your environment.
Traditionally, many Python projects use a `requirements.txt` file to list the project's dependencies.
You may also see `requirements-dev.txt` to list dependencies only used for contributing to
the project, such as linters or test runners. This approach can be fine, but it has two issues:
1) no "lockfiles", and 2) you still need to set up metadata about your project.
Instead of the traditional requirements.txt approach, build tools such as [Poetry](https://python-poetry.org/) improve dependency management. Poetry also ensures that you properly set up metadata for your project,
such as which Python versions you support; this metadata is necessary to
[package your project](#package-your-project).
Installing a dependency through Poetry will add it to a "lockfile",
which keeps track of the exact versions of each package you have
installed. Lockfiles are crucial for
["supply chain security"](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-supply-chain-security).
Lockfiles also ensure that your project will not break overnight due to new releases of dependencies
breaking your project; with a lockfile, your dependencies will only change when you intentionally upgrade.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Eric-Arellano Is it important to put "supply chain security" in quotes? I'd leave them off unless it's confusing otherwise.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've incorporated this into f6977d8. I've left out the security bit as most projects are run-once programs for a specific experiment.


See [Poetry: Basic usage](https://python-poetry.org/docs/basic-usage/) to set
up your project with Poetry.

## Package your project

Consider [packaging your Python
project](https://packaging.python.org/en/latest/tutorials/packaging-projects/)
to make it easy for others to install and use. You should also consider
uploading your package to [PyPI](https://pypi.org/) so it can be installed
through `pip`.

If your project is a transpiler plugin, see [Create a transpiler
plugin](/guides/create-transpiler-plugin) to integrate correctly with Qiskit's
transpiler. This makes it easy for users to incorporate your plugin into their
Qiskit code.

## Test your project

Tests are small functions you'll write to make sure your code is working
correctly. A good test suite makes working on your code easier; if the tests
pass, your code works. This means you can be confident you haven't broken
anything when refactoring or adding new features. Seeing tests in a project's
repository gives users more confidence in the stability of the project.

The two most popular testing frameworks in Python are:
* [`pytest`](https://docs.pytest.org/en/stable/)
* Python's built-in [`unittest`](https://docs.python.org/3/library/unittest.html)

You can also consider using [`tox`](https://tox.wiki/en/4.18.0/) to test your
project against different versions of Python.
frankharkins marked this conversation as resolved.
Show resolved Hide resolved

## Code quality tools

A linter is a tool that detects (and sometimes corrects) common problems in
your code. A popular linter for Python is
[`ruff`](https://docs.astral.sh/ruff/). Other popular tools include
[`mypy`](https://www.mypy-lang.org/) for type-checking, and
[`bandit`](https://bandit.readthedocs.io/en/latest/) for security scanning.
frankharkins marked this conversation as resolved.
Show resolved Hide resolved

Once you've set your tools up, you can use a [GitHub action](#github) to make
frankharkins marked this conversation as resolved.
Show resolved Hide resolved
sure all code pushed to your repository has been linted.
frankharkins marked this conversation as resolved.
Show resolved Hide resolved