Habitica Wiki
Advertisement
Habitica Wiki

To contribute code to Habitica's habitica.com website and API, first follow the instructions in Setting up Habitica Locally. Once your local install is working, this page will give you information about how to proceed with making a change. You can refer back to this page each time you start a new change or when you run into trouble with your local install.

This page is not relevant for contributing to development for the mobile apps.

General Notes[]

  • You must also read Guidance for Blacksmiths.
  • Join the Aspiring Blacksmiths guild and read it every day while you are working on code for Habitica. Important announcements are made there. For example:
    • When Habitica's dependencies are updated, a post will advise you to run npm install (see "Updating Your Local Install" below for the full process).
    • When new environment variables are added to Habitica's server, a post will advise you to update your copy of config.json by comparing it to config.json.example
  • If you experience an error at any point in any of the instructions on this page, resolve that error before going further. Ask for help in the Aspiring Blacksmiths guild if necessary.
  • Some familiarity with `git` and GitHub is assumed here. Guidance for Blacksmiths contains links to generic documentation and links to relevant sections are presented below so that you can learn about any git commands that you don't understand.
  • If anything in this page seems incorrect or confusing, ask in Aspiring Blacksmiths. If you're certain something is incorrect, you're welcome to edit this page!
  • When you're looking for information related to a specific part of Habitica, go to the wiki page(s) for that topic and look to see if there's an "Information for Developers" section at the bottom. For more details about those sections and how to best use them, see "Information for Developers" Sections on General Wiki Pages in Guidance for Blacksmiths.

Updating Your Local Install[]

This section contains sub-sections for the following three situations and it is important that you follow the instructions below carefully for the situation that applies to you:

  • you created your local install before May 2018
  • you created your local install after May 2018 but before 15 July 2020
  • you created your local install after 15 July 2020 but you haven't updated it for a few days (also follow this section if you ever experience any problems with your local install before asking for help).

If your local install was made before May 2018:[]

  1. Delete the entire local install (i.e., delete the directory that you cloned the repository into).
  2. See the points in the next section about stopping or uninstalling MongoDB server - they apply to you as well.
  3. Go through the full installation process described in Setting up Habitica Locally.

It's recommended to also do that full deletion process if your install is more than a few months old and you don't have any incomplete code changes that you want to keep.

If your local install was made before 15 July 2020:[]

