TLDR: Even after using different *nix operating systems like Ubuntu, CentOS, Oracle Linux, macos for many years, I am still not sure about the best way to manipulate environment variables but here is what works for me for my bioinformatics focused use case. There are countless resources such as this one but more often than not, they teach you “how to fish” but when all you would like to accomplish is to be able to run the new software you just installed, here is your fish: Prepend the $PATH variable with the new path and do that within ~/.bashrc (or ~/.zshrc if you are using zsh shell) and make sure ~/.bashrc is sourced from ~/.bash_profile (or ~/.zprofile for that matter).*
One can set (environment) variables within different files in a GNU/Linux operating system, for example ~/.pam_environment, ~/.profile, ~/.bashrc, ~/.bash_profile, and ~/.bash_login are a few but not all.
Where to set (environment) variables depends on the shell type. For simplicity, we will ignore non-interactive shells and will focus only on interacive login shells and interactive non-login shells. The former is the one initiated at login, for example when you login to a server via ssh using putty. You get the latter when you open up a new terminal (bash session) when you are already logged in, for example when opening a new terminal within VSCode. (Actually you can change VSCode settings to get a login shell so not all VSCode shells are non-login.)
What matters to you as a user comes from the fact that login shells and non-login shells are sourcing different sets of files. For interactive login shells, /etc/profile is sourced followed by the first of the following: ~/.bash_profile, ~/.bash_login, ~/.profile. This means that ~/.profile would not be sourced if ~/.bash_profile or ~/.bash_login exists. For interactive non-login shells, ~/.bashrc is sourced.
As you must have realized, there is no file that is invoked (or sourced) for login as well as non-login shells. The workaround is setting environment varibles in ~/.bashrc and then have your ~/.profile or ~./bash_profile source your ~/.bashrc:
The newly added path of $HOME/.local/bin is appended to $PATH, this is advised over prepending $PATH. Thanks to this, the typed command/script/app is first searched within whatever is already on $PATH and only after that the newly added path is checked.
~/.bash_profile
The set-up above ensures that non-login shells as well as login shells would inherit the changes made in ~/.bashrc.
If for some reason you are using bash and zsh together, you could add/modify environment variables in ~/.profile, source this from ~/.bash_login as well as ~/.zsh_login. In that scenario you can opt for log-in shells from VSCode but I am not sure if it is worth it especially when you are using zsh because of oh-my-zsh. oh-my-bash offers pretty much the same functionality albeit not as customizable.
settings.json
* The caveat above is, quoting from the Ubuntu docs: “Shell config files such as ~/.bashrc, ~/.bash_profile, and ~/.bash_login are often suggested for setting environment variables. While this may work on Bash shells for programs started from the shell, variables set in those files are not available by default to programs started from the graphical environment in a desktop session.” In that respect, the better but little bit more convoluted set-up is setting/modifying $PATH (or the like) within ~/.profile (“since it gets executed automatically by the DisplayManager during the start-up process desktop session as well as by the login shell when one logs in from the textual console”), have it sourced from ~/.bash_profile (or get rid of ~/.bash_profile altogehter but I am not doing that because it comes rather populated with different GNU/Linux flavors) and finally have ~/.bash_profile sourced from within ~/.bashrc.