diff --git a/.github/BRANCH_AND_RELEASE_PROCESS.md b/.github/BRANCH_AND_RELEASE_PROCESS.md new file mode 100644 index 00000000..da2cd8ed --- /dev/null +++ b/.github/BRANCH_AND_RELEASE_PROCESS.md @@ -0,0 +1,88 @@ +# Branch and Release Process + +- [Branch and Release Process](#branch-and-release-process) + - [Branching Process](#branching-process) + - [Branching Methods](#branching-methods) + - [Branch Process for This Project](#branch-process-for-this-project) + - [Why Pick This Strategy?](#why-pick-this-strategy) + - [Release Process](#release-process) + +## Branching Process + +In software development, selecting an appropriate Git branch strategy is crucial for maintaining code integrity, fostering collaboration, and streamlining project management. A well-defined branch strategy helps teams manage code changes systematically, reducing the risk of conflicts and ensuring that features, bug fixes, and releases are properly isolated. + +## Branching Methods + +For open-source projects, three popular Git branching strategies are: + +1. **Git Flow**: + + Git Flow is a robust branching strategy that uses multiple branches for feature development, releases, and hotfixes. The primary branches include: + + - `main`: Holds the production-ready code. + - `develop`: Integrates all completed features and serves as the staging area for the next release. + - `feature/*`: Branches off from `develop` for new features. + - `release/*`: Branches off from `develop` when preparing a new release. + - `hotfix/*`: Branches off from `main` for critical fixes that need to be deployed immediately. + + Git Flow is suitable for projects with regular release cycles and helps maintain a clear and structured workflow. + +2. **GitHub Flow**: + + GitHub Flow is a simpler, more streamlined approach ideal for projects that deploy frequently. Its key principles include: + + - A single `main` branch always containing deployable code. + - Branches for each feature or bug fix that branch off from `main` and merge back into `main` upon completion. + - Continuous deployment from the `main` branch, allowing for fast iterations and rapid delivery of new features. + + This strategy emphasizes simplicity and continuous integration, making it well-suited for fast-paced development environments. + +3. **Trunk-Based Development**: + + Trunk-Based Development focuses on keeping a single, stable branch (the "trunk") where all developers commit their code. Key practices include: + + - Small, frequent commits directly to the `main` branch. + - Short-lived feature branches that are quickly merged back into `main`. + - Emphasis on automated testing and continuous integration to ensure code stability. + This strategy aims to minimize merge conflicts and maintain a high level of code quality, promoting rapid feedback and collaboration. + +Each of these strategies has its own strengths and is chosen based on the specific needs and workflow of the project. + +## Branch Process for This Project + +This project's branch process sits between **GitHub Flow** and **Git Flow** by taking the best of both worlds. This projects branching strategy looks like: + +Aspects used from **GitHub Flow**: + +- A single `main` branch always containing deployable code. +- Branches for each feature or bug fix that branch off from `main` and merge back into `main` upon completion. +- Continuous deployment from the `main` branch, allowing for fast iterations and rapid delivery of new features. + +Aspects used from **Git Flow**: + +- `release-v[0-9]+/*`: Branches off from `main` when preparing a new release. +- `hotfix/*`: Branches off from `main` (or a release branch) for critical fixes that need to be deployed immediately. + +### Why Pick This Strategy? + +This is done in order to foster: + +- maximum collaboration with external contributors + - since we are on GitHub, it's the standard workflow by default. (its why `develop`, or `alpha`/`beta`/etc branches aren't created by default) + - it's intuitively obvious where contributions (ie PRs) need to merge with zero background on the project + - this puts all bespoke, project, and repo management on the project maintainers +- forces the project maintainers to embrace CI/CD + - `main` must work at all times; therefore, main can be deployed or released at all times +- things don't always go according to plan + - having the branching strategy for releases **Git Flow** helps support of concurrent versions + - provides flexibilty to create release trains + +## Release Process + +The release process for this project is designed to balance the rapid iteration capabilities of **GitHub Flow** with the structured release management of **Git Flow**. Releases are typically created off `main` since we strive to keep backwards compatibility and prevent breaking any interfaces. This implies that releases are basically a single train pushing features out. In terms of new feature release health, you should consider the `main` branch unstable. Consumers of this SDK should **ONLY** ever consume a tagged release on the repo release page. + +In the event of a breaking interface change, a `release-v[0-9]+` branch is created off the main branch or at the point of divergence. Additionally, according to semver best practices, the project is accompanied by a major version bump. It's implied that these different interfaces are to be supported until determined by the company SLA. + +In scenarios where urgent issues arise, the `hotfix` branch comes into play. A hotfix branch is created off main or the relevant release branch to address critical issues that need immediate attention. After the hotfix is implemented and thoroughly tested, it is merged back into both the `main` and the `release-v[0-9]+` branches to ensure the fix is included in the current and future versions of the project. + +This dual approach of leveraging both **GitHub Flow** and **Git Flow** ensures that the project can iterate quickly while maintaining high standards of code stability and release management. diff --git a/.github/CODE_CONTRIBUTIONS_GUIDE.md b/.github/CODE_CONTRIBUTIONS_GUIDE.md new file mode 100644 index 00000000..b5cd3614 --- /dev/null +++ b/.github/CODE_CONTRIBUTIONS_GUIDE.md @@ -0,0 +1,158 @@ +# Development Guide + +- [Development Guide](#development-guide) + - [Welcome](#welcome) + - [Preparing Your Local Operating System](#preparing-your-local-operating-system) + - [Setting Up macOS](#setting-up-macos) + - [(Optionally) Setting Up Windows](#optional-setting-up-windows) + - [Installing Required Software](#installing-required-software) + - [Installing on macOS](#installing-on-macos) + - [Installing on Linux](#installing-on-linux) + - [Installing Python](#installing-python) + - [(Optionally) Virtual Environment Manager](#optionally-virtual-environment-manager) + - [Installing Docker](#installing-docker) + - [GitHub Workflow](#github-workflow) + +## Welcome + +This document is the canonical source of truth for building and contributing to the [Python SDK][project]. + +Please submit an [issue] on GitHub if you: + +- Notice a requirement that this doc does not capture. +- Find a different doc that specifies requirements (the doc should instead link here). + +## Preparing Your Local Operating System + +Where needed, each piece of required software will have separate instructions for Linux, Windows, or macOS. + +### Setting Up macOS + +Parts of this project assume you are using GNU command line tools; you will need to install those tools on your system. [Follow these directions to install the tools](https://ryanparman.com/posts/2019/using-gnu-command-line-tools-in-macos-instead-of-freebsd-tools/). + +In particular, this command installs the necessary packages: + +```bash +brew install coreutils ed findutils gawk gnu-sed gnu-tar grep make jq +``` + +You will want to include this block or something similar at the end of your `.bashrc` or shell init script: + +```bash +GNUBINS="$(find `brew --prefix`/opt -type d -follow -name gnubin -print)" + +for bindir in ${GNUBINS[@]} +do + export PATH=$bindir:$PATH +done + +export PATH +``` + +This ensures that the GNU tools are found first in your path. Note that shell init scripts work a little differently for macOS. [This article can help you figure out what changes to make.](https://scriptingosx.com/2017/04/about-bash_profile-and-bashrc-on-macos/) + +### (Optional) Setting Up Windows + +If you are running Windows, you can contribute to the SDK without requiring a Linux-based operating system. However, it is **HIGHLY** recommended that you have access to a Linux terminal or command prompt. Is this absolutely necessary? No. Will this help out sometime down the road? Yes! + +There are two recommended methods to set up your machine. To determine which method is the best choice, you must first determine which version of Windows you are running. To do this, press Windows logo key + R, type winver, and click OK. You may also enter the ver command at the Windows Command Prompt. + +- If you're using Windows 10, Version 2004, Build 19041 or higher, you can use Windows Subsystem for Linux (WSL) to perform various tasks. [Follow these instructions to install WSL2](https://docs.microsoft.com/en-us/windows/wsl/install-win10). +- If you're using an earlier version of Windows, create a Linux virtual machine with at least 8GB of memory and 60GB of disk space. + +Once you have finished setting up your WSL2 installation or Linux VM, follow the instructions below to configure your system for building and developing code. + +**NOTE:** Some `examples` at the root of the repo *may* require modification as they implement Linux SIGTERM signals. This typically tends to be code using the Async IO threading model. Those examples will work on Windows if that code is removed. + +## Installing Required Software + +After setting up your operating system, you will be required to install software dependencies required to run examples, perform static checks, linters, execute tests, etc. + +### Installing on macOS + +Some build tools were installed when you prepared your system with the GNU command line tools earlier. However, you will also need to install the [Command Line Tools for Xcode](https://developer.apple.com/library/archive/technotes/tn2339/_index.html). + +### Installing on Linux + +All Linux distributions have the GNU tools available. Below are the most popular distributions and commands used to install these tools. + +- Debian/Ubuntu + + ```bash + sudo apt update + sudo apt install build-essential + ``` + +- Fedora/RHEL/CentOS + + ```bash + sudo yum update + sudo yum groupinstall "Development Tools" + ``` + +- OpenSUSE + + ```bash + sudo zypper update + sudo zypper install -t pattern devel_C_C++ + ``` + +- Arch + + ```bash + sudo pacman -Sy base-devel + ``` + +### Installing Python + +The Python SDK is written in [Python](https://www.python.org/downloads/). To set up a Python development environment, please follow the instructions in this [Python 3 Installation guide](https://realpython.com/installing-python/). + +#### (Optionally) Virtual Environment Manager + +Once you have installed Python, an optional but **HIGHLY** recommended piece of software is something that will manage virtual environments. This is important because Python projects tend to have software requirements that vary widely between projects, and even those that use the same package may require running different versions of those dependencies. + +This will allow you to have multiple environments co-exist together, making it easy to switch between environments as required. There are a number of different options for virtual environment software out there. You can find a list of recommended ones below. + +##### Miniconda + +Miniconda is a free minimal installer for conda. It is a small bootstrap version of Anaconda that includes only conda. + +[https://docs.anaconda.com/miniconda/](https://docs.anaconda.com/miniconda/) + +##### venv + +The venv module supports creating lightweight "virtual environments", each with their own independent set of Python packages installed in their site directories. + +[https://docs.python.org/3/library/venv.html](https://docs.python.org/3/library/venv.html) + +##### pyenv + +pyenv lets you easily switch between multiple versions of Python. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well. + +[https://github.com/pyenv/pyenv](https://github.com/pyenv/pyenv) + +### Installing Docker + +Some aspects of development require Docker. To install Docker in your development environment, [follow the instructions from the Docker website](https://docs.docker.com/get-docker/). + +**Note:** If you are running macOS, ensure that `/usr/local/bin` is in your `PATH`. + +### Project Specific Software + +Once you have the basics, you can download and install any project specific dependencies by navigating to the root your fork and running: + +```bash +make ensure-deps +``` + +If you have not forked and `git clone`'ed your fork, please review the next section. + +## GitHub Workflow + +To check out code to work on, please refer to [this guide][github_workflow]. + +> Attribution: This was in part borrowed from this [document](https://github.com/kubernetes/community/blob/master/contributors/devel/development.md) but tailored for our use case. + +[project]: https://github.com/deepgram/deepgram-python-sdk +[issue]: https://github.com/deepgram/deepgram-python-sdk/issues +[github_workflow]: https://github.com/deepgram/deepgram-python-sdk/.github/GITHUB_WORKFLOW.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 3e308773..f30c4563 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -2,7 +2,7 @@ The Deepgram developer community is filled with amazing, clever and creative people, and we're excited for you to join us. Our goal is to create safe and inclusive spaces, have meaningful conversations, and explore ways to make sure that every voice is heard and understood. -#### Being a Good Community Member +## Being a Good Community Member Because we prioritize creating a safe space for our members, we believe in actively working on how we, as individuals, can ensure a positive community environment through our own actions and mindsets. @@ -63,7 +63,7 @@ Contribute to the community in a positive and thoughtful way. Consider what’s Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential. -# Additional rules for online spaces +## Additional rules for online spaces For Deepgram’s official online spaces, like our YouTube & Twitch chats, we have some additional rules. Any of the following behaviors can result in a ban without warning. @@ -87,39 +87,39 @@ Please don’t post it or link to it. It doesn’t belong in our online spaces. Please do not use excessive curse words. Additionally, do not use graphic sexual or violent language — again, think of our spaces as places for people of all ages. -# Enforcement & Reporting +## Enforcement & Reporting If you are being harassed by a member of the Deepgram developer community, if you observe someone else being harassed, or you experience actions or behaviors that are contrary to our Code of Conduct, please report the behavior using our [Code of Conduct Report Form](https://developers.deepgram.com/code-of-conduct/report-form/). -## Enforcement Guidelines +### Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: -### 1. Correction +#### 1. Correction **_Community Impact:_** Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **_Consequence:_** A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. -### 2. Warning +#### 2. Warning **_Community Impact:_** A violation through a single incident or series of actions. **_Consequence:_** A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. -### 3. Temporary Ban +#### 3. Temporary Ban **_Community Impact:_** A serious violation of community standards, including sustained inappropriate behavior. **_Consequence:_** A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. -### 4. Permanent Ban +#### 4. Permanent Ban **_Community Impact:_** Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **_Consequence:_** A permanent ban from any sort of public interaction within the community. -# Attribution +## Attribution This Code of Conduct is adapted from: diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 812f8935..0b2f3644 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,49 +2,49 @@ Want to contribute to this project? We ❤️ it! -Here are a few types of contributions that we would be interested in hearing about. +- [Your First Contribution](#your-first-contribution) + - [Contribution Types](#contribution-types) + - [Making Code Contributions](#making-code-contributions) -* Bug fixes - * If you find a bug, please first report it using Github Issues. - * Issues that have already been identified as a bug will be labeled `🐛 bug`. - * If you'd like to submit a fix for a bug, send a Pull Request from your own fork and mention the Issue number. - * Include a test that isolates the bug and verifies that it was fixed. -* New Features - * If you'd like to accomplish something in the extension that it doesn't already do, describe the problem in a new Github Issue. - * Issues that have been identified as a feature request will be labeled `✨ enhancement`. - * If you'd like to implement the new feature, please wait for feedback from the project maintainers before spending - too much time writing the code. In some cases, `✨ enhancement`s may not align well with the project objectives at - the time. -* Tests, Documentation, Miscellaneous - * If you think the test coverage could be improved, the documentation could be clearer, you've got an alternative - implementation of something that may have more advantages, or any other change we would still be glad hear about - it. - * If its a trivial change, go ahead and send a Pull Request with the changes you have in mind - * If not, open a Github Issue to discuss the idea first. -* Snippets - * To add snippets: - * Add a directory in the `snippets` folder with the name of the language. - * Add one or more files in the language directory with snippets. - * Update the `package.json` to include the snippets you added. +## Prerequisites + +Before submitting code to this project, you should first complete the following prerequisites. Completing these steps will make your first contribution easier: + +- Read the [Code of Conduct](https://github.com/deepgram/deepgram-python-sdk/blob/main/.github/CODE_OF_CONDUCT.md) at [https://github.com/deepgram/deepgram-python-sdk/blob/main/.github/CODE_OF_CONDUCT.md](https://github.com/deepgram/deepgram-python-sdk/blob/main/.github/CODE_OF_CONDUCT.md). +- [Sign up](http://github.com/signup) for a GitHub user account. + +## Your First Contribution -We also welcome anyone to work on any existing issues with the `👋🏽 good first issue` tag. +The first step to getting started contributing to the Python SDK is to find something to work on. Help is always welcome, and no contribution is too small (but see below)! -## Requirements -For a contribution to be accepted: +Here are some things you can do today to get started contributing: -* The test suite must be complete and pass. Run `pytest --api-key tests/` -* Code must follow existing styling conventions -* Commit messages must be descriptive. Related issues should be mentioned by number. +- Help improve the documentation +- Clarify code, variables, or functions that can be commented on +- Write test coverage +- Help triage issues -If the contribution doesn't meet these criteria, a maintainer will discuss it with you on the Issue. You can still -continue to add more commits to the branch you have sent the Pull Request from. +If the above suggestions don't appeal to you, you can browse the issues labeled as a [good first issue](https://github.com/deepgram/deepgram-python-sdk/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) to see who is looking for help. The good first issue label also indicates that project maintainers have committed to providing extra assistance for new contributors. When you've found an issue to work on, you can assign it to yourself. + +### Contribution Types + +Here are a few types of contributions that we would be interested in hearing about. + +- Bug fixes + - If you find a bug, please first report it using Github Issues. + - Issues that have already been identified as a bug will be labeled `🐛 bug`. + - Before you start any coding or implementation, please see the [Making Code Contributions](#making-code-contributions) section first. +- New Features + - If you'd like to accomplish something in the project that it doesn't already done, describe the problem in a new Github Issue. + + - Issues that have been identified as a feature request will be labeled `✨ enhancement`. + - Before you start any coding or implementation, please see the [Making Code Contributions](#making-code-contributions) section first. +- Tests, Documentation, Miscellaneous + - If you think the test coverage could be improved, the documentation could be clearer, you've got an alternative + implementation of something that may have more advantages, or any other change we would still be glad hear about + it. -## How To +## Making Code Contributions -1. Fork this repository on GitHub. -1. Clone/fetch your fork to your local development machine. -1. Create a new branch (e.g. `issue-12`, `feat.add_foo`, etc) and check it out. -1. Make your changes and commit them. (Did the tests pass? No linting errors?) -1. Push your new branch to your fork. (e.g. `git push myname issue-12`) -1. Open a Pull Request from your new branch to the original fork's `main` branch. +for those interested in contributing code to the project, please review the [Code Contribution Guide](https://github.com/deepgram/deepgram-python-sdk/blob/main/.github/CODE_CONTRIBUTIONS_GUIDE.md) for more details. diff --git a/.github/GITHUB_WORKFLOW.md b/.github/GITHUB_WORKFLOW.md new file mode 100644 index 00000000..eb5d23d3 --- /dev/null +++ b/.github/GITHUB_WORKFLOW.md @@ -0,0 +1,297 @@ +# GitHub Workflow + +![Git workflow](images/git_workflow.png) + +This is the standard GitHub workflow used by most projects on GitHub regardless of the [branching strategy](https://github.com/deepgram/deepgram-python-sdk/blob/main/.github/BRANCH_AND_RELEASE_PROCESS.md) you decided to employ. + +However, it is important to understand [this project's branching process](https://github.com/deepgram/deepgram-python-sdk/blob/main/.github/BRANCH_AND_RELEASE_PROCESS.md) to know where you need to create your branches from. + +- [GitHub Workflow](#github-workflow) + - [1. Fork in the Cloud](#1-fork-in-the-cloud) + - [2. Clone Fork to Local Storage](#2-clone-fork-to-local-storage) + - [3. (Optional But HIGHLY Recommended) Set `git pull` to `rebase` Instead](#3-optional-but-highly-recommended-set-git-pull-to-rebase-instead) + - [4. Create a Working Branch](#4-create-a-working-branch) + - [5. Commit Your Changes](#5-commit-your-changes) + - [6. Push to GitHub](#6-push-to-github) + - [7. (If Needed) Keep Your Branch in Sync](#7-if-needed-keep-your-branch-in-sync) + - [8. Create a Pull Request](#8-create-a-pull-request) + - [9. Get a Code Review](#9-get-a-code-review) + - [10. Squash Commits](#10-squash-commits) + - [11. Merging a commit](#11-merging-a-commit) + - [(If Needed) Reverting a Commit](#if-needed-reverting-a-commit) + +## 1. Fork in the Cloud + +1. Visit the repo in which you would like to contribute to +2. Click `Fork` button (top right) to establish a cloud-based fork. + +## 2. Clone Fork to Local Storage + +Set `user` to match your github profile name: + +```bash +export user= +``` + +Both `$working_dir` and `$user` are mentioned in the figure above. + +Create your clone: + +```bash +mkdir -p $working_dir +cd $working_dir +git clone git@github.com:$user/deepgram-python-sdk.git + +cd $working_dir/deepgram-python-sdk +git remote add upstream git@github.com:deepgram/deepgram-python-sdk.git + +# Never push to upstream main (or master) +git remote set-url --push upstream no_push + +# Confirm that your remotes make sense: +git remote -v +``` + +## 3. (Optional But HIGHLY Recommended) Set `git pull` to `rebase` Instead + +This is an optional step and we will do our best here to provide directions should you not set this, but doing a `git pull` is invasive and can get quite nasty. The preferred way is to **ALWAYS** use **rebase** in favor of a traditional `git pull`. + +This will override `git pull` to effectively alias or under the covers do a `git rebase` globally: + +```bash +git config --global pull.rebase true +``` + +If you only want to do this per repo, you can navigate to the root of the repo and run this: + +```bash +git config pull.rebase true +``` + +## 4. Create a Working Branch + +Get your local `main` up to date. Note that depending on which repository you are working from, the default branch may be called `master` instead of `main`. + +```bash +cd $working_dir/deepgram-python-sdk +git fetch upstream +git checkout main +git rebase upstream main +``` + +Create your new branch. + +```bash +git checkout -b myfeature +``` + +You may now edit files on the `myfeature` branch. + +## 5. Commit Your Changes + +You will probably want to regularly commit your changes. It is likely that you will go back and edit, build, and test multiple times. After a few cycles of this, you might [amend your previous commit](https://www.w3schools.com/git/git_amend.asp). + +```bash +git commit +``` + +## 6. Push to GitHub + +When your changes are ready for review, push your working branch to your fork on GitHub. + +```bash +git push --set-upstream origin myfeature +``` + +## 7. (If Needed) Keep Your Branch in Sync + +You will need to periodically fetch changes from the `upstream` repository to keep your working branch in sync. + +Make sure your local repository is on your working branch and run the following commands to keep it in sync: + +```bash +git fetch upstream +git rebase upstream/main +``` + +> Please don't use `git pull` instead of the above `fetch` and `rebase`. Since `git pull` executes a merge, it creates merge commits. These make the commit history messy and violate the principle that commits ought to be individually understandable and useful. + +If you do have conflicts after the `git rebase`, you can get the list of files with conflicts by using `git status`. The items in red are the items needing conflict resolution. Once you do resolve them, you can individually add them back into the rebase. + +```bash +# what items need resolving +git status + +# resolve the items by making code changes + +# for each file that has been resolved +git add + +# continue the rebase +git rebase --continue + +# update your branch on your fork +git push -f +``` + +Depending on how many commits are ahead of yours, you may need to repeat this step 6 multiple times. + +Once the rebase is successful, you probably want to clean up the [commit message](https://www.w3schools.com/git/git_amend.asp). + +```bash +git commit --amend +``` + +After doing this, move onto the next step. + +## 8. Create a Pull Request + +1. Visit your fork at `https://github.com//deepgram-python-sdk` +2. Click the **Compare & Pull Request** button next to your `myfeature` branch. +3. Submit your Pull Request + +_If you have upstream write access_, please refrain from using the GitHub UI for creating PRs, because GitHub will create the PR branch inside the main repository rather than inside your fork. + +### 9. Get a Code Review + +Once your pull request has been opened it will be assigned to one or more reviewers. Those reviewers will do a thorough code review, looking for +correctness, bugs, opportunities for improvement, documentation and comments, and style. + +Commit changes made in response to review comments to the same branch on your fork. + +Very small PRs are easy to review. Very large PRs are very difficult to review. + +### 10. Squash Commits + +After a review, prepare your PR for merging by squashing your commits. + +All commits left on your branch after a review should represent meaningful milestones or units of work. Use commits to add clarity to the development and review process. + +Before merging a PR, squash the following kinds of commits: + +- Fixes/review feedback +- Typos +- Merges and rebases +- Work in progress + +Aim to have every commit in a PR compile and pass tests independently if you can, but it's not a requirement. + +To squash your commits, perform an [interactive rebase](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History): + +1. Check your git branch: + + ```bash + git status + ``` + + The output should be similar to this: + + ```bash + On branch your-contribution + Your branch is up to date with 'origin/your-contribution'. + ``` + +1. Start an interactive rebase using a specific commit hash, or count backwards from your last commit using `HEAD~`, where `` represents the number of commits to include in the rebase. + + To get this `` value, the easiest way to do this is to run `git log` and then count the number of commits until you hit `main` but not including `main`. + + ```bash + git log + ``` + + Once you have that number, continue with the rebase and squash. + + ```bash + git rebase -i HEAD~3 + ``` + + The output should be similar to this: + + ```bash + pick 2ebe926 Original commit + pick 31f33e9 Address feedback + pick b0315fe Second unit of work + + # Rebase 7c34fc9..b0315ff onto 7c34fc9 (3 commands) + # + # Commands: + # p, pick = use commit + # r, reword = use commit, but edit the commit message + # e, edit = use commit, but stop for amending + # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + ... + ``` + +1. Use a command line text editor to change the word `pick` to `squash` for the commits you want to squash, then save your changes and continue the rebase: + + ```bash + pick 2ebe926 Original commit + squash 31f33e9 Address feedback + squash b0315fe Second unit of work + ... + ``` + + The output after saving changes should look similar to this: + + ```bash + [detached HEAD 61fdded] Second unit of work + Date: Thu Mar 5 19:01:32 2020 +0100 + 2 files changed, 15 insertions(+), 1 deletion(-) + ... + + Successfully rebased and updated refs/heads/main. + ``` + +1. Force push your changes to your remote branch: + + ```bash + git push --force + ``` + +## 11. Merging a commit + +Once you've received review and approval, your commits are squashed, and your PR is ready for merging. + +Merging happens automatically after both a Reviewer and Approver have approved the PR. If you haven't squashed your commits, they may ask you to do so before approving a PR. + +## (If Needed) Reverting a Commit + +In case you wish to revert a commit, use the following instructions. + +_If you have upstream write access_, please refrain from using the `Revert` button in the GitHub UI for creating the PR, because GitHub will create the PR branch inside the main repository rather than inside your fork. + +- Create a branch and sync it with upstream. + + ```bash + # create a branch + git checkout -b myrevert + + # sync the branch with upstream + git fetch upstream + git rebase upstream/main + ``` + +- If the commit you wish to revert is a _merge commit_, use this command: + + ```bash + # SHA is the hash of the merge commit you wish to revert + git revert -m 1 + ``` + + If it is a _single commit_, use this command: + + ```bash + # SHA is the hash of the single commit you wish to revert + git revert + ``` + +- This will create a new commit reverting the changes. Push this new commit to your remote. + + ```bash + git push myrevert + ``` + +- Finally, [create a Pull Request](#8-create-a-pull-request) using this branch. + +> Attribution: This was in part borrowed from this [document](https://github.com/kubernetes/community/blob/master/contributors/guide/github-workflow.md) but tailored for our use case. diff --git a/.github/images/git_workflow.png b/.github/images/git_workflow.png new file mode 100644 index 00000000..6e1ca57b Binary files /dev/null and b/.github/images/git_workflow.png differ