|
| 1 | +# Git / GitHub Reviewing Workflow |
| 2 | + |
| 3 | +Reviewing is done via the GitHub pull request interface, generally following the [GitHub guidelines](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests). |
| 4 | + |
| 5 | +Reviewing implies 5 actions: |
| 6 | + |
| 7 | +1. Reviewing the commit messages and metadata (signature, authorship) |
| 8 | + |
| 9 | +1. Reviewing the content of the contribution: good design, implementation value, readability, compliance |
| 10 | + |
| 11 | +1. Testing changes, making sure the fix the problem or they add the proposed feature, making sure they don't break anything |
| 12 | + |
| 13 | +1. Submitting the review |
| 14 | + |
| 15 | +1. Discussing and iterating |
| 16 | + |
| 17 | +All of these actions can rely on automation, such as linters, static analysis tools, unit testing / integration testing, typically included in CI/CD pipelines, such as those provided by [GitHub Actions](https://docs.github.com/en/actions). |
| 18 | + |
| 19 | +## Set Up |
| 20 | + |
| 21 | +Doing the review requires two items: |
| 22 | + |
| 23 | +1. Be logged in on GitHub and have reviewer access to the pull request. |
| 24 | + The second part means that you have access to the pull request (in case of a private) repository. |
| 25 | + |
| 26 | + In order to be formally assigned as a reviewer to a pull request in the GitHub interface, you have to have the [`Triage` role the repository](https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization). |
| 27 | + This role is assigned to you by a admin member of the repository. |
| 28 | + This role is not a requirement, you can do a review without being assigned as a reviewer. |
| 29 | + |
| 30 | +1. Have a local clone of the repository (or a clone of your fork of the repository). |
| 31 | + So you either did, at point, `git clone <URL>` using the `<URL>` of the main repository, or using the `<URL`> of your [fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks) of that repository. |
| 32 | + |
| 33 | +For the first item, you browser should have opened the GitHub pull request. |
| 34 | + |
| 35 | +For the second item, you will configure your local repository to point to the branch used to create the pull request. |
| 36 | +For this, do the following: |
| 37 | + |
| 38 | +1. Be sure you are located, using the command line, on the local copy of the repository. |
| 39 | + |
| 40 | +1. Copy the link mentioned in the `from <username>:<branch>` part of the pull request. |
| 41 | + This is the link to the contribution source. |
| 42 | + E.g. `https://github.com/cluosh/unikraft/tree/staging`, `https://github.com/michpappas/unikraft/tree/michpappas/feature/libukmemtag`. |
| 43 | + |
| 44 | + The link stores 3 important pieces of information of the remote contribution: |
| 45 | + |
| 46 | + 1. The username: `cluosh` and `michpappas` |
| 47 | + 1. The repository name: `unikraft` and `unikraft` |
| 48 | + 1. The branch name: `staging` and `michpappas/feature/libukmemtag` |
| 49 | + |
| 50 | + Copy paste the link and edit it to only include the username and the repository name. |
| 51 | + Remove the branch part, that is anything in the URL starting from and including `/tree/...`. |
| 52 | + E.g. `https://github.com/cluosh/unikraft`, `https://github.com/michpappas/unikraft`. |
| 53 | + |
| 54 | +1. **Note**: This step is required if this is the first time you add a given remote. |
| 55 | + If you have added a remote for the username before, you ca skip this step. |
| 56 | + You can try the command below and, if you get a message such as `remote ... already exists`, you can go to the next step. |
| 57 | + |
| 58 | + ```console |
| 59 | + git remote add <username> <URL> |
| 60 | + ``` |
| 61 | + |
| 62 | + where `<username>` is the username in the URL, e.g. `cluosh`, `michpappas`. |
| 63 | + E.g.: |
| 64 | + |
| 65 | + ```console |
| 66 | + git remote add cluosh http://github.com/cluosh/unikraft |
| 67 | + git remote add michpappas https://github.com/michpappas/unikraft |
| 68 | + ``` |
| 69 | + |
| 70 | + Verify it was added correctly by using: |
| 71 | + |
| 72 | + ```console |
| 73 | + git remote show <username> |
| 74 | + ``` |
| 75 | + |
| 76 | + E.g.: |
| 77 | + |
| 78 | + ```console |
| 79 | + git remote show cluosh |
| 80 | + git remote show michpappas |
| 81 | + ``` |
| 82 | + |
| 83 | +1. Check the remote branch that was used to create the pull request: |
| 84 | + |
| 85 | + ```console |
| 86 | + git branch -a |
| 87 | + ``` |
| 88 | + |
| 89 | + In the output of the above command you should see a line `remotes/<username>/<branch>`. |
| 90 | + If you don't see that, you did something wrong and you need to remove and recreate the remote, via the `git remote` command. |
| 91 | + |
| 92 | +1. Fetch the contribution from the remote end: |
| 93 | + |
| 94 | + ```console |
| 95 | + git fetch <username> |
| 96 | + ``` |
| 97 | + |
| 98 | + E.g.: |
| 99 | + |
| 100 | + ```console |
| 101 | + git fetch cluosh |
| 102 | + git fetch michpappas |
| 103 | + ``` |
| 104 | + |
| 105 | +1. Create a local branch of the contribution: |
| 106 | + |
| 107 | + ```console |
| 108 | + git checkout -b <local-branch-name> <username>/<branch> |
| 109 | + ``` |
| 110 | + |
| 111 | + where: |
| 112 | + |
| 113 | + - `<username>` is the name of the remote |
| 114 | + - `<branch>` is the name of the remote branch |
| 115 | + - `<local-branch-name>` is the name of the local branch you will use |
| 116 | + |
| 117 | + The name of the local branch is something you choose. |
| 118 | + Generally, it is advised to keep the same name as `<branch>`. |
| 119 | + However, it may be the case that the contributor uses a value for `<branch>` that conflicts with an existing local one (such as `main` or `master` or `testing`). |
| 120 | + In that case, it is suggested to use `<username>-<branch>` for the local branch name. |
| 121 | + |
| 122 | + E.g.: |
| 123 | + |
| 124 | + ```console |
| 125 | + git checkout -b cluosh-staging cluosh/staging |
| 126 | + git checkout -b michpappas/feature/libukmemtag michpappas/michpappas/feature/libukmemtag |
| 127 | + ``` |
| 128 | + |
| 129 | + In case of the first command, we used `<username>-<branch>` for the local branch. |
| 130 | + This is because the remote branch name (`staging`) conflicted with a local branch name called the same (`staging`). |
| 131 | + |
| 132 | + In the case of the second command we used the same name for the local branch as for the remote branch: `michpappas/feature/libukmemtag`. |
| 133 | + Note that there is a recommendation to use, as branch name, the format `<username>/<branch-detail>`, to be able to pin the branch name to the user creating it. |
| 134 | + |
| 135 | +So, at this point you should have: |
| 136 | + |
| 137 | +- Your browser pointing out to the pull request interface on GitHub. |
| 138 | +- Your local repository pointing to the contents of the remote branch used in the pull request. |
| 139 | + |
| 140 | +We will detail the 5 review action below, mentioning whether they will happen either on the GitHub pull request interface or locally, on the clone of the repository. |
| 141 | + |
| 142 | +## Review Commit Metadata |
| 143 | + |
| 144 | +Reviewing the commit metadata happens locally. |
| 145 | +Use the command to browse through the metadata of commits: |
| 146 | + |
| 147 | +```console |
| 148 | +git log |
| 149 | +``` |
| 150 | + |
| 151 | +Check the commits in the contributions and make sure they follow [good commit practices](https://cbea.ms/git-commit/). |
| 152 | +Generally, this means: |
| 153 | + |
| 154 | +1. The first line of the commit message (the title) is a representative line, that's not very long (ideally, but not strictly, limited at 50 characters). |
| 155 | + The title line typically has a prefix that points to the type of contribution and/or the location in the repository. |
| 156 | + This is generally stated as part of the repository contributor conventions. |
| 157 | + |
| 158 | +1. Make sure there is an empty line after the title line and the rest of the commit message (the body). |
| 159 | + |
| 160 | +1. Make sure the lines in the body are limited to 72 characters. |
| 161 | + |
| 162 | +1. Make sure there are no typos or spelling mistakes in the title or body. |
| 163 | + |
| 164 | +1. Make sure the author is properly stated, generally in the form of `Firstname Lastname <email>`. |
| 165 | + |
| 166 | +1. If the commit conventions use or imply using a [`Signed-off-by` line](https://stackoverflow.com/a/14044024/4804196), make sure that line also has the author properly stated. |
| 167 | + Also make sure the exact same name are used for both the author and the `Signed-off-by` line. |
| 168 | + |
| 169 | +1. Make sure the commit message is readable and to the point. |
| 170 | + Make sure it clearly details what the commit does. |
| 171 | + Make sure it fits the content of the commit (the actual contribution); |
| 172 | + i.e. when you check the changes in the commit, they are well connected to the message; |
| 173 | + that is they don't mention more or less than the commit contents. |
| 174 | + |
| 175 | +You will submit any issues in the general review message. |
| 176 | + |
| 177 | +## Review Contents |
| 178 | + |
| 179 | +Reviewing contents is done both in the pull request GitHub interface and locally. |
| 180 | + |
| 181 | +In the pull request GitHub interface, go the to the `Files changed` tab where you can see an interactive view of the changes. |
| 182 | +Walk through the changes and check for anything that may not be good / correct: |
| 183 | + |
| 184 | +- hard to read content |
| 185 | +- typos |
| 186 | +- violation of general coding / writing conventions |
| 187 | + - lines to large |
| 188 | + - missing newlines at the end of the files |
| 189 | + - training white spaces |
| 190 | + - improper indentation |
| 191 | +- violation of project coding / writing conventions |
| 192 | +- general coding / writing mistakes |
| 193 | +- project-specific coding / writing mistakes |
| 194 | + |
| 195 | +Follow the [GitHub review guidelines](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/reviewing-proposed-changes-in-a-pull-request) and add your request for changes. |
| 196 | +In the GitHub interactive interface in the `Files changed` tab you can request changes either on a single line or on multiple lines, where the `+` icon appears when hovering. |
| 197 | +You can request changes as feedback text or as concrete content update suggestions, as shown in the [GitHub review guidelines](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/reviewing-proposed-changes-in-a-pull-request) and add your request for changes. |
| 198 | + |
| 199 | +Locally you can get a unified view of the changes inside files. |
| 200 | +You can open a file and check out its entirety: existing content and newly contributed content. |
| 201 | +You can check the newly contributed content and make sure that: |
| 202 | + |
| 203 | +- It is consistent with existing content: same structure, same format, same conventions. |
| 204 | +- It is readable and integrates well with existing content. |
| 205 | + |
| 206 | +Finally, you want to be sure that the content is well aligned with the commits it is part of. |
| 207 | +Each commit should do one thing and do one thing well, and the content and commit should be aligned. |
| 208 | + |
| 209 | +For that, go through each commit in the contribution, from the oldest to the most recent one. |
| 210 | +Find the commit IDs by using: |
| 211 | + |
| 212 | +```console |
| 213 | +git log |
| 214 | +``` |
| 215 | + |
| 216 | +Go to the history and get the oldest commit ID (the commit hash) and then check it. |
| 217 | +Then get the next commit ID and check it. |
| 218 | +And so on. |
| 219 | + |
| 220 | +To check each commit use: |
| 221 | + |
| 222 | +```console |
| 223 | +git show <commit_id> |
| 224 | +``` |
| 225 | + |
| 226 | +where `<commit_id>` is the ID (hash) of the commit. |
| 227 | + |
| 228 | +When checking the commit be sure that: |
| 229 | + |
| 230 | +- The commit message and the commit contents correspond. |
| 231 | + The commit message should not state anything more or less than the contents. |
| 232 | + |
| 233 | +- The commit is "atomic". |
| 234 | + That is, it does one thing and one thing well. |
| 235 | + |
| 236 | + You may have two situations: |
| 237 | + |
| 238 | + 1. The commit is too "large", it has multiple contributions. |
| 239 | + In this case, the feedback should be to split to commit in smaller "atomic" commits, each per contribution. |
| 240 | + |
| 241 | + 1. The commit is too small. |
| 242 | + There are multiple commits related to the same contribution. |
| 243 | + In this case, the feedback should be to squash the commits into a single commit. |
| 244 | + |
| 245 | +In case of issues with individual commits, you will reference them by ID (or link) in the general review message. |
| 246 | +You can get a link to the commit in the `Commits` tab in the pull request interface on GitHub. |
| 247 | + |
| 248 | +## Test Changes |
| 249 | + |
| 250 | +In the above steps, you checked the contribution without actually using it. |
| 251 | +Changes must be tested to make sure they are correct and don't break anything. |
| 252 | + |
| 253 | +Ideally, the repository has CI/CD pipelines configured that automate testing of common items. |
| 254 | +This generally relies on the repository itself featuring tests that can be called automatically. |
| 255 | + |
| 256 | +Even if this is the case, there may be specific tests that you want do manually. |
| 257 | + |
| 258 | +When reviewing documentation contributions, make sure you run the documented actions (commands or otherwise) to ensure they work OK. |
| 259 | + |
| 260 | +Testing is generally particular to the repository. |
| 261 | +Do your best in ensuring that contributions work as expectedly and they don't introduce additional bugs. |
| 262 | + |
| 263 | +You will submit any issues resulting from the testing phase in the general review message. |
| 264 | + |
| 265 | +## Submit Review |
| 266 | + |
| 267 | +You submit the review in the pull request interface on GitHub. |
| 268 | + |
| 269 | +In the `Files changed` tab, click on the `Review changes` button and add your review in the pop-up text area. |
| 270 | +This is a step that you will do from the beginning, and keep adding contents to the review message as you go through the review changes. |
| 271 | +Note that if you click outside of the pop-up text are, it will close, but the review message is still there; |
| 272 | +you can get back to it by clicking the `Review changes` button again. |
| 273 | +This is useful because reviewing is an ongoing process and you may want to switch between filling the pop-up text area, adding suggestions, or checking the commits in the `Commits` tab. |
| 274 | + |
| 275 | +Once the text and suggestions of your review are complete, in the pop-up text area check on of the three buttons: `Comment`, `Approve` or `Request changes`. |
| 276 | +Typically, you choose `Approve` in case all is OK with the pull request and it can be merged, from your point of view; |
| 277 | +and you choose `Request changes` in case changes are required, as you detail in the suggestions and in the review text. |
| 278 | + |
| 279 | +Finally, click the `Submit review` button and complete the review. |
| 280 | + |
| 281 | +## Discussion and Iteration |
| 282 | + |
| 283 | +After the review is submitted, the pull request author will address the issues. |
| 284 | +The author will update the commit messages and contents. |
| 285 | +And will also start conversations on the main tab (`Conversation`) on the pull request on GitHub. |
| 286 | + |
| 287 | +As a reviewer, you will add your input to conversations to clarify the review or reach an agreement regarding part of the contribution. |
| 288 | + |
| 289 | +With conversations settled and the commit contents updated, you will be asked to do another review round. |
| 290 | +For the new round, you will iterate through the same steps above and then resubmit a new review. |
| 291 | + |
| 292 | +The steps above are the same, expect for getting the contribution updates. |
| 293 | +To get the updates, make sure you are on the local branch: |
| 294 | + |
| 295 | +```console |
| 296 | +git status |
| 297 | +``` |
| 298 | + |
| 299 | +If not, checkout to the local branch: |
| 300 | + |
| 301 | +```console |
| 302 | +git checkout <local-branch-name> |
| 303 | +``` |
| 304 | + |
| 305 | +E.g.: |
| 306 | + |
| 307 | +```console |
| 308 | +git checkout cluosh-staging |
| 309 | +``` |
| 310 | + |
| 311 | +or: |
| 312 | + |
| 313 | +```console |
| 314 | +git checkout michpappas/feature/libukmemtag |
| 315 | +``` |
| 316 | + |
| 317 | +And update the branch with the updated contents of the contribution: |
| 318 | + |
| 319 | +```console |
| 320 | +git fetch <username> |
| 321 | +git reset --hard <username>/<branch-name> |
| 322 | +``` |
| 323 | + |
| 324 | +E.g.: |
| 325 | + |
| 326 | +```console |
| 327 | +git fetch cluosh |
| 328 | +git reset --hard cluosh/staging |
| 329 | +``` |
| 330 | + |
| 331 | +or: |
| 332 | + |
| 333 | +```console |
| 334 | +git fetch michpappas |
| 335 | +git reset --hard michpappas/michpappas/feature/libukmemtag |
| 336 | +``` |
| 337 | + |
| 338 | +With a new review submitted, the author will address comments and you will iterate. |
| 339 | + |
| 340 | +For larger projects, it's common to have multiple review rounds. |
| 341 | +This, of course depends, on the contribution complexity. |
0 commit comments