diff --git a/CHANGELOG.md b/CHANGELOG.md index 9592e6d49f7..2b5fe455aa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to Sourcegraph are documented in this file. ### Added - Added topQueries to the GraphQL API. +- Admins can now turn off site alerts for minor and patch version updates using the `alerts.showMinorUpdates` setting. Alerts will still be shown for major version updates. ### Changed diff --git a/package.json b/package.json index 92517e93030..7bafb381e0d 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "@types/react-visibility-sensor": "5.0.1", "@types/reactstrap": "8.0.1", "@types/sanitize-html": "1.18.3", + "@types/semver": "^6.0.0", "@types/shelljs": "0.8.5", "@types/shelljs-exec-proxy": "0.1.0", "@types/signale": "1.2.1", @@ -236,6 +237,7 @@ "reactstrap": "https://registry.npmjs.org/@sqs/reactstrap/-/reactstrap-6.5.0-tmp1.tgz", "rxjs": "^6.4.0", "sanitize-html": "^1.20.0", + "semver": "^6.0.0", "sourcegraph": "link:packages/sourcegraph-extension-api", "string-score": "^1.0.1", "symbol-observable": "^1.2.0", diff --git a/schema/schema.go b/schema/schema.go index a80a9144e16..e27fcb42c00 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -402,6 +402,7 @@ type Sentry struct { // Settings description: Configuration settings for users and organizations on Sourcegraph. type Settings struct { + AlertsShowPatchUpdates bool `json:"alerts.showPatchUpdates,omitempty"` Extensions map[string]bool `json:"extensions,omitempty"` Motd []string `json:"motd,omitempty"` Notices []*Notice `json:"notices,omitempty"` diff --git a/schema/settings.schema.json b/schema/settings.schema.json index f87f847593b..1764ec24758 100644 --- a/schema/settings.schema.json +++ b/schema/settings.schema.json @@ -94,6 +94,11 @@ } } }, + "alerts.showPatchUpdates": { + "description": "Whether to show alerts for patch version updates. Alerts for major and minor version updates will always be shown.", + "type": "boolean", + "default": true + }, "extensions": { "description": "The Sourcegraph extensions to use. Enable an extension by adding a property `\"my/extension\": true` (where `my/extension` is the extension ID). Override a previously enabled extension and disable it by setting its value to `false`.", "type": "object", diff --git a/schema/settings_stringdata.go b/schema/settings_stringdata.go index a0011aa08ca..5e36c457455 100644 --- a/schema/settings_stringdata.go +++ b/schema/settings_stringdata.go @@ -99,6 +99,11 @@ const SettingsSchemaJSON = `{ } } }, + "alerts.showPatchUpdates": { + "description": "Whether to show alerts for patch version updates. Alerts for major and minor version updates will always be shown.", + "type": "boolean", + "default": true + }, "extensions": { "description": "The Sourcegraph extensions to use. Enable an extension by adding a property ` + "`" + `\"my/extension\": true` + "`" + ` (where ` + "`" + `my/extension` + "`" + ` is the extension ID). Override a previously enabled extension and disable it by setting its value to ` + "`" + `false` + "`" + `.", "type": "object", diff --git a/web/src/global/GlobalAlerts.tsx b/web/src/global/GlobalAlerts.tsx index 0e6a4a3a05b..818596acd0e 100644 --- a/web/src/global/GlobalAlerts.tsx +++ b/web/src/global/GlobalAlerts.tsx @@ -2,6 +2,7 @@ import { parseISO } from 'date-fns' import differenceInDays from 'date-fns/differenceInDays' import * as React from 'react' import { Subscription } from 'rxjs' +import * as semver from 'semver' import { Markdown } from '../../../shared/src/components/Markdown' import { isSettingsValid, SettingsCascadeProps } from '../../../shared/src/settings/settings' import { renderMarkdown } from '../../../shared/src/util/markdown' @@ -57,7 +58,13 @@ export class GlobalAlerts extends React.PureComponent { {this.props.isSiteAdmin && this.state.siteFlags.updateCheck && !this.state.siteFlags.updateCheck.errorMessage && - this.state.siteFlags.updateCheck.updateVersionAvailable && ( + this.state.siteFlags.updateCheck.updateVersionAvailable && + ((isSettingsValid(this.props.settingsCascade) && + this.props.settingsCascade.final['alerts.showPatchUpdates'] !== false) || + isMinorUpdateAvailable( + this.state.siteFlags.productVersion, + this.state.siteFlags.updateCheck.updateVersionAvailable + )) && ( { ) } } + +function isMinorUpdateAvailable(currentVersion: string, updateVersion: string): boolean { + const cv = semver.parse(currentVersion, { loose: false }) + const uv = semver.parse(updateVersion, { loose: false }) + // If either current or update versions aren't semvers (e.g., a user is on a date-based build version, or "dev"), + // always return true and allow any alerts to be shown. This has the effect of simply deferring to the response + // from Sourcegraph.com about whether an update alert is needed. + if (cv === null || uv === null) { + return true + } + return semver.major(cv) !== semver.major(uv) || semver.minor(cv) !== semver.minor(uv) +} diff --git a/web/src/site/backend.tsx b/web/src/site/backend.tsx index c7efaba840e..0904f79ce16 100644 --- a/web/src/site/backend.tsx +++ b/web/src/site/backend.tsx @@ -55,6 +55,7 @@ export function refreshSiteFlags(): Observable { } noLicenseWarningUserCount } + productVersion } } `) diff --git a/web/src/site/index.ts b/web/src/site/index.ts index 31cfc249658..0a64c933bce 100644 --- a/web/src/site/index.ts +++ b/web/src/site/index.ts @@ -11,4 +11,5 @@ export type SiteFlags = Pick< | 'sendsEmailVerificationEmails' | 'updateCheck' | 'productSubscription' + | 'productVersion' > diff --git a/yarn.lock b/yarn.lock index bc907f7bbf9..0adbe30fb01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2526,6 +2526,11 @@ dependencies: "@types/htmlparser2" "*" +"@types/semver@^6.0.0": + version "6.0.0" + resolved "https://registry.npmjs.org/@types/semver/-/semver-6.0.0.tgz#86ba89f02a414e39c68d02b351872e4ed31bd773" + integrity sha512-OO0srjOGH99a4LUN2its3+r6CBYcplhJ466yLqs+zvAWgphCpS8hYZEZ797tRDP/QKcqTdb/YCN6ifASoAWkrQ== + "@types/serve-static@*": version "1.13.2" resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48"