I agree. But I find two problems with your proposal:
1- Maintaining a mirror of dependencies can be a non-trivial overhead. In this app that I was working on, the previous devs had forked some gems on github, and then added that specific github repo to the requirements. But they did not do it for every dependency, probably they did not have time/resources to do that.
2- As a corollary to the above, sometimes the problem is not the package itself but compatibility among packages. E.g. package A requires version <=2.5 of package B, but package C requires version >= 2.8 of package B. Now I hear you asking "then how did it compile in the frist place?" probably the requirement was for package A v.2.9 and package C latest version, so while A was frozen, C got updated. This kind of problems is not solved by forking on Github, unless you mantain a different fork of each library for each of your project, but that's even more problematic than maintaining dependencies themselves.
P.S. At least for once, it wasn't "my fault", I didn't build that app LOL ;-)
> 1- Maintaining a mirror of dependencies can be a non-trivial overhead. In this app that I was working on, the previous devs had forked some gems on github, and then added that specific github repo to the requirements. But they did not do it for every dependency, probably they did not have time/resources to do that.
You've precisely identified the trade-off. You basically have three options. You can
1. Maintain a local repo of your dependencies (high effort)
2. No dependencies, include everything as 'first-class' code (lower upfront effort, but v. messy)
This problem is solved by mirror dependencies and pinning the versions. Even against a git repo, pinning to a particular sha is something that is possible.
Automatically upgrading versions (i.e. not pinning versions) in a production build is an anti-pattern.
These sound like problems incurred due to a previous lack of software engineering rigor. As an industry, when we encounter challenges like this we should be learning how to solve them without reinventing the wheel. Pinning versions and maintaining mirrors of dependencies (whether that's an http caching proxy for npm/pypi/maven/etc or keeping a snapshot of all dependencies in a directory or a filesystem somewhere) is something that any company requiring stability needs to take seriously.
Of course pinning the versions and identifying the particular commit in the Gemfile would have solved it, as long as it was done for every package, otherwise we are back at problem n. 2 in my post above.
In this particular case, there were just 3-4 requirements (out of more than 100) that were pointing to a git repo, and only one of them also specified a particular commit. The other "git-requirements" were just cloning the latest commit from the respective repo.
> Automatically upgrading versions (i.e. not pinning versions) in a production build is an anti-pattern.
We did not have access to a production version, only to a git repo, that's the very reason why we had to rebuild in the first place. I can imagine all versions were locked when the system went into production years ago.
1- Maintaining a mirror of dependencies can be a non-trivial overhead. In this app that I was working on, the previous devs had forked some gems on github, and then added that specific github repo to the requirements. But they did not do it for every dependency, probably they did not have time/resources to do that.
2- As a corollary to the above, sometimes the problem is not the package itself but compatibility among packages. E.g. package A requires version <=2.5 of package B, but package C requires version >= 2.8 of package B. Now I hear you asking "then how did it compile in the frist place?" probably the requirement was for package A v.2.9 and package C latest version, so while A was frozen, C got updated. This kind of problems is not solved by forking on Github, unless you mantain a different fork of each library for each of your project, but that's even more problematic than maintaining dependencies themselves.
P.S. At least for once, it wasn't "my fault", I didn't build that app LOL ;-)