A detailed guide to how to contribute to Parsons, for those who have never contributed to an open source project before - or who need a refresher!
The guide covers most of what you need to know to make contributions to Parsons. It does not assume any previous experience contributing to open source software. Please let us know if you spot mistakes or have questions!
A recorded training which covers much of this guide can be found here.
Please come join us in the Parsons Slack!
First, we really want to meet you. The Parsons community is just as focused on building skills and relationships in the community as it is on building Parsons itself. We would genuinely love to get to know you.
Second, you will probably get stuck somewhere in the process of contributing. While you can also ask for help with a specific issue by posting in the issue tracker, a quicker and easier way to get advice is to post to the #getting-help or #contrib channel in Slack.
To join the slack, email [email protected].
This guide focuses on making contributions through changes to the repository but there are many other valuable ways to contribute. Kinds of contribution include:
One of the best ways to help Parsons is to point out how it could be better! We very much need your help to know what we need to improve.
You can tell us what you need by submitting an issue to the issue tracker. We now have issue templates that walk you through the information that will help us respond to your issue. If there’s anything confusing, let us know!
You can also raise questions or issues in the Slack. Not every request fits into a Github issue! Feel free to be ambitious in your requests, or to raise concerns that are too vague to be immediately tackled, like, “I just can’t figure out how to use Parsons in my work.” Sometimes you don’t know exactly what’s not working for you, and that’s okay! That’s still useful information for us.
Teaching and mentoring others can be as simple as responding to questions in Slack when you feel you have something to say, or it can be more involved. For instance, several of our community members have started leading trainings. (This is often as volunteers, but sometimes can be paid.) If you are interested in creating and/or leading trainings, we can help prepare you.
Writing or updating documentation such as guides is another very welcome form of teaching. Or, you can contribute an example to the use case library. This is a library of real world examples of people using Parsons. They each come with a sample script that people can adapt for their needs.
We want to get the word out about Parsons—what it is, and how it can be useful. Community members can contribute to these efforts by:
Blogging or sharing on social media about how they use Parsons, or talking at community events about it
Sharing Parsons events and trainings (which are almost always free and open to the public) with their workplace
Suggesting other organizations we can partner with, for example to create new connectors (like the ActBlue and TargetSmart teams hae), to run trainings (like we’re doing with Generation Data, DigiDems, and more) or other potential collaborations
If you’re new to contributing to Parsons, you’re probably not ready to become a maintainer, but you can start doing some of the individual tasks that maintainers do. These include:
Responding to new issues. We try to quickly respond to new issues in the issue tracker, so people know that someone is listening. Sometimes we need to ask people for more information so that we know what issue they’re actually having.
Reproducing bugs. When people report problems with Parsons, it’s helpful to double-check that it’s an issue for more than just them. We do this by trying to reproduce the bug. This can be done by someone other than the person who eventually fixes it!
Reviewing pull requests. Every pull request is reviewed by at least one other person. They go through the contribution and make sure it meets our code conventions, has tests and documentation (if needed), and just generally does what it says it does. While you may not be able to approve a PR, your review is still very valuable!
Cleaning up old issues. Sometimes issues get fixed by pull requests, but never closed, or the issue reported is no longer relevant. If you think an issue ought to be closed, please comment and say so—you’re probably right!
Changes to the codebase, as well as to our version-controlled documentation, require updating the repository. That’s what the rest of this guide focuses on. However “changing the repository” covers a lot of different tasks! These include:
Fixing a bug that’s been reported
Updating an existing connector
We’re happy to help you pick a task to work on if you want to ask for advice in #contrib. But it’s also useful to be able to look for tasks in the issue tracker. Here are a few labels that might be particularly useful for you to filter on:
Good first issue. These are tasks that someone thought might be a good task for someone relatively new to the project. Note, though, that sometimes people are wrong about that! If you’re struggling with something labeled ‘good first issue’ it’s not your fault! Let us know so that we can (a) help you better and (b) maybe relabel it.
Documentation. Gets you only documentation tasks.
New connector. Gets you requests for new connectors.
Connector update. Gets you requests to update existing connectors.
You can also use the search function to find requests related to a particular connector. For example, maybe you’re more familiar with NGPVAN and want to focus on requests related to that.
One thing to pay attention to with issues in the tracker is assignees. If a person has been assigned to a task, that means it’s not open for other people to work on. (If they were assigned more than a month or so ago, and the issue is still open, it’s not rude to ask if they’re still working on it.) When you want to work on a task, we can assign it to you.
So you’ve picked a task. Great!
For tasks that involve a particular connector, you may want to use a test account or “sandbox”. This may be necessary to reproduce the bug, to explore potential causes, and to check that your fix works.
The maintainers have sandbox accounts set up for about half a dozen connectors, and we can share those with you. There’s several other connectors that allow you to create test accounts for free. You can learn more about them at this link.
Please reach out even if the connector you want to work with isn’t listed. We may be able to find a workaround.
The rest of this guide assumes some familiarity with the command line. If you’re new to the command line or want a refresher, check out our command line tips.
Go to the Parsons Github repository and click the “Fork” button in the right-hand corner. This will make a copy of the repository under your account.
Then, clone your copy of the repository to your computer. You can do this by looking for the green ‘code’ button on your fork’s Github page. Copy the URL (you probably want the https:
url, not the ssh:
url, unless you have ssh set up for Github). Go to the command line and, wherever you want the repository to be, type in git clone
and then the url. The command should look like:
git clone https://github.com/$your-u/parsons.git
This will copy the repository to your computer.
Next we need to set up a virtual environment. If you’ve nevered used virtual environments before, we can install the tools we need via the instructions in the installation guide.
If you’ve used virtual environments on your machine before, we don’t need to install anything. We can just make and activate the environments via the command line:
Windows
Create a virtual environment for Parsons, by executing: mkvirtualenv parsons
Activate this virtual environment for use by executing: workon parsons
Mac/Linux with Python 3.4+
Create a virtual environment: python -m venv $path_to_your_env/parsons
Activate the virtual environment: source parsons/bin/activate
Mac/Linux with Python < 3.4
Create a virtual environment: virtualenv $path_to_your_env/$your_env_name
Activate the virtual environment: source parsons/bin/activate
Once we’ve made and activated our virtual environments, we need to install Parsons’s dependencies. To do this, use the following command:
pip install -r requirements.txt
Those are the dependencies for using Parsons. Additionally, we’ll want to add the dependencies for developing Parsons:
pip install -r requirements-dev.txt
Once you’ve finished setting up Parsons, go ahead and run the tests. These should all pass—if they don’t, please ask for help in the Slack!. It’s important to do this before you’ve made any changes, so that you know that any failures that happen after you make changes are caused by those changes. Otherwise, they could be due to a problem with setup!
To run all the entire suite of unit tests, execute the following command:
pytest -rf test/
Once the pytest tool has finished running all of the tests, it will output details around any errors or test failures it encountered. If no failures are identified, then you are good to go!
Note: Some tests are written to call out to external API’s, and will be skipped as part of standard unit testing. This is expected.
We also need to make sure your code is linted. “Linting” is a jargony term that means “going through the code and making sure it’s all formatted the same way”.
We use flake8 and Black to format our code. To lint your code, execute the following commands:
To lint the code, execute the following command:
flake8 --max-line-length=100 --extend-ignore=E203,W503 parsons
black --check parsons/ test/ useful_resources/
Because you haven’t made any changes yet, the linter like the tests should automatically pass.
You’re now ready to make your changes.
Optionally, you can choose to do your work on a “branch”. This is helpful so you can work on multiple things at once, each on its own branch. It also helps avoid merge conflicts long term.
To make a new branch, type: git checkout -b your-branch-name
(This is actually a combination of two commands, git branch
aka “make a branch” and git checkout branch-name
, aka “switch to using the branch with name branch-name”.)
To switch to an existing branch, including the default branch (“main”), use: git checkout branch-name
Note that when using an existing branch, we don’t use the -b flag.
Go ahead and use your code editor to make whatever changes you need to make. What exactly you do will depend on what task you’re working on! We often recommend starting with a small documentation change, so you can focus on all these steps we’re teaching you about, but you don’t have to!
If you are making code changes, please consult our coding conventions for extra guidance.
Once you’re done making changes, re-run the tests + linter using the instructions from the earlier step.
If your changes introduce new errors in the test suites, or style issues that need to be linted, now is the time to do so. I often need to google error messages or linting codes to understand what the results are telling me. That’s totally normal. Feel free to ask for help in the Slack with debugging errors.
If you’ve made a documentation change, you’ll want to re-build the docs and visually inspect them.
To do this, change into the docs folder with the command cd docs/
You’ll need to install an additional set of dependencies with the command: pip install -r requirements.txt
You can then re-build the docs with the command make html
.
Finally, you can go into your browser and open the files generated in /your-repo-name/docs/html
If you don’t see your changes, one common problem is accidentally making your documentation edits in the html files instead of the source files. The source files all have the extension .rst. When you run the ‘make html’ command, the html files are automatically generated from the source files. If your edits were in the html files, they’re automatically overwritten. Always edit in the .rst files!
Once you’re finished with your changes, and you’ve tested and checked them, you want to save them in version control. This is a completely different thing than “saving” the files through your code editor. You will need to do both.
First, get a list of all the files you changed with the command:
git status
This shows all changed files, excluding the special file types that are ignored by git (a list of all ignored files can be found in our .gitignore file).
You can add your files with the command git add
.
Add a single file: git add path_to_file/file_name
Add a folder and all contained files: git add folder_name
Add all changed files (as displayed by the git status
command): git add .
Every time you add a file, you’re telling git, “okay, here’s another thing to add to the changes going in this commit”. A commit is thus a chunk of changes. The version history of a project is a list of commits arranged in the order in which they were committed.
To commit your changes, type: git commit -m “Insert a brief description of your changes”
Commit messages are meant to be brief, although you can add more information to them as needed by leaving a blank space before the extra info, like so:
git commit -m "Insert a brief description of your changesHere's more information:
A
B
C"
Once your changes are committed, it’s time to send them back to the Parson’s repo!
Before you create your pull request, you need to determine if your commit contains breaking changes. Parsons waits to release all breaking changes at once in a major version release. We frequently release minor versions which do not contain breaking changes.
A breaking change is any modification to the code which would cause a Parsons user’s code to break when they installed the update. These are examples of breaking changes:
Deleting a function or class
Renaming a function or class
Changing the return type of a function
Renaming or changing the type of a parameter for a function
Modifying the behavior of a function so it returns a different value for the same inputs
A non-breaking change is any modification to the code that a Parsons user can ignore when they install the update, and their code will still work. These are examples of non-breaking changes:
Adding a new function or class
Adding a new parameter with a default value to a function
Adding a return to a function which previously had no return
You’ve added your changes to version control, but they’re still just on your local computer. The next step is to send them to your fork. You can do this with the command:
git push origin your-branch-name
When you go to your fork on Github, you should see an alert near the top of the page saying that there have been changes, and showing you a button to make a pull request.
It will look a little like this:
Go ahead and click the button to create the pull request. The next page should give you space to describe the contents of the pull request. This is often auto-filled with info from your commit messages. Feel free to add more info if you see fit.
When creating a pull request, you need to select a base branch. This is where you code will end up when it is merged. If your code does contain breaking changes, then you should select the “major release” branch as your base. If your code does not contain breaking changes, then you should select the “main” branch as your base. Most pull requests will use the “main” branch, but you should still follow the instructions to determine whether your code contains breaking changes.
Then click “create pull request”.
Success! You’ve created a pull request!
When you submit a Pull Request, some tests will automatically run. When they are running, they look kind of orange-y and say “Some checks haven’t completed yet”:
Once the tests finish running, they will appear in green (passing) or red (failing). If the tests are failing, you can investigate why by clicking the details button to the right:
Doing this will open up the CircleCI/continuous integration page:
You can click on the failing test (in this case “test”) to see the details of what went wrong:
In this particular case, we can see that most of the steps passed, but there was a problem with the linting. Opening up the linting tab allows us to see the particular thing that went wrong:
If you have trouble understanding why the tests are failing or how to fix them, please reach out for help!
Once your tests are passing, you’ll need to wait for review from a community member/maintainer. This can sometimes take a few days, so if you need a quick response please tell us so we can prioritize it. Feel free to follow up after a few days if no one has responded.
The review may require additional changes. To do this, you’ll want to take the following steps:
Make changes in your code editor
Test/lint/build docs as needed to check everything’s still working
Add + commit your changes
Push to your fork
When you push to your fork on the branch that generated the pull request, Github will automatically update the pull request with your changes.
Once your code is approved by at least one person with approval powers, it can be merged.
Occasionally there are merge conflicts that block this step. See “Resolving merge conflicts” below.
When the maintainer merges your code, you should get a notification saying so, and the pull request itself will turn from green to purple and say “merged”.
Congratulations, and thank you for your contribution!!!
Once you’ve made your first change, you can make subsequent changes with the following workflow:
Get the most recent version of Parsons from the move-coop repository
Make sure that tests + linting run fine
Check out a new feature-branch
Make your changes
Test + lint again
Submit a new pull request
You should be familiar with most of those steps, but we do need to do a little bit of additional setup. In order to get the most recent version of Parsons from the move-coop repository, we need to add it as a remote.
Setting your Git remotes only has to be done once (and I recommend you do it when you make your first contribution, although you don’t have to).
Remotes are links to other copies of the repository. You can check your remotes with the command git remote
You should have one remote, “origin”. This will be the default remote—when you don’t specify which remote you mean, it will use this origin. You can see what origin links to using git remote -v
(the -v stands for “verbose”). The origin should link to your fork of Parsons.
You can add move-coop’s Parsons repo to your remotes with the command:
git remote add move-coop https://github.com/move-coop/parsons.git
The git remote -v
command should now show your fork under “origin” and move-coop’s version under “move-coop”.
Make sure you’re on your main branch before pulling changes. Then run the following command:
git pull move-coop main
This gets move-coop’s version of main and applies all its updates to your local version of main. (Or rather, it applies it to whatever branch you’re on locally, which should be main.)
If there have been any changes since you first forked the repository, it should fetch and apply those changes. Otherwise, it will tell you that your version is up to date.
If you do all of your work on branches and not on main, you should not have any merge conflicts when you do this.
Once this is done, you’re ready to check out a new feature branch with git checkout -b new-feature-branch
. The new branch will have the same version history as your main and move-coop’s main.
Resolving merge conflicts is maybe the most annoying part of working with version control. It trips everyone up sometimes—even people like me who’ve been doing it for over a decade.
If you’re struggling to resolve a merge conflict, please reach out for help!
Github provides pretty good guidance on how to resolve merge conflicts via the command line.
Another common issue is when you’ve had a pull request open for a long time. If enough changes happen to the main repository, your pull request might be in conflict just because it contains out-of-date code. In that case, you’ll want to follow these instructions for rebasing your pull request.
Don’t forget to ask for help if you need it! Our biggest priority in the Parsons community is not writing code but learning from each other. :)