@@ -140,6 +140,47 @@ find_version_from_git_tags() {
140140 echo " ${variable_name} =${! variable_name} "
141141}
142142
143+ # Use semver logic to decrement a version number then look for the closest match
144+ find_prev_version_from_git_tags () {
145+ local variable_name=$1
146+ local current_version=${! variable_name}
147+ local repository=$2
148+ # Normally a "v" is used before the version number, but support alternate cases
149+ local prefix=${3:- " tags/v" }
150+ # Some repositories use "_" instead of "." for version number part separation, support that
151+ local separator=${4:- " ." }
152+ # Some tools release versions that omit the last digit (e.g. go)
153+ local last_part_optional=${5:- " false" }
154+ # Some repositories may have tags that include a suffix (e.g. actions/node-versions)
155+ local version_suffix_regex=$6
156+ # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios.
157+ set +e
158+ major=" $( echo " ${current_version} " | grep -oE ' ^[0-9]+' || echo ' ' ) "
159+ minor=" $( echo " ${current_version} " | grep -oP ' ^[0-9]+\.\K[0-9]+' || echo ' ' ) "
160+ breakfix=" $( echo " ${current_version} " | grep -oP ' ^[0-9]+\.[0-9]+\.\K[0-9]+' 2> /dev/null || echo ' ' ) "
161+
162+ if [ " ${minor} " = " 0" ] && [ " ${breakfix} " = " 0" ]; then
163+ (( major= major- 1 ))
164+ declare -g ${variable_name} =" ${major} "
165+ # Look for latest version from previous major release
166+ find_version_from_git_tags " ${variable_name} " " ${repository} " " ${prefix} " " ${separator} " " ${last_part_optional} "
167+ # Handle situations like Go's odd version pattern where "0" releases omit the last part
168+ elif [ " ${breakfix} " = " " ] || [ " ${breakfix} " = " 0" ]; then
169+ (( minor= minor- 1 ))
170+ declare -g ${variable_name} =" ${major} .${minor} "
171+ # Look for latest version from previous minor release
172+ find_version_from_git_tags " ${variable_name} " " ${repository} " " ${prefix} " " ${separator} " " ${last_part_optional} "
173+ else
174+ (( breakfix= breakfix- 1 ))
175+ if [ " ${breakfix} " = " 0" ] && [ " ${last_part_optional} " = " true" ]; then
176+ declare -g ${variable_name} =" ${major} .${minor} "
177+ else
178+ declare -g ${variable_name} =" ${major} .${minor} .${breakfix} "
179+ fi
180+ fi
181+ set -e
182+ }
183+
143184apt_get_update ()
144185{
145186 if [ " $( find /var/lib/apt/lists/* | wc -l) " = " 0" ]; then
@@ -173,25 +214,46 @@ if ! type git > /dev/null 2>&1; then
173214 check_packages git
174215fi
175216
217+ # Function to fetch the version released prior to the latest version
218+ get_previous_version () {
219+ local url=$1
220+ local repo_url=$2
221+ variable_name=$3
222+ prev_version=${! variable_name}
223+
224+ output=$( curl -s " $repo_url " ) ;
225+
226+ # install jq
227+ check_packages jq
228+
229+ message=$( echo " $output " | jq -r ' .message' )
230+
231+ if [[ $message == " API rate limit exceeded" * ]]; then
232+ echo -e " \nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message} "
233+ echo -e " \nAttempting to find latest version using GitHub tags."
234+ find_prev_version_from_git_tags prev_version " $url " " tags/v" " _"
235+ declare -g ${variable_name} =" ${prev_version} "
236+ else
237+ echo -e " \nAttempting to find latest version using GitHub Api."
238+ version=$( echo " $output " | jq -r ' .tag_name' | tr ' _' ' .' )
239+ declare -g ${variable_name} =" ${version# v} "
240+ fi
241+ echo " ${variable_name} =${! variable_name} "
242+ }
243+
244+ get_github_api_repo_url () {
245+ local url=$1
246+ echo " ${url/ https: \/\/ github.com/ https: \/\/ api.github.com\/ repos} /releases/latest"
247+ }
248+
176249
177250# Figure out correct version of a three part version number is not passed
178- find_version_from_git_tags RUBY_VERSION " https://github.com/ruby/ruby" " tags/v" " _"
251+ RUBY_URL=" https://github.com/ruby/ruby"
252+ ORIGINAL_RUBY_VERSION=$RUBY_VERSION
253+ find_version_from_git_tags RUBY_VERSION $RUBY_URL " tags/v" " _"
179254
180- # Just install Ruby if RVM already installed
181- if rvm --version > /dev/null; then
182- echo " Ruby Version Manager already exists."
183- if [[ " $( ruby -v) " = * " ${RUBY_VERSION} " * ]]; then
184- echo " (!) Ruby is already installed with version ${RUBY_VERSION} . Skipping..."
185- elif [ " ${RUBY_VERSION} " != " none" ]; then
186- echo " Installing specified Ruby version."
187- su ${USERNAME} -c " rvm install ruby ${RUBY_VERSION} "
188- fi
189- SKIP_GEM_INSTALL=" false"
190- SKIP_RBENV_RBUILD=" true"
191- else
192- # Install RVM
193- receive_gpg_keys RVM_GPG_KEYS
194- # Determine appropriate settings for rvm installer
255+ set_rvm_install_args () {
256+ RUBY_VERSION=$1
195257 if [ " ${RUBY_VERSION} " = " none" ]; then
196258 RVM_INSTALL_ARGS=" "
197259 elif [[ " $( ruby -v) " = * " ${RUBY_VERSION} " * ]]; then
@@ -210,19 +272,48 @@ else
210272 DEFAULT_GEMS=" "
211273 fi
212274 fi
275+ }
276+
277+ install_previous_version () {
278+ if [[ $ORIGINAL_RUBY_VERSION == " latest" ]]; then
279+ repo_url=$( get_github_api_repo_url " $RUBY_URL " )
280+ get_previous_version " ${RUBY_URL} " " ${repo_url} " RUBY_VERSION
281+ set_rvm_install_args $RUBY_VERSION
282+ curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems=" ${DEFAULT_GEMS} " 2>&1
283+ else
284+ echo " Failed to install Ruby version $ORIGINAL_RUBY_VERSION . Exiting..."
285+ fi
286+ }
287+
288+ # Just install Ruby if RVM already installed
289+ if rvm --version > /dev/null; then
290+ echo " Ruby Version Manager already exists."
291+ if [[ " $( ruby -v) " = * " ${RUBY_VERSION} " * ]]; then
292+ echo " (!) Ruby is already installed with version ${RUBY_VERSION} . Skipping..."
293+ elif [ " ${RUBY_VERSION} " != " none" ]; then
294+ echo " Installing specified Ruby version."
295+ su ${USERNAME} -c " rvm install ruby ${RUBY_VERSION} "
296+ fi
297+ SKIP_GEM_INSTALL=" false"
298+ SKIP_RBENV_RBUILD=" true"
299+ else
300+ # Install RVM
301+ receive_gpg_keys RVM_GPG_KEYS
302+ # Determine appropriate settings for rvm installer
303+ set_rvm_install_args $RUBY_VERSION
213304 # Create rvm group as a system group to reduce the odds of conflict with local user UIDs
214305 if ! cat /etc/group | grep -e " ^rvm:" > /dev/null 2>&1 ; then
215306 groupadd -r rvm
216307 fi
217308 # Install rvm
218- curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems=" ${DEFAULT_GEMS} " 2>&1
309+ curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems=" ${DEFAULT_GEMS} " 2>&1 || install_previous_version
219310 usermod -aG rvm ${USERNAME}
220311 source /usr/local/rvm/scripts/rvm
221312 rvm fix-permissions system
222313 rm -rf ${GNUPGHOME}
223314fi
224315
225- if [ " ${INSTALL_RUBY_TOOLS} " = " true" ]; then
316+ if [ " ${INSTALL_RUBY_TOOLS} " = " true" ]; then
226317 # Non-root user may not have "gem" in path when script is run and no ruby version
227318 # is installed by rvm, so handle this by using root's default gem in this case
228319 ROOT_GEM=" $( which gem || echo " " ) "
@@ -239,7 +330,7 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then
239330 read -a additional_versions <<< " $ADDITIONAL_VERSIONS"
240331 for version in " ${additional_versions[@]} " ; do
241332 # Figure out correct version of a three part version number is not passed
242- find_version_from_git_tags version " https://github.com/ruby/ruby " " tags/v" " _"
333+ find_version_from_git_tags version $RUBY_URL " tags/v" " _"
243334 source /usr/local/rvm/scripts/rvm
244335 rvm install ruby ${version}
245336 done
0 commit comments