You can use a .dependencies file in the user directory of your grav installation to create a manifest of plugins and themes, and run bin/grav install to install them. I recently wrote this into a README for a theme I'm redeveloping. Have a look there to save me re-explaining. I did notice an error in the first paragraph where I say the file should go into Grav's root. It should be in Grav user.
So:
Grav's command line interface install command will consult a YAML manifest of themes and plugins to install. You'll find Grav's default dependencies in a file called .dependencies in Grav's user directory.
(I don't think this file is officially documented BTW)
I generally have a few variations between environments (dev, test, prod), so I put the files under user/env/dev/.gitignore etc. I symlink user/.dependencies in each environment to the right one. (I also symlink user/env/<hostname> to user/env/dev, user/env/test etc. to keep my symlinks consistent.) I commit those environment dependencies. I don't commit the symlink at user/.dependencies because it changes per environment. So it's added into my .gitignore.
I have recently thought of a better way for me that won't involve setting symlinks in each environment. I haven't implemented this yet. Because I use Docker, I will simply bind mount user/env/<environment>/.dependencies to user/.dependencies. I use a slightly different standard docker-compose file for each environment anyway. (I actually chain them so that each environment has its own overrides, but that's a detail.) This might seem complicated but it keeps me away from the likes of Kubernetes :) This would only be a viable system if you are using Docker to deploy.
So my deploy becomes just a few steps now:
git clone <user dir repo>
docker-compose up -d
bin/grav install
There are a few config edits and might be a few other steps like running composer for a some plugins that don't come bundled with their PHP dependencies. But it can be as quick as a few minutes, which is fine for how often I do it. Another thing I might do manually is upload files containing secrets that are excluded from my site repos.
A lot more detail than you asked for but it shows that you can come up with a pretty smooth workflow to suit you.