When you originally set up your local install, you manually installed a MongoDB server. It was separate from your Habitica local install but was used by your local install to store data. As of 15 July 2020 that separate MongoDB server is no longer used by your local install and if it is kept running, your local install won't work properly.

  1. If you have data in your Habitica MongoDB database that you need to keep (e.g., local user accounts with important tasks in them), export the data or save it in some other way. This old data will not be available through your local install from now on unless you import it or re-add it. Refer to online MongoDB instructions as needed. Note that it is not recommended to keep data from the old database unless the data is essential to you.
  2. Stop the MongoDB server using MongoDB's standard server stop command for your system.
  3. Optionally, you can uninstall the MongoDB server (it won't hurt if it remains installed). Don't uninstall it if you use it for any other projects!
  4. Follow the steps in the next section to update your local install. This will cause a new instance of MongoDB to be automatically installed within your Habitica directory.

NB the MongoDB change also changed the name of the database. Previously it was habitrpg, now it is habitica-dev. I.e., to gain access to the database's mongo shell, you type mongo habitica-dev

If your local install was made after 15 July 2020 but you haven't used it for a few days:[]

  1. Ensure that you are using exactly node 14 and npm 6. Refer to Setting up Habitica Locally if you need assistance with that. As of December 2020, node 12 will also work but it will stop working in the future so install node 14 when you can.
  2. If you have uncommitted changes, commit them or stash them.
  3. Checkout the develop branch and rebase it:
    1. git checkout develop
    2. git fetch upstream
    3. git rebase upstream/develop
  4. Compare your local config.json file with the config.json.example file and if there are any changes, apply them to config.json:
    diff config.json.example config.json
    cp config.json.example config.json
    It is permitted to have differences between the two files (for example, you might need to use a different port number than the default one) but you must always fully understand the reasons for the differences and document them in your own notes for your own future reference. If you are not sure why your config.json file is different, overwrite it with config.json.example.
  5. Update any node packages by running npm install. Carefully review the output for errors and resolve the errors before continuing. You might find that running npm ci instead of npm install helps if npm install gives errors.
  6. Start the local server using the instructions in "Start the Habitica Web Server" section in Setting up Habitica Locally and test that the website works.
  7. If you already have a branch that you have been using to make changes:
    1. Checkout the branch: git checkout name-of-your-branch
      Tip: git checkout - (note the hyphen) will switch between your current branch and the previous one you were using.
    2. Use git diff to examine the differences between your branch and the develop branch:
      git diff upstream/develop
      If there are differences that are not from changes you have made to your branch, decide whether you should bring those changes into your branch now or later. If you are not sure, do it now. To apply differences:
      1. git fetch upstream
      2. git merge upstream/develop
      3. Fix any merge conflicts that might exist.
      4. Reapply changes that you stashed, if any.

Creating a Change[]

When you're ready to start making a change to Habitica's website or API, follow this process:

  1. If you have not yet decided what change to make, refer to "Ways to Help" in Guidance for Blacksmiths.
  2. If your change will fix or partially fix an issue in GitHub, or if it is a change you've thought up yourself, it is important that you follow all of the steps listed in "Ways to Help" in Guidance for Blacksmiths. Not following those steps may mean that your change is not accepted and your time may have been wasted. Because of that, it's recommended that you don't proceed further with the steps below until you've been advised that you're welcome to proceed, as described in the "Ways to Help" section.
  3. Create a new branch in your local install for this change, choosing any name you wish for your branch. Don't do any development in the develop branch because it will cause problems for you as soon as you want to work on more than one change at once. To create a new branch:
    1. git fetch upstream
    2. git checkout -b name-of-your-branch upstream/develop
  4. Start coding!
  5. To find information about where certain data is stored in API's schema:
    • read the rest of this page (e.g., you might find it in the section about creating test data),
    • read the Application Programming Interface page, especially its Tips section,
    • search in the website/server/models directory and its subdirectories in the code base,
    • if you still can't find it, ask for help in the Aspiring Blacksmiths guild.
  6. When you have progressed far enough that you want to make a commit, give it a meaningful name that describes the code changes being made in that specific commit. This will help admins and other developers review your work. Make as many commits as you feel necessary - you do not need to limit yourself to one commit per change.
    • Remember that if you are adding new files to the repository, you will have to use git add on those files before you commit them.
  7. If you want to move to a different branch before you are ready to commit (e.g., to test unmodified code in the develop branch), you can stash your changes.

Finding the Location of the Code to Change[]

Habitica's repository contains a lot of code in many directories so finding the correct files to modify can seem overwhelming. However, there's a (usually) easy way to work out where to start if you're changing an existing feature to the website or API. This might also help if you're adding a new feature in the same place as an existing one.

Note that the sample commands below worked as described at the time of writing. Future changes in Habitica's code might make them work differently or not at all but they are just examples to show how to use the process. The process will work even if the sample commands don't.

Look at the existing feature on the website and work out if it can be best described by some unique text that appears in the feature (e.g., a section heading or an explanatory sentence or text that appears on hover) or with an image (e.g., an icon or image that you would click on to use the feature).

If the existing feature contains some unique text (e.g., "already in a party"):

  1. Copy the exact text to your clipboard (or be prepared to type it accurately).
  2. Go to your local install and cd into the top-level directory (that's the directory where config.json is).
  3. Use git grep to search for the text in the code base. For example:
    git grep "already in a party"
  4. Examine the output. You will usually see the locales strings for that text. For example:
    website/common/locales/en/groups.json:250: "userAlreadyInAParty": "UserID: <%= userId %>, User \"<%= username %>\" already in a party. ",
    If it shows you that the text is hard-coded directly into program code, skip the next step.
  5. Take the key from the locales text ("userAlreadyInAParty") and grep to find where it's used:
    git grep userAlreadyInAParty
  6. You'll now be looking at the place in Habitica's code that might be where you need to make changes, or that at least will show you certain code (e.g., a function name) that you can put into another git grep command.
  7. Keep drilling down through the code with git grep commands until you've found the right place(s) to make your change. If you're on a Unix-like system or have an appropriate Windows program installed, you can use regular grep to filter the results of git grep. For example, to ignore locales files after you've found the correct string key:
    git grep userAlreadyInAParty | grep -v "/locales/"

If the existing feature contains an image rather than unique text, first read through the above process to understand the basics of searching through the code then:

  1. Right-click on the image and do "inspect element" (or your browser's equivalent command). That will show you the HTML code that creates the image.
  2. How you proceed depends on the exact situation but it's likely that the HTML code you'll see some HTML/CSS class names. Some class names will look generic and so will be less likely to help you find the required code; others might be more specific and so will probably direct you to the correct piece of code. Pick one of those specific class names.
  3. Follow the above process but using the class name in your first git grep command.

Testing your Change Manually[]

Before submitting your code for review, log in to the website in your local install and test your feature or bug fix thoroughly.

  • Refer to the "Start the Habitica Web Server" section in Setting up Habitica Locally for how to get the website working locally.
  • If you need to make code changes after starting the local site, refer to "Restarting the Local Web Server" below.
  • Test all aspects of your new code in the website (and/or by using direct API commands if you have modified the API).
  • Also test any existing features that are related to the code you've changed to ensure that they are still working as intended. For example, if you are modifying the task editing screen, you might want to check that editing challenge tasks and group plan tasks has not been affected inappropriately.
  • See the "Debug Menu and Admin Panel" section below for easy ways to set up your test accounts.

Debug Menu and Admin Panel[]

Debug Menu

In the footer of your local install's website, there is a debug menu with several useful tools for quickly modifying a test account (giving Gems, adding Quest progress, etc). This can make testing your code faster and more efficient. Experiment with the menu items to find out what each one does.

One of the options in the debug menu (not currently shown in the screenshot to the right) is "Make Admin", which will convert the user account to an admin user. After you click that option, reload the website, then go to Help > Admin Panel, which is a feature that is not available to non-admin accounts. The Admin Panel will let you change any account in multiple ways (e.g., adding or removing Inventory items, awarding Contributor Tiers, etc). This is a useful tool for setting up user accounts in ways that allow you to test various features.

The Hall of Heroes also contains admin-only features but they are not as good as the Admin Panel and will be removed in June 2022.

Restarting the Local Web Server[]

The commands listed in the "Start the Habitica Web Server" section in Setting up Habitica Locally will start a web server that uses the current code in your local install. When you change that code, the local website needs to pick up the new code. How that happens depends on whether you use Docker or any other type of local install.

Restarting the Local Web Server on any System except Docker[]

If you're not using Docker, you can make the local website use your new code by manually stopping the npm processes with Ctrl-C and restarting them as described in the "Start the Habitica Web Server" section in Setting up Habitica Locally.

However to make restarting more convenient, the local Habitica web server uses nodemon. It watches the source code in your local copy of the repository and automatically restarts the web server when the code changes. This means that you usually don't need to do Ctrl-C and a restart.

You can also force nodemon to restart the web server by typing rs and then hitting Enter in the same terminal that npm start is already running in. As a reminder of that, if you examine the output of npm start), you'll see this explanation:

[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node ./website/src/server.js`

However, if you find that the local website does not seem to be using your latest code changes, it is advisable to use Ctrl-C and restart the processes.

Restarting the Local Web Server on Docker[]

If you are using Docker as described in Setting up Habitica Locally on Docker, when you make changes to the code in the repository on your host machine, the changes will not automatically appear in the local Habitica web server. Using rs or Ctrl-C and npm start will not help. Instead you need to run this command to update the containers:

docker-compose -f docker-compose.dev.yml up -d --build

For details about why, see Pull Request #11518.

Testing API Documentation Changes[]

If you will be modifying the API documentation, you will want to access the local copy to confirm that your changes display correctly. Run npm run apidoc to compile them once and view them at http://localhost:3000/apidoc/ (replace 3000 with the appropriate number if your local install uses a different port, but note that apidoc is served from the server so you need to use server port instead of client port 8080, and for this reason the link in the website footer does not work in local dev environment).

If you would like the documentation to be automatically recompiled every time you save a change to the API's files, run npm install -g gulp-cli using sudo on a Unix/Linux/MacOS host or Administrator on a Windows host, and then in each editing session run gulp apidoc:watch

Creating Test Data[]

Manual tests of your changes are likely to require user accounts or guilds with specific characteristics.

Many changes to user accounts can be made using the Debug menu in the footer of your test website (see above), including making the account an admin, which then gives you access other options for changing accounts.

Some changes to users or guilds can only be made by modifying the documents in the users and groups collections in the database. Below are some examples. If you are not familiar with MongoDB, see the section of that name in Guidance for Blacksmiths (e.g., for information about using its CLI or GUI tools).

To add a one-month gift Subscription to a user, where the user's User ID is 12345678-b5b9-4bb4-8b82-123456789abc:

> db.users.update({_id: '12345678-b5b9-4bb4-8b82-123456789abc'}, {$set: {
    'purchased.plan': {
            'owner': "12345678-b5b9-4bb4-8b82-123456789abc",
            "dateCreated"    : new Date("2017-12-25T01:00:00.000Z"),
            "dateUpdated"    : new Date("2017-12-25T00:00:00.000Z"),
            "dateTerminated" : null, // or you can add a date using the same format as above if needed for your testing
            "gemsBought" : 0,
            "extraMonths" : 0,
            "quantity" : 1,
            "mysteryItems" : [ ],
            "consecutive" : {
                "count" : 1, "offset":0,  "gemCapExtra":0,  "trinkets":0,
            },
            "customerId" : "Gift",
    },
}})

To add Mystery Items to the gift box for a user, refer to the Information for Developers section in Mystery Item.

To add a Group Plan to a group (guild or party), where the group's ID is abcdef12-b5b9-4bb4-8b82-abcdef123456 and the group leader's User ID is 12345678-b5b9-4bb4-8b82-123456789abc:

> db.groups.update({_id: 'abcdef12-b5b9-4bb4-8b82-abcdef123456'}, {$set: {
        "purchased.plan": {
            "owner": "12345678-b5b9-4bb4-8b82-123456789abc",
            "dateCreated": "2017-12-25T01:00:00.000Z",
            "dateUpdated": "2017-12-25T01:00:00.000Z",
            "dateTerminated": null,
            "consecutive": {
                "trinkets": 0, "gemCapExtra": 0, "offset": 0, "count": 0
            },
            "mysteryItems": [],
            "gemsBought": 0,
            "extraMonths": 0,
            "quantity": 3,
            "customerId": "group-unlimited",
            "paymentMethod": "Group Unlimited",
            "planId": "group_monthly",
            "subscriptionId": ""
        }
}})

To add a free subscription from a Group Plan to a user, where the user's User ID is 12345678-b5b9-4bb4-8b82-123456789abc:

> db.users.update({_id: '12345678-b5b9-4bb4-8b82-123456789abc'}, {$set: {
    'purchased.plan': {
            'owner': "12345678-b5b9-4bb4-8b82-123456789abc",
            "dateCreated"    : new Date("2017-12-25T01:00:00.000Z"),
            "dateUpdated"    : new Date("2017-12-25T00:00:00.000Z"),
            "dateTerminated" : null, // or you can add a date using the same format as above if needed for your testing
            "gemsBought" : 0,
            "extraMonths" : 0,
            "quantity" : 1,
            "mysteryItems" : [ ],
            "consecutive" : {
                "count" : 1, "offset":0,  "gemCapExtra":0,  "trinkets":0,
            },
            "lastBillingDate": null,
            "paymentMethod": "Group Plan",
            "customerId": "group-plan",
            "planId": "group_plan_auto",
            "nextPaymentProcessing": null,
            "nextBillingDate": null,
            "additionalData": null,
	},
}})

Creating and Running Automated Tests[]

Habitica has a test suite in the top-level test directory. When Habitica's admins deploy a new version of the website to production, the deployment process runs the tests and refuses to deploy the site if there are any failed tests.

Before you submit your code for review, ideally you should ensure that all existing tests pass. You should also create new tests for every aspect of your feature or bug fix and ensure your tests pass.

However, sometimes it is not possible to run the full test suite locally because the tests time out or fail for reasons unrelated to your code. If you are unable to run the existing tests or unsure which new tests you should create, you can submit the code you've written so far for review in a pull request (as described in a section below) and ask for advice about tests.

When you create a pull request, the full test suite is automatically run against it. If any tests fail, the results will be reported in your pull request with a link to the test output. This is a good alternative for testing your code if running the full test suite times out locally. Sometimes even the automatic tests time out or report errors due to temporary problems, in which case admins can restart the test suite.

If any failed tests are caused by your code, you will need to modify your code before your pull request can be merged.

The first steps in running tests locally depend on whether you are using Docker or not:

  • If you are not using Docker:
    1. Stop any npm process such as npm start or any process that is already running tests (don't try to run two test processes at the same time).
    2. Run killall node. This step is not always necessary, but if you have recently run tests and try to run them again, you might see errors such as "before all" hook: callee$2$0 and Error: connect ECONNREFUSED. Killing all node processes will prevent those errors.
  • If you are using Docker:
    1. Note that this process may no longer work after Habitica's MongoDB changes on 15 July 2020. Post to the Aspiring Blacksmiths guild if you need help.
    2. Do not stop the npm processes that are running in your existing containers.
    3. Attach to the habitrpg_client container for test execution by running:
      docker-compose exec client sh
    4. Observe that you now have a bash shell into which you can type commands. The bash prompt will look like this:
      #
    5. Optionally, you might want to create a new container for test execution:
      docker run --name habitica_test -it --volume `pwd`:/usr/src/habitrpg habitica_client gulp test:${your_test_category}:watch
      That command above creates a container called habitica_test, which you can stop and start for running tests.

You are now ready to run one or more of the tests.

Running the Full Test Suite[]

To run the full test suite:

  1. Change directory into the top-level directory of your local install.
  2. In one command prompt or terminal run npm run mongo:dev and leave it running. If it is already running from previous development or testing, you don't need to stop and restart it.
  3. In a second command prompt or terminal run npm run test and fix any errors that are reported.
  4. If you suspect that errors might not be caused by your code, investigate that by testing in the develop branch:
    1. Commit or stash your changes.
    2. git checkout develop
    3. npm run test
    4. Move back to your own branch with git checkout -
  5. Create new tests for all parts of your new or modified code and ensure that they all pass.

Running a Subset of the Automated Tests[]

The full npm run test command is equivalent to running, in order:

  • npm run lint (lint tests, which help to ensure code quality and consistency)
  • npm run test:api:unit (unit tests)
  • npm run test:api-v3:integration (integration tests for API v3)
  • npm run test:api-v4:integration (integration tests for API v4, a private API that normally shouldn't be used)

If one of those tests fails, the whole npm run test command blocks and fails. You can run each of those commands by itself if you are interested in only one type of test.

While you are editing code or creating tests, it is often convenient to run only the tests that are relevant to your changes.

  1. Use .only to mark the test(s) you want to run:
    • To run only a single test, change it('test name', ...) to it.only('test name', ...)
    • To run only one section of tests, change describe('section name', ...) to describe.only('section name', ...). You might find that context is used instead of describe and it can be modified in the same way.
    • .only can be added to more than one test or section, in one or more files, to run all of those tests / sections but no others.
    • Remember to always remove .only before committing your changes!
  2. Run either the unit tests or integration tests depending on which files contain the tests you are interested in:
    • if the files are under the test/api/unit/ directory, run the unit tests with:
      npm run test:api:unit
    • if the files are under the test/api/v3/integration/ directory, run the integration tests with:
      npm run test:api-v3:integration

Integration Tests[]

The integration tests are for testing Habitica's API. They are performed by making HTTP requests to the API's endpoints and asserting on the data that is returned.

Each top level API route has its own integration test directory. For example, all the routes that begin with /groups/ are in /test/api/v3/integration/groups/.

Each file in an integration test directory should encompass a single route and follow this file naming standard:

  • begin with the REST parameter for the route (POST, GET, etc.)
  • display the full name of the route with / replaced by _
  • end with .test.js

For example, for the POST route https://habitica.com/api/v3/groups/:groupId/join, the tests are in the file test/api/v3/integration/groups/POST-groups_groupId_join.test.js.

If you need to fix errors reported by the integration tests, you might find it helps to run the web server at the same time as the tests so that you can inspect the web server's output caused by the tests. To do that, in one terminal run:
NODE_ENV=test npm start
and then in a different terminal window run:
npm run test:api-v3:integration:separate-server

Promises in Integration Tests[]

To mitigate callback hell, there is a helper method to generate a user object that can make HTTP requests that return promises. This makes it easy to chain together commands. All you need to do to make a subsequent request is return another promise and then call .then((result) => {}) on the surrounding block, like so:

it('does something', () => {
  let user;

  return generateUser().then((_user) => { // We return the initial promise so this test can be run asyncronously
    user = _user;

    return user.post('/groups', {
      type: 'party',
    });
  }).then((party) => { // the result of the promise above is the argument of the function
    return user.put(`/groups/${party._id}`, {
      name: 'My party',
    });
  }).then((result) => {
    return user.get('/groups/party');
  }).then((party) => {
    expect(party.name).to.eql('My party');
  });
});

If the test is simple, you can use the chai-as-promised return expect(somePromise).to.eventually syntax to make your assertion.

it('makes the party creator the leader automatically', () => {
  return expect(user.post('/groups', {
    type: 'party',
  })).to.eventually.have.deep.property('leader._id', user._id);
});

If the test is checking that the request returns an error, use the `.eventually.be.rejected.and.eql` syntax.

it('returns an error', () => {
  return expect(user.get('/groups/id-of-a-party-that-user-does-not-belong-to'))
    .to.eventually.be.rejected.and.eql({
      code: 404,
      text: t('messageGroupNotFound'),
    });
});

Running Tests in Vagrant[]

If you are running the tests in vagrant, you might see the following error:

Error: /vagrant/.eslintrc:
Configuration for rule "func-style" is invalid:
Value "2,declaration,[object Object]" has more items than allowed.

or many instances of these:

 1:1  error  Definition for rule 'no-empty-pattern' was not found    no-empty-pattern
 1:1  error  Definition for rule 'no-arrow-condition' was not found  no-arrow-condition

You might also find that this test starts but never completes:

Starting 'test:e2e:safe'...

You can avoid those problems by editing two files in the top-level directory of your local install.

  • Edit .eslintrc to comment out these lines:
    • "no-empty-pattern": 2,
    • "no-arrow-condition": 2,
    • "func-style": [2, "declaration", { "allowArrowFunctions": true }],
  • Edit tasks/gulp-tests.js to comment out this line:
    • 'test:e2e:safe',

Do not commit those changes because those lines are needed for running tests on the server.

Tips[]

Code formatting and quality: Maintain the coding standards that are already in use in the code base (e.g., two spaces for each indentation level). We use lint to ensure consistent code formatting. When submitting a pull request, an automatic test suite will run over your code and will fail if lint indicates problems. The tests must pass before your code can be accepted.

Gender-neutral language: When writing documentation or code comments, use gender-neutral language (e.g., don't use "he" or "she" or "he/she"). We typically use they / them as a singular pronoun throughout Habitica to cover people of all genders.

Keep your commits clean: Commits must contain only files suitable for inclusion in Habitica's official repository. If you add any files for personal use, never specify them in a git add or git commit command. Also do not specify them in the repository's .gitignore file because changes to that file will be included in the official repository; use your global .gitignore file instead.

Migrations: Some Habitica website changes require parts of the database to be changed (e.g., modifying all existing user accounts to assign a default value for a new setting). Such database changes are done with a migration script, which contains JavaScript that connects to the database and makes modifications. All migration scripts are in migrations/. Read them and use them as examples to write your own script. The more recently edited scripts are likely to contain better, more up-to-date code than older scripts (the ones in the migrations/archive directory are less likely to be useful examples unless they have a recent date). Migration scripts need to be run from within a migration runner script (migrations/migration-runner.js). To run a migration:

  1. Change to the top-level directory of your local install (the directory where the config.json file exists).
  2. Open the file migrations/migration-runner.js in a text editor.
  3. Find the comment // Replace this with your migration near the bottom of the file. The next line will be const processUsers = require('./a/path/to/a/script.js');
  4. Edit that line so that the path to the script points to the migration you want to run without the "migrations/" portion of the path. For example, if you want to run migrations/groups/migrate-chat.js edit that line to insert ./groups/migrate-chat.js -- i.e., when you have finished editing the script, the line must look like this:
    const processUsers = require('./groups/migrate-chat.js');
  5. Save your change and quit the editor.
  6. Run the migration by executing this command:
    node migrations/migration-runner.js

Submitting your Change for Review in a Pull Request[]

When you have finished your change, or if you want feedback on your Work in Progress (WIP) code, create a Pull Request (PR) using the process below.

  1. Commit any uncommitted changes (use a meaningful commit message).
  2. If significant time has passed since you created the branch, merge the latest changes from upstream/develop into your branch. See the "Merge Changes from upstream/develop" section below for more details.
  3. Don't squash your commits unless you really want to. Habitica's staff don't require you to do that and sometimes it's easier to review a PR one commit at a time.
  4. Push your commits to your fork of Habitica in GitHub:
    git push origin name-of-your-branch
  5. In GitHub, create a pull request (PR) (in brief, go to https://github.com/YourUsername/habitica and click on the "New pull request" button).
    • Give your PR a meaningful title that describes the bug being fixed or the feature being created / modified. It should be possible for people to get some understanding of your PR from the title alone, so it needs to contain more than, for example, "fixes the bug in issue 1234".
    • If your PR will fully fix an issue, add "fixes #[issue number]" to the end of the title (e.g., "fixes #1234").
    • If your PR will partially fix an issue, add "partial fix for #[issue number]" to the end of the title.
    • If you are making a PR to seek help with your code, put "WIP" (Work In Progress) at the start of the title. Optionally, you can also enable "draft mode" if you know how to.
    • Follow the instructions that you'll see in the comment field of the PR.
    • If your PR will fully or partially fix an issue, add "fixes #[issue number]" or "partial fix for #[issue number]" in the body of the PR (as well as in the title).
    • Always write a meaningful explanation of your change in detail in the body of the PR. Don't rely on the title explaining it fully and please don't expect the admins to understand the PR just by reading your code. The PR description gives the admins the context necessary to understand and approve code more rapidly, and also allows non-technical staff and contributors to determine if your PR is relevant to them.
    • If your change has a visible effect on the website, include screenshots showing the existing and new behavior to help demonstrate what is changing. To learn how to add images, see the note at the bottom of GitHub's comment field.
    • If you are making a PR to seek help with your code, include the above information and also state that the PR is not complete and describe the help you need.
    • If this is your first PR in this repo, you'll see a message saying "1 workflow awaiting approval. First-time contributors need a maintainer to approve running workflows." The workflow is the one that runs the automatic tests. Add a comment to your Pull Request saying something like this: "I'm a first time contributor so the workflow for tests hasn't run automatically. Please can an admin click the button to start it?"
Notes
  • Admins will receive an email when your pull request is created so you do not need to inform them in any way.
  • If your pull request references an issue, the issue will be updated automatically to contain a link to your PR.
  • You can add comments to your pull request to ask for advice, even while in draft mode.
  • If you are making a PR for a WIP to seek help with your code, it is not necessary for the tests to pass.
  • If you find it's impossible to run the tests locally due to limitations in your system, it's acceptable to make a PR and then examine the output of the test suite that's run automatically against your PR. Please write in your PR that you are doing this so that admins know not to review your PR until you have said it is ready.

Merge Changes from upstream/develop[]

If a significant time has passed since you created the branch on your local install, use rebase or merge to bring the latest changes from upstream/develop into your branch before your push your branch to GitHub. Follow this process:

  1. git fetch upstream
  2. git rebase upstream/develop or git merge upstream/develop
  3. Fix any merge conflicts.
  4. Re-run the automated tests.
  5. Fix any problems and commit again.

Since the code can be very different, be sure to re-test your changes manually, especially if the rebase or merge modified any code related to your pull request.

Having your Pull Request Tested and Reviewed[]

When you make a PR, Habitica's automated tests will be run. Two test builds are run, one against your branch and one against your branch as if it had been merged into the most recent develop branch in Habitica's repository. These tests will fail if there are problems with your code and you can use the links that will appear in the PR to review the failures. However, there should normally be no failures if you had run npm test successfully in your local install. Sometimes the tests will fail from problems that aren't related to your change (e.g., if timeouts happen during the test build); if so, admins will restart the test build and you will not need to take any actions. However you should always review test failures to work out if they are from your code or not. If failures are from your code, admins will ask you to fix the problems before they test and review your code.

After the test build succeeds, one or more admins will review your pull request by testing it on their own local install and reading your code changes. Admins will try to do this promptly but the time frame depends to some extent on how many PRs there are and other factors. Admins have a target of reviewing each PR within two weeks, or sooner when possible. PRs are usually reviewed at the beginning or end of each week, so if you submit an update at any other time, it might be a few days before it's reviewed. While you're waiting, you're welcome to work on another issue if you wish to.

Admins might request changes and will then apply the status: pr: with author: needs work GitHub label to your pull request. When that happens, before your pull request can be accepted, you will need to make those changes or explain why you think they should not be made. Admins can be identified by GitHub's "Member" indicator to the right of their names; any person in GitHub who does not have that indicator is not an admin, even if they seem to be speaking with authority.

Other contributors might also suggest changes. Implementing them might be optional, depending on the suggestion, but experienced contributors often make good suggestions. If you notice that an admin has commented favourably on a contributor's suggestion or has given it a positive emoji (e.g., thumbs up or a smiley face) then it's recommended that you do implement the suggestion or explain why you think it should not be implemented.

If you don't understand the changes requested or are having trouble with them, don't be afraid to ask for help! You are also welcome to commit and push partial changes if you need advice about how to finish them.

If other PRs are merged to develop while yours is being reviewed, admins might ask you to fix merge conflicts. This can be done in your local install by merging in the latest version of upstream/develop and manually editing the conflicts that git tells you about. You are welcome to ask for advice about this if needed!

When you have handled all feedback given to you by admins (and optionally by contributors), add a comment to the PR to state that the PR is ready for review again. Admins will then replace the status: pr: with author: needs work label with the status: pr: ready for review GitHub label and your PR will go back into the queue for further review.

If you have handled all feedback given to you and your PR has the status: pr: with author: needs work label after a week, please post a small reminder to the PR that you've made the requested changes and that it's ready for review again.

If your PR has the status: pr: with author: needs work label and you haven't made any updates or comments for a month, admins will ask you about your progress. You will have a week to respond to confirm that you’re still working on the PR or your claim on the PR and any associated issue will lapse. You’ll be able to refresh a claim three times before it will lapse automatically. Once your claim has lapsed, admins will either take over the PR to complete it themselves or will release it to the developer community for someone else to work on. If you completed some work that is later merged, you’ll receive partial contributor credit. Admins might shorten these turnaround times if the PR is of high priority - they will clearly state a due date in those cases.

Some of this information was initially released by SabreCat in the PR Process Update blog post.

Making Changes to your PR[]

To change code that has already been submitted in a PR or to merge in upstream/develop to fix conflicts:

  1. In your local install, go to the branch that you created for your change:
    git checkout name-of-your-branch
  2. Make the code changes or do the merge and fix any merge conflicts (see above for more details about merging).
  3. Commit the changes, using a meaningful commit message (e.g., describe the fixes that were made in response to feedback). If you are just merging you might find that no new commit is needed.
  4. Push to your fork of Habitica in GitHub using the same command you used for the original push:
    git push origin name-of-your-branch
    That will automatically update your PR.
    • If you have rebased since the last time you pushed, you might find that a normal push command fails and that you need to do a forced push by specifying -f:
      git push -f origin name-of-your-branch
    • Note that as a general rule you should be cautious about using -f to force any git command to succeed. It's expected and generally necessary when pushing after a rebase, however in any other situation make sure that you understand the consequences of using -f before you use it.
  5. When you have finished making changes and pushing, add a comment to the PR to say what has changed and to state that it is ready for review again.

Note that admins will receive emails for all new comments added to PRs, but they are not emailed when any existing comment is edited so to ensure everything you write is seen by admins, make new comments instead of editing old ones. If there is a reason to edit an old comment, you can do that but please also create a new comment to explain what has changed in the previous comment.

Reviewing Other Contributors PRs[]

Habitica welcomes members of the coding community to review each other's work and add comments or suggestions on PRs. However please only review if you have a good understanding of the code and have experience with the functional area covered by the PR.

Habitica's staff are considering the possibility of having a new contributor title for users who are doing a particularly good job with reviewing and testing PRs. More information will be given later if this proceeds.

This information was initially released by SabreCat in the PR Process Update blog post.

Acceptance of Your PR and the Release Cycle[]

When an admin decides that your pull request (PR) is ready to be accepted, they will give it the status: pr: tested and approved; merge pending GitHub label.

Each week by the end of Monday in USA time, admins do a final brief review of all PRs with that label. In rare cases, they will decide to delay a PR for longer (e.g., for more testing on a dedicated test server). Each other PR with that label is merged into the develop branch and a comment is added to the PR to state that either you have been given a contributor tier or that your PR has been noted as credit towards your next tier.

Occasionally admins forget to update your Habitica account with information about your PR (and are always sorry about that!) If your PR is merged and a day later there is still no comment in it from an admin regarding a new tier or credit towards a tier, please post to the PR to ask about it. Similarly, if an admin has stated that you have been given a new tier but you have not seen your tier increase in Habitica, please ask in the PR. Admins really do want to know when they have forgotten this important step! If you believe that this might have happened in any old PRs that you or others might have made, you are welcome to ask in those are PRs, no matter how old they are.

Once your PR is merged into develop, your change becomes available on a staging server that staff use for as much of their normal use of Habitica as possible. This means that most new features and bug fixes are used under real-world conditions by several people for a few days before becoming available to all Habiticans. This helps to identify any errors that might have been missed during testing (e.g., if other PRs have negative interactions with your PR). The staging area is not available to other Habiticans.

Each Thursday morning in USA time, admins will migrate all changes that are in staging to the production website. You can monitor the Releases page to find out when this happens. There can be a delay of a couple of hours between the Releases page being updated and the new release appearing on the Habitica website.

Occasionally there will be a week when PRs are not merged on Mondays or deployed to production on Thursdays, for example, during a holiday period when several staff might be on holidays.

Advertisement