It sounds like your development environment is similar to ours. We use RStudio Server Pro, RStudio Connect, Gitlab and Postgres across several RHEL servers. We create internal customer facing dashboards that require significant validation and testing before rolling out. They are used on a daily basis for folks to do their job, so it requires a lot of planning, organization and coordination to keep things up to date.
For version control, we have a mantra that if it's more than ad hoc analysis, it gets pushed. That way information is centrally stored and others can collaborate on it easily. For branching, simple projects only have a master branch but more complex ones could have two types of branches:
Master/Develop: This is where the published branch is on Master but additional development work goes into develop. These are for simple apps where there are few feature requests and it has a very narrow scope.
Master/Version: Like above, Master is the published version, but each new version of the software has a branch created for it. This allows us to assign issues/milestones to a specific branch version.
In general, I strongly recommend using the issue/milestone featuring for complex apps. It's fantastic and it provides some much more transparency into development than most had seen.
For testing and validation, we are moving away from paper testing as it is slow and doesn't provide enough complexity. Shinytest for validating changes to shiny apps and testthat for unit testing are great tools. Definitely look into them and consider integrating them into your development pipeline. We don't use CI but Shinytest should allow you to perform that functionality along with Gitlab. Here's a link.
For ETL type jobs, we converted them to RMarkdown documents. Anything that's a cronjob can be converted into a RMarkdown document. This accomplishes a few things:
1: Allows for documentation in Gitlab
2. Creates transparency in how ETL works
3. Centralizes code development in RStudio Server
4. Centralizes code execution in RStudio Connect
One thing that isn't discussed here but is really important are commenting and naming convention. If your group is like ours, you have a team of non-software developers performing software development. In many cases these folks have not been taught to follow any type of logical naming convention or to unitize their code into reproducible chunks. This is a cultural thing but you can start by developing a standard naming convention for variables. It helps by getting everyone to try and standardize the feel of the code and slows them down when writing. We haven't completely eliminated every "data_final_2b" variable, but it has helped.
For other best practices, you can see some of my other posts. Most of it is around the IT components of setting up and administrating this type of environment, but others are how to treat and develop different types of Shiny apps. You may find how we handle publishing of different app versions of an app to RStudio Connect useful.