T
The first thing to do is to define what is meant by "Continuous Integration", "Continuous Delivery", and "Continuous Deployment". They've come to mean different things to different people.
Continuous Integration comes from Extreme Programming, developed by Kent Beck and others. In Extreme Programming Explained: Embrace Change, Beck says this about Continuous Integration:
Integrate and build a complete product. If the goal is to burn a CD,
burn a CD. If the goal is to deploy a web site, deploy a web site,
even if it is to a test environment. Continuous integration should be
complete enough that the first deployment of the system is no big
deal.
From an Extreme Programming perspective, Continuous Integration would result in a deliverable, such as a library or package or container in a registry. If the goal is to make the package, that would be sufficient. However, if the team handles building the system, true Continuous Integration would go further and deploy that package or container to an environment. The team would need to define what its goal and deliverable would be - is it a user-facing software system or a package?
Having a well-controlled staging or test environment is almost certainly required when performing Extreme Programming's form of Continuous Integration or what is often referred to as Continuous Delivery today. These practices require that you have confidence in the ability to deploy software to the production environment on-demand. Without deploying it somewhere, preferably to an environment that is sufficiently like the production environment, how do you intend to have the necessary confidence? This only applies to teams building systems, though - teams building packages may be confident by creating a package somewhere and not publishing it.
As far as branching, you don't need a branch-per-environment. You can continue to use trunk-based development ( https://trunkbaseddevelopment.com/committing-straight-to-the-trunk/ or https://trunkbaseddevelopment.com/short-lived-feature-branches/ ) with https://trunkbaseddevelopment.com/release-from-trunk/ or https://trunkbaseddevelopment.com/branch-for-release/ . If you are practicing XP's definition of CI or Continuous Delivery, each commit to trunk would result in a build created and deployed somewhere. When you decide to go to production, a person would make the decision to promote the artifacts associated with a specific build to production. If you are branching for release, this would be associated with creating a release branch from trunk. Otherwise, it would be promoting a particular commit hash or tag.