Skip to content
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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature to opt-in to get notifications for beta releases #11169

Merged
merged 9 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cmd/minikube/cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ var settings = []Setting{
name: config.WantUpdateNotification,
set: SetBool,
},
{
name: config.WantBetaUpdateNotification,
set: SetBool,
},
{
name: config.ReminderWaitPeriodInHours,
set: SetInt,
Expand Down
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/update-check.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var updateCheckCmd = &cobra.Command{
Long: `Print current and latest version number`,
Run: func(command *cobra.Command, args []string) {
url := notify.GithubMinikubeReleasesURL
r, err := notify.GetAllVersionsFromURL(url)
r, err := notify.AllVersionsFromURL(url)
if err != nil {
exit.Error(reason.InetVersionUnavailable, "Unable to fetch latest version info", err)
}
Expand Down
2 changes: 2 additions & 0 deletions deploy/minikube/releases-beta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
47 changes: 29 additions & 18 deletions hack/jenkins/release_update_releases_json.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ export DARWIN_SHA256=$(cat out/minikube-darwin-amd64.sha256)
export LINUX_SHA256=$(cat out/minikube-linux-amd64.sha256)
export WINDOWS_SHA256=$(cat out/minikube-windows-amd64.exe.sha256)

if ! [[ "${VERSION_BUILD}" =~ ^[0-9]+$ ]]; then
echo "NOTE: ${TAGNAME} appears to be a non-standard release, not updating releases.json"
exit 0
fi

# Update releases.json w/ new release in gcs and github
git config user.name "minikube-bot"
git config user.email "minikube-bot@google.com"
Expand All @@ -43,20 +38,36 @@ git checkout -b "jenkins-releases.json-${TAGNAME}"

git status

#Prepends the new version to the release.json file
sed -i "0,/{/s/{/{\n \"name\": \"${TAGNAME}\",\n \"checksums\": {\n \"darwin\": \"${DARWIN_SHA256}\",\n \"linux\": \"${LINUX_SHA256}\",\n \"windows\": \"${WINDOWS_SHA256}\"\n }\n },\n {"/ deploy/minikube/releases.json
if ! [[ "${VERSION_BUILD}" =~ ^[0-9]+$ ]]; then
#Prepends the new version to the release-beta.json file
sed -i "0,/{/s/{/{\n \"name\": \"${TAGNAME}\",\n \"checksums\": {\n \"darwin\": \"${DARWIN_SHA256}\",\n \"linux\": \"${LINUX_SHA256}\",\n \"windows\": \"${WINDOWS_SHA256}\"\n }\n },\n {"/ deploy/minikube/releases-beta.json

git add -A
git commit -m "Update releases-beta.json to include ${TAGNAME}"
git remote add minikube-bot git@github.com:minikube-bot/minikube.git
git push -f minikube-bot jenkins-releases.json-${TAGNAME}

# Send PR from minikube-bot/minikube to kubernetes/minikube
curl -X POST -u minikube-bot:${BOT_PASSWORD} -k -d "{\"title\": \"update releases-beta.json to include ${TAGNAME}\",\"head\": \"minikube-bot:jenkins-releases.json-${TAGNAME}\",\"base\": \"master\"}" https://api.github.com/repos/kubernetes/minikube/pulls

#Update the front page of our documentation
now=$(date +"%b %d, %Y")
sed -i "s/Latest Release: .* (/Latest Release: ${TAGNAME} - ${now} (/" site/content/en/docs/_index.md
# Upload file to GCS so that minikube can see the new version
gsutil cp deploy/minikube/releases.json gs://minikube/releases-beta.json
else
#Prepends the new version to the release.json file
sed -i "0,/{/s/{/{\n \"name\": \"${TAGNAME}\",\n \"checksums\": {\n \"darwin\": \"${DARWIN_SHA256}\",\n \"linux\": \"${LINUX_SHA256}\",\n \"windows\": \"${WINDOWS_SHA256}\"\n }\n },\n {"/ deploy/minikube/releases.json

git add -A
git commit -m "Update releases.json to include ${TAGNAME}"
git remote add minikube-bot git@github.com:minikube-bot/minikube.git
git push -f minikube-bot jenkins-releases.json-${TAGNAME}
#Update the front page of our documentation
now=$(date +"%b %d, %Y")
sed -i "s/Latest Release: .* (/Latest Release: ${TAGNAME} - ${now} (/" site/content/en/docs/_index.md

# Send PR from minikube-bot/minikube to kubernetes/minikube
curl -X POST -u minikube-bot:${BOT_PASSWORD} -k -d "{\"title\": \"update releases.json to include ${TAGNAME}\",\"head\": \"minikube-bot:jenkins-releases.json-${TAGNAME}\",\"base\": \"master\"}" https://api.github.com/repos/kubernetes/minikube/pulls
git add -A
git commit -m "Update releases.json to include ${TAGNAME}"
git remote add minikube-bot git@github.com:minikube-bot/minikube.git
git push -f minikube-bot jenkins-releases.json-${TAGNAME}

# Upload file to GCS so that minikube can see the new version
gsutil cp deploy/minikube/releases.json gs://minikube/releases.json
# Send PR from minikube-bot/minikube to kubernetes/minikube
curl -X POST -u minikube-bot:${BOT_PASSWORD} -k -d "{\"title\": \"update releases.json to include ${TAGNAME}\",\"head\": \"minikube-bot:jenkins-releases.json-${TAGNAME}\",\"base\": \"master\"}" https://api.github.com/repos/kubernetes/minikube/pulls

# Upload file to GCS so that minikube can see the new version
gsutil cp deploy/minikube/releases.json gs://minikube/releases.json
fi
4 changes: 3 additions & 1 deletion pkg/minikube/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ import (
const (
// WantUpdateNotification is the key for WantUpdateNotification
WantUpdateNotification = "WantUpdateNotification"
// ReminderWaitPeriodInHours is the key for WantUpdateNotification
// WantBetaUpdateNotification is the key for WantBetaUpdateNotification
WantBetaUpdateNotification = "WantBetaUpdateNotification"
// ReminderWaitPeriodInHours is the key for ReminderWaitPeriodInHours
ReminderWaitPeriodInHours = "ReminderWaitPeriodInHours"
// WantReportError is the key for WantReportError
WantReportError = "WantReportError"
Expand Down
2 changes: 2 additions & 0 deletions pkg/minikube/notify/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ package notify
const (
// GithubMinikubeReleasesURL is the URL of the minikube github releases JSON file
GithubMinikubeReleasesURL = "https://storage.googleapis.com/minikube/releases.json"
// GithubMinikubeBetaReleasesURL is the URL of the minikube Github beta releases JSON file
GithubMinikubeBetaReleasesURL = "https://storage.googleapis.com/minikube/releases-beta.json"
)
93 changes: 68 additions & 25 deletions pkg/minikube/notify/notify.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,45 +43,88 @@ var (
)

// MaybePrintUpdateTextFromGithub prints update text if needed, from github
func MaybePrintUpdateTextFromGithub() bool {
return MaybePrintUpdateText(GithubMinikubeReleasesURL, lastUpdateCheckFilePath)
func MaybePrintUpdateTextFromGithub() {
maybePrintUpdateText(GithubMinikubeReleasesURL, GithubMinikubeBetaReleasesURL, lastUpdateCheckFilePath)
}

// MaybePrintUpdateText prints update text, returns a bool if life is good.
func MaybePrintUpdateText(url string, lastUpdatePath string) bool {
func maybePrintUpdateText(latestReleasesURL string, betaReleasesURL string, lastUpdatePath string) {
if !shouldCheckURLVersion(lastUpdatePath) {
return false
return
}
latestVersion, err := getLatestVersionFromURL(url)
latestVersion, err := latestVersionFromURL(latestReleasesURL)
if err != nil {
klog.Warning(err)
return true
return
}
localVersion, err := version.GetSemverVersion()
if err != nil {
klog.Warning(err)
return true
}
if localVersion.Compare(latestVersion) < 0 {
if err := writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC()); err != nil {
klog.Errorf("write time failed: %v", err)
}
url := "https://github.com/kubernetes/minikube/releases/tag/v" + latestVersion.String()
out.Styled(style.Celebrate, `minikube {{.version}} is available! Download it: {{.url}}`, out.V{"version": latestVersion, "url": url})
out.Styled(style.Tip, "To disable this notice, run: 'minikube config set WantUpdateNotification false'\n")
return true
}
return false
return
}
if maybePrintBetaUpdateText(betaReleasesURL, localVersion, latestVersion, lastUpdatePath) {
return
}
if localVersion.Compare(latestVersion) >= 0 {
return
}
printUpdateText(latestVersion)
}

// maybePrintBetaUpdateText returns true if update text is printed
func maybePrintBetaUpdateText(betaReleasesURL string, localVersion semver.Version, latestFullVersion semver.Version, lastUpdatePath string) bool {
if !shouldCheckURLBetaVersion(lastUpdatePath) {
return false
}
latestBetaVersion, err := latestVersionFromURL(betaReleasesURL)
if err != nil {
klog.Warning(err)
return false
}
if latestFullVersion.Compare(latestBetaVersion) >= 0 {
return false
}
if localVersion.Compare(latestBetaVersion) >= 0 {
return false
}
printBetaUpdateText(latestBetaVersion)
return true
}

func printUpdateTextCommon(version semver.Version) {
if err := writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC()); err != nil {
klog.Errorf("write time failed: %v", err)
}
url := "https://github.com/kubernetes/minikube/releases/tag/v" + version.String()
out.Styled(style.Celebrate, `minikube {{.version}} is available! Download it: {{.url}}`, out.V{"version": version, "url": url})
}

func printUpdateText(version semver.Version) {
printUpdateTextCommon(version)
out.Styled(style.Tip, "To disable this notice, run: 'minikube config set WantUpdateNotification false'\n")
}

func printBetaUpdateText(version semver.Version) {
printUpdateTextCommon(version)
out.Styled(style.Tip, "To disable beta notices, run: 'minikube config set WantBetaUpdateNotification false'")
out.Styled(style.Tip, "To disable update notices in general, run: 'minikube config set WantUpdateNotification false'\n")
}

func shouldCheckURLVersion(filePath string) bool {
if !viper.GetBool(config.WantUpdateNotification) {
return false
}
lastUpdateTime := getTimeFromFileIfExists(filePath)
lastUpdateTime := timeFromFileIfExists(filePath)
return time.Since(lastUpdateTime).Hours() >= viper.GetFloat64(config.ReminderWaitPeriodInHours)
}

func shouldCheckURLBetaVersion(filePath string) bool {
if !viper.GetBool(config.WantBetaUpdateNotification) {
return false
}

return shouldCheckURLVersion(filePath)
}

// Release represents a release
type Release struct {
Name string
Expand Down Expand Up @@ -112,16 +155,16 @@ func getJSON(url string, target *Releases) error {
return json.NewDecoder(resp.Body).Decode(target)
}

func getLatestVersionFromURL(url string) (semver.Version, error) {
r, err := GetAllVersionsFromURL(url)
var latestVersionFromURL = func(url string) (semver.Version, error) {
r, err := AllVersionsFromURL(url)
if err != nil {
return semver.Version{}, err
}
return semver.Make(strings.TrimPrefix(r[0].Name, version.VersionPrefix))
}

// GetAllVersionsFromURL get all versions from a JSON URL
func GetAllVersionsFromURL(url string) (Releases, error) {
// AllVersionsFromURL get all versions from a JSON URL
func AllVersionsFromURL(url string) (Releases, error) {
var releases Releases
klog.Info("Checking for updates...")
if err := getJSON(url, &releases); err != nil {
Expand All @@ -141,7 +184,7 @@ func writeTimeToFile(path string, inputTime time.Time) error {
return nil
}

func getTimeFromFileIfExists(path string) time.Time {
func timeFromFileIfExists(path string) time.Time {
lastUpdateCheckTime, err := ioutil.ReadFile(path)
if err != nil {
return time.Time{}
Expand Down
Loading