It’s not clear exactly what level of trust you have towards contributors. You could update your question to explain a bit more about whether people are all on one team or might be strangers.
One feature that is likely to help is “branch protection settings” on this protected branches article. You can state that only code reviewed PRs are allowed into a branch. See also About Code Owners where some users can be named as the code owners on a particular branch. Only they can accept changes to the branch.
With those controls you can set it up so that anyone can contribute to a repository but the branch(es) where release are taken from are strongly controlled.
You might consider not having people write directly to the repo if they are not trusted team members. It’s normal to have untrusted people fork the repo, add the main repo as “git remote add main $URL” and do their work on their own repo. They can “git remote pull main” to refresh from the main repo and “git push origin” to update their own fork. When they are done they can go to the web interface of their fork and creating a pull request. It will automatically be directed back to the main repo they forked. Then only writers to the main repo can merge the pull request. That is much cleaner if you really want to limit who can write to your main repo.
You can also enable “squash and merge” of pull requests so that when the PR is accepted all the commits in the PR are squashed into a single commit on the branch they are merged into.
GitHub access controls seem very permissive as “write whole repo” until you see that everyone can create forks and send PRs. When you do only have one team using a private repo then letting them push their own branches into the repo, then integrated onto a projected branch, gives good controls over what is released.