continuous integration – How to create a release while implementing CI?

It may be a pretty simple question, but if I understand the concepts correctly, I can’t really grasp how are you supposed to create releases with CI.

Basically, if you merge unfinished branches into development branch for the CI (so everyone’s code is as up to date as possible etc.), you’re never really going to end up with a stable, ready to deploy version on your master, as there’s always some unfinished work going on.

How are you meant to create a deployment version if you keep updating your master with unfinished features?

The only idea I had was using cherry-pick or doing an additional pull request to stable branch only when the feature is finally finished, but both of these approaches seem wrong.

I read something about not merging unfinished features, and only merging master into the unfinished branches, but wouldn’t that cause the very problem CI is trying to prevent? As in, if you have 2 big feature branches being worked on, before they get finished you have no changes to the master, and then you have 2 huge pull requests from both features being complete.

Am I missing something obvious?
Thanks!