-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
github-cli: simplify logic for detecting available gh releases #318
Conversation
This change relies on `git ls-remote --tags --sort=version:refname` to sort git versions in a semver-compatible mode and alleviate the need to scan for version numbers manually. The new approach selects at most two latest releases that match VERSION and installs the first `.deb` that was successfully downloaded from a GitHub CLI release. This also removes support for installing a specific version number with `apt-get install gh=VERSION`, since the GitHub CLI package repository does not retain older gh versions and only allows installing the latest one. Finally, this removes version-selecting tests that only tested an implementation that was entirely contained within tests. Bonuses: - Only install curl, apt-transport-https, dirmngr, gnupg2 when needed. - Ensure `apt-get update` runs at most once. - Remove the side-effect of `/var/lib/apt/lists` being wiped out when the github-cli feature is activated. - Add ability to export bash functions for testing: `TEST_EXPORT=find_version_from_git_tags ./src/github-cli/install.sh` - Errors are printed to stderr.
none ) | ||
# opt out of installing gh | ||
exit 0 | ||
;; | ||
latest | lts | stable | current ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is my interpretation of "version": "none"
and "version": "current"
correct? I wasn't sure how those values are supposed to be handled since they aren't documented
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current proposals
property mentions latest
and none
. But if the gihutb-cli supports other keywords, then it's nice to add. Thanks!
Feel free to update the proposals here as well - here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From existing code, it looked like github-cli
feature supported many different keywords, but I only want to support the old ones for backwards compatibility and not actively suggest their use. I do not even understand what none
is about. The usages I'd like to document are:
"version": "latest"
- default"version": "2.20.1"
- lock to a specific version"version": "2.20"
- install the latest 2.20.x"version": "2"
- install the latest 2.x
Any suggestions how to best document this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, for version
option we are accepting semver values so I think it should be self explanatory of how versions are computed. However, it's great to document and make the usage clearer. Feel free to add a NOTES.md
file in https://github.com/devcontainers/features/tree/main/src/github-cli. The action would automatically add the contents to the README file.
(example - docker-in-docker)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome! Thank you for providing a cleaner and sleek approach for detecting releases. Much appreciated 馃憦
I have left some comments/questions. Would appreciate if you could help add tests to validate this change. Also, looks like there is one failing test 馃槃
@@ -9,6 +9,7 @@ | |||
|
|||
CLI_VERSION=${VERSION:-"latest"} | |||
INSTALL_DIRECTLY_FROM_GITHUB_RELEASE=${INSTALLDIRECTLYFROMGITHUBRELEASE:-"true"} | |||
TEST_EXPORT=${TEST_EXPORT:-} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add ability to export bash functions for testing: TEST_EXPORT=find_version_from_git_tags ./src/github-cli/install.sh
Could you help me explain the scenarios in which this is helpful? I read this part 鈽濓笍 , but usually tests for Features are run with devcontainers features test
cmd. Curious to understand your thought behind it's usage 馃槃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used this "export" mechanism in my development to manually test a single bash function from the install.sh
script without running the whole install.sh
script (which wouldn't even work on macOS). I noticed that you copied over bash functions for testing into the test.sh
script, and with this mechanism you could possibly export functions for testing in CI rather that copying over the functions. However, I haven't made use of that in the current PR, and I'm not really attached to the TEST_EXPORT mechanism either. We could also just drop it from the final implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. I agree that if we aren't planning to make use of it, it's great to drop the changes. thanks!
@@ -17,11 +18,8 @@ keyserver hkp://keyserver.pgp.com" | |||
|
|||
set -e | |||
|
|||
# Clean up |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR #210 intentionally added the cleaning up of old packages at the start and end of the script (for all Features) which makes sense to me. Hence, each Feature cleans up the cache and starts afresh. Do you have any other thoughts where this would not be helpful ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for linking to the more general PR. I did not realize this pattern spans multiple different features.
I found it odd that simply activating the github-cli
feature would have side-effects on the apt-get mechanism, even if apt-get update
wasn't invoked at all. Also, /var/lib/apt/lists
is an implementation detail of apt-get and I don't think it's healthy for scripts like ours to rely on it in the long run. Finally, I find that cleaning the /var/lib/apt/lists
cache after the script is done is unnecessary as caches exist for a reason. So my suggestion would be to just do apt-get update
once, then apt-get install
a few times to get what we need, and to leave everything else to the system.
echo "Running apt-get update..." | ||
apt-get update -y | ||
fi | ||
ran_apt_get_update="false" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we decide to re-add the Cleanup, we could remove this change as well 馃槃
declare -g ${variable_name}="${major}.${minor}.${breakfix}" | ||
fi | ||
local prefix="${1:-}" | ||
git ls-remote --tags --sort=-version:refname https://github.com/cli/cli.git | while read -r _ ref; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah! This looks so much cleaner and nicer 馃憦
Wondering, if you could add few test scenarios to validate that these changes work as expected?
We have some guidance on how write tests here - https://github.com/devcontainers/cli/blob/main/docs/features/test.md#scenarios
Also, this repo has quite a few samples (eg - dotnet)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the pointers! I'll try to do that
# the exact version is specified explicitly | ||
versions=( "$CLI_VERSION" ) | ||
;; | ||
* ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also add another case for *.*
? that's something users might use as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, but the case for *.*
is already handled by the general fallback case *
, which will also match *.*
.
none ) | ||
# opt out of installing gh | ||
exit 0 | ||
;; | ||
latest | lts | stable | current ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current proposals
property mentions latest
and none
. But if the gihutb-cli supports other keywords, then it's nice to add. Thanks!
Feel free to update the proposals here as well - here
. /etc/os-release | ||
receive_gpg_keys GITHUB_CLI_ARCHIVE_GPG_KEY /usr/share/keyrings/githubcli-archive-keyring.gpg | ||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list | ||
apt-get update | ||
apt-get -y install "gh${version_suffix}" | ||
apt-get -y install gh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to know. Thanks!
Can we also add a description to installDirectlyFromGitHubRelease property to prompt that?
Something like 馃憞
If false, it installs the latest version of GitHub CLI
Looking at the CI failure: it looks like the git version on Bionic is too old to support the |
Hi @mislav 馃憢 This PR would be super useful and will improve the current Feature. Let me know if I could somehow help to push it through. thanks! |
@samruddhikhandale Thanks; I intend to finish this PR soon by addressing review comments.
|
Thanks for all your guidance @samruddhikhandale, but I'm going to close this because it's no longer needed. In GitHub CLI we've just changed our deployment process so that release assets are published at the same time as the git tag itself. Therefore, there isn't a period of time anymore where a git tag exists but the assets do not exist, so there is no need for a fallback mechanism to select the previous git tag. |
Nice, that's awesome. Thank you for the update! |
This change relies on
git ls-remote --tags --sort=version:refname
to sort git versions in a semver-compatible mode and alleviate the need to scan for version numbers manually. The new approach selects at most two latest releases that match VERSION and installs the first.deb
that was successfully downloaded from a GitHub CLI release.This also removes support for installing a specific version number with
apt-get install gh=VERSION
, since the GitHub CLI package repository does not retain older gh versions and only allows installing the latest one.Finally, this removes version-selecting tests that only tested an implementation that was entirely contained within tests.
Bonuses:
apt-get update
runs at most once./var/lib/apt/lists
being wiped out when the github-cli feature is activated.TEST_EXPORT=find_version_from_git_tags ./src/github-cli/install.sh
Followup to #310
/cc @samruddhikhandale: I thought I'd take a stab at reducing the size of the implementation so that the github-cli feature is easier to maintain over time. I hope this can be useful! 馃檱