If tests pass, then testers send the change/new feature/bugfix to operations team for deployment.

Currently, we've adopted the following approach:
We have a master branch from which we create one or more custom branches to make our new commits. Then we send a pull request to the release branch along with the task to test the newly developed code. If tests pass the testers merge the commits to release branch, create a pull request from release to master and open a deployment task. After the deployment, the changes are merged to master.

But there a problem here. We're never sure that the production runs the code that's in the master branch, because a human factor is involved. So next time when I want to create a branch from master I'll have to check if all the previous changes are reflected in it.

Can someone suggest a better flow? What are the best practices for this kind of situations?

P.S. I know automating the whole software development-deployment lifecycle would probably solve many problems, including this one, but currently we're a bit away from full automation.