From 3baf4a6e23d45e4c72b580297ed2eb00be43ee8a Mon Sep 17 00:00:00 2001 From: Baelx <16845197+Baelx@users.noreply.github.com> Date: Wed, 10 Apr 2024 01:05:13 -0700 Subject: [PATCH] DESENG-475 Add contributing guidelines for repo (#2437) * DESENG-475 Add contributing guidelines for repo * DESENG-475 Update changelog, finalize guide --- CHANGELOG.MD | 3 +++ CONTRIBUTING.md | 57 ++++++++++++++++++++++++++++++++++++++- docs/pr-segmentation.png | Bin 0 -> 18462 bytes 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 docs/pr-segmentation.png diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 5924ad6d4..08c06f800 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,3 +1,6 @@ +## April 10, 2024 +- **Task** Update contributing guide for developers [DESENG-475](https://apps.itsm.gov.bc.ca/jira/browse/DESENG-475) + ## April 09, 2024 - **Task**: CSS Selector specificity [🎟️ DESENG-577](https://apps.itsm.gov.bc.ca/jira/browse/DESENG-577) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 43d4d4a72..fb7b51679 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,61 @@ Government employees, public and members of the private sector are encouraged to (If you are new to GitHub, you might start with a [basic tutorial](https://help.github.com/articles/set-up-git) and check out a more detailed guide to [pull requests](https://help.github.com/articles/using-pull-requests/).) -Pull requests will be evaluated by the repository guardians on a schedule and if deemed beneficial will be committed to the master. +Pull requests will be evaluated by the repository guardians on a schedule and if deemed beneficial will be committed to the main branch. All contributors retain the original copyright to their stuff, but by contributing to this project, you grant a world-wide, royalty-free, perpetual, irrevocable, non-exclusive, transferable license to all users **under the terms of the [license](./LICENSE) under which this project is distributed**. + +## Changelog + +Developers should update the changelog with each merge into main. The changelog should reference a JIRA ticket number or, if none is associated, provide a detailed explanation of the work. The date should also be provided. No version number is necessary. For example: + +``` +## April 20, 2024 +- Fixed bug that didn't allow users to post [DESENG-123](https://apps.itsm.gov.bc.ca/jira/browse/DESENG-123) +``` + +Take note of the previous date in the changelog when committing. If the current date is at the top of the file, add a bullet for your changes under that date header. + +## Pull Requests + +If a high volume of changes is to be submitted as a PR, we ask that the work be segmented into multiple PRs. A common threshold is that a PR should contain 20 changed files at most. Of course it also depends on the complexity of the changes but we ask that work be broken up into smaller logical chunks whenver possible. + +### Examples + +1. Let's say you've added 5 new files and made complex changes to 10 others. You also have 5 files that have minor changes in syntax as a result of running the linter. This would be a good place to submit a PR. +2. You have 1 new file added and you may need to make minor changes to syntax or variable names in 25-30 other files. This would be fine to submit as a single PR. + +Segmenting a PR is more of an art than a science and PRs typically won't be rejected if they're larger than 20 files. How you segment may be informed by how you choose to branch in git. An example segmentation workflow is provided below. + +### Segmentation technique + +One common technique used for segmenting PRs is to create a "parent" feature branch off of main. From there, you can create many "child" branches from the parent. A PR is submitted each time you want to merge a child into its parent. A child branch will represent one logical division of the work and, as mentioned above, will contain no more than 20 changed files (depending on complexity of changes). + +![PR Segmentation Diagram](docs/pr-segmentation.png) + +With this method of segmentation, you don't need to worry about committing incomplete or broken features to main. When all child branches have been completed for the feature, the parent is then merged back into main in a final PR. This final review can contain your CHANGELOG.md entry. In the title or description of your PR, please indicate that all work has already been reviewed. + +__Example__: You're tasked with adding a new page to the frontend which requires read access to the DB via a new API route. You create a feature branch off of main, then a child branch off of your feature branch. You then add the new API endpoint required. You submit a PR for this work by requesting to merge your child branch into your parent feature branch. Once merged, you create another child branch off your feature branch and add the new page. You submit this work as its own PR - merging into the parent feature branch again. All work is now complete so you finish things off by submitting a PR to merge your parent feature branch into the main branch. The work has already been approved in previous reviews. You can now choose to update the Changelog. If you need to add any additional, unreviewed work, you can make a note about it in the PR description. + +## Merge Techniques + +Due to how PRs are commonly segmented in this repository, and due to its active nature, rebasing is discouraged as a way to merge changes. Traditional merge commits are preferred as they preserve history and make it easier to resolve merge conflicts. + +## Guidelines for reviewers + +Conditions for whether to Approve or Request Changes for a PR can come with a lot of nuance. We try to err on the side of Approve unless there are obvious changes needed. Below is a list of reasons to "stop" a PR. Items with a star next to them are subject to interpretation by the review. Some items may prompt to discussion between the reviewer and the submitting developer so that choices can be justified. + +Examples of when to Request Changes +- Logging functions are left in that aren't required or needed later (with exceptions for error logging, i.e. console.error, etc.) +- Commented-code is left in that isn't needed later +- Widespread incorrect syntax use (using snake case for many variables in JS when it's not required) +- Significant amount of repeition in code that can be condensed without much issue (code isn't DRY) * +- Unnecessary function calls, overly verbose code * + +## Common Components/Utilities + +- `@transational`: Database method decorator. If there is an exception during execution, the entire DB session will be safely rolled back to a point in time just before the decorated function was called. If not, the session will be saved, unless autocommit is set to False. This helps replace most session management boilerplate. +- `authorization.check_auth`: Checks a user for one or more roles and for the correct engagement. +- `schema_utils.validate`: The most commonly used method for validating request data in resources. This method takes the request JSON data and compares it to a JSON file that acts as a schema for incoming requests of that type. + + diff --git a/docs/pr-segmentation.png b/docs/pr-segmentation.png new file mode 100644 index 0000000000000000000000000000000000000000..2401f8739547def2901d07b6456cff506493be6b GIT binary patch literal 18462 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 literal 0 HcmV?d00001