From b74cc14b727b93bec60e2f75ea69ae3e01753649 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 24 Feb 2023 14:45:17 -0800 Subject: [PATCH] Release 6.4.0-beta.17 (#7237) * Various improvements to release-tool (#7232) * Various improvements to release-tool - Pass more IO from script to user to provide better UX - Interactive versioning using lerna directly - Remove all CMD args in favour of interactive Signed-off-by: Sebastian Malton * Remove some more unnecessary console logs Signed-off-by: Sebastian Malton * Resolve comments Signed-off-by: Sebastian Malton * Fix repoRoot issue Signed-off-by: Sebastian Malton * De-spagetti-ify release-tool Signed-off-by: Sebastian Malton * Fix bugs related to picking PRs Signed-off-by: Sebastian Malton * Fix name Signed-off-by: Sebastian Malton * Improve display after picking PRs Signed-off-by: Sebastian Malton * Rename pickWhichPRsToUse Signed-off-by: Sebastian Malton * Add line describing what to do Signed-off-by: Sebastian Malton * Fix not displaying output after cherry-pick fails Signed-off-by: Sebastian Malton --------- Signed-off-by: Sebastian Malton Co-authored-by: Roman Signed-off-by: Sebastian Malton * Fix ApiManager not handling duplicate apiBases of KubeApis (#7235) * Add failing unit test Signed-off-by: Sebastian Malton * Fix failing unit test Signed-off-by: Sebastian Malton --------- Signed-off-by: Sebastian Malton * Allow extensions to opt-out of KubeApi auto registering (#7217) Signed-off-by: Sebastian Malton * Remove all references to slack (#7233) * Remove all references to slack Signed-off-by: Sebastian Malton * Fix readme Signed-off-by: Sebastian Malton * Cleanup migration Signed-off-by: Sebastian Malton * Remove existing slack link from weblink store Signed-off-by: Sebastian Malton * Fix type error and wording on ErrorBoundary Signed-off-by: Sebastian Malton * Don't export forumsUrl to extension API - Also just remove slack URL Signed-off-by: Sebastian Malton * Update snapshots again Signed-off-by: Sebastian Malton * Update snapshots again v3 Signed-off-by: Sebastian Malton * Revert remove slackUrl Signed-off-by: Sebastian Malton * Fix filtering Signed-off-by: Sebastian Malton * Fix readme Signed-off-by: Sebastian Malton * More of a fix Signed-off-by: Sebastian Malton * Try again Signed-off-by: Sebastian Malton * Slightly better for now Signed-off-by: Sebastian Malton --------- Signed-off-by: Sebastian Malton * "Release 6.4.0-beta.17" Signed-off-by: Sebastian Malton --------- Signed-off-by: Sebastian Malton Co-authored-by: Roman --- README.md | 6 +- docs/README.md | 20 +- lerna.json | 2 +- mkdocs.yml | 48 +- packages/core/package.json | 2 +- .../k8s-api/__tests__/api-manager.test.ts | 38 +- .../common/k8s-api/api-manager/api-manager.ts | 9 +- packages/core/src/common/vars.ts | 2 +- .../core/src/extensions/common-api/app.ts | 7 +- .../core/src/extensions/common-api/k8s-api.ts | 18 +- ...acters-in-page-registrations.test.tsx.snap | 4 +- .../navigate-to-extension-page.test.tsx.snap | 4 +- ...ation-using-application-menu.test.tsx.snap | 4 +- .../installing-update.test.ts.snap | 24 +- ...g-update-using-topbar-button.test.tsx.snap | 8 +- .../installing-update-using-tray.test.ts.snap | 24 +- .../__snapshots__/force-update.test.ts.snap | 12 +- ...eriodical-checking-of-updates.test.ts.snap | 4 +- ...selection-of-update-stability.test.ts.snap | 4 +- .../opening-entity-details.test.tsx.snap | 4 +- .../keyboard-shortcuts.test.tsx.snap | 32 +- ...-settings-for-correct-entity.test.tsx.snap | 4 +- ...gation-using-application-menu.test.ts.snap | 4 +- ...gation-using-application-menu.test.ts.snap | 4 +- .../navigation-using-tray.test.ts.snap | 4 +- ...-originating-from-extensions.test.tsx.snap | 4 +- ...dability-using-extension-api.test.tsx.snap | 16 +- ...gation-using-application-menu.test.ts.snap | 8 +- .../core/src/main/weblinks-store/links.ts | 4 +- .../migrations/5.1.4.injectable.ts | 4 +- .../migrations/5.4.5-beta.1.injectable.ts | 36 +- .../migrations/currentVersion.injectable.ts | 14 +- .../renderer/components/+welcome/welcome.tsx | 6 +- .../error-boundary/error-boundary.tsx | 10 +- packages/extension-api/package.json | 4 +- packages/open-lens/package.json | 4 +- packages/release-tool/package.json | 13 +- packages/release-tool/src/index.ts | 508 +++++++++--------- 38 files changed, 500 insertions(+), 423 deletions(-) diff --git a/README.md b/README.md index 3949cb23c8..f97e647c6d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Lens Desktop Core ("OpenLens") [![Build Status](https://github.com/lensapp/lens/actions/workflows/test.yml/badge.svg)](https://github.com/lensapp/lens/actions/workflows/test.yml) -[![Chat on Slack](https://img.shields.io/badge/chat-on%20slack-blue.svg?logo=slack&longCache=true&style=flat)](https://k8slens.dev/slack.html) +[Explore our Forums](https://forums.k8slens.dev) ## The Repository -This repository is where Team Lens develops the core of the [Lens Desktop](https://k8slens.dev) product together with the community. +This repository is where Team Lens develops the core of the [Lens Desktop](https://k8slens.dev) product together with the community. The core is a library, powered by [Electron](https://www.electronjs.org/) and [React](https://reactjs.org/). Unlike generic Electron + React frameworks / boilerplates, it is very opinionated for creating Lens Desktop-like applications and has support for Lens Extensions. @@ -31,4 +31,4 @@ See [Contributing](https://docs.k8slens.dev/contributing/) page. ## License -See [License](LICENSE). \ No newline at end of file +See [License](LICENSE). diff --git a/docs/README.md b/docs/README.md index 67369f86fc..b22509eb16 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,15 +7,15 @@ To install your first extension you should goto the [extension page](lens://app/ This documentation describes: -* How to build, run, test, and publish an extension. -* How to take full advantage of the Lens Extension API. -* Where to find [guides](extensions/guides/README.md) and [code samples](https://github.com/lensapp/lens-extension-samples) to help get you started. +- How to build, run, test, and publish an extension. +- How to take full advantage of the Lens Extension API. +- Where to find [guides](extensions/guides/README.md) and [code samples](https://github.com/lensapp/lens-extension-samples) to help get you started. ## What Extensions Can Do Here are some examples of what you can achieve with the Extension API: -* Add custom components & views in the UI - Extending the Lens Workbench +- Add custom components & views in the UI - Extending the Lens Workbench For an overview of the Lens Extension API, refer to the [Common Capabilities](extensions/capabilities/common-capabilities.md) page. [Extension Guides Overview](extensions/guides/README.md) also includes a list of code samples and guides that illustrate various ways of using the Lens Extension API. @@ -23,11 +23,11 @@ For an overview of the Lens Extension API, refer to the [Common Capabilities](ex Here is what each section of the Lens Extension API docs can help you with: -* **Getting Started** teaches fundamental concepts for building extensions with the Hello World sample. -* **Extension Capabilities** dissects Lens's Extension API into smaller categories and points you to more detailed topics. -* **Extension Guides** includes guides and code samples that explain specific usages of Lens Extension API. -* **Testing and Publishing** includes in-depth guides on various extension development topics, such as testing and publishing extensions. -* **API Reference** contains exhaustive references for the Lens Extension API, Contribution Points, and many other topics. +- **Getting Started** teaches fundamental concepts for building extensions with the Hello World sample. +- **Extension Capabilities** dissects Lens's Extension API into smaller categories and points you to more detailed topics. +- **Extension Guides** includes guides and code samples that explain specific usages of Lens Extension API. +- **Testing and Publishing** includes in-depth guides on various extension development topics, such as testing and publishing extensions. +- **API Reference** contains exhaustive references for the Lens Extension API, Contribution Points, and many other topics. ## What's New @@ -45,7 +45,7 @@ See the [Lens v4 to v5 extension migration notes](extensions/extension-migration ## Looking for Help -If you have questions for extension development, try asking on the [Lens Dev Slack](http://k8slens.slack.com/). It's a public chatroom for Lens developers, where Lens team members chime in from time to time. +If you have questions for extension development, try asking on the [Lens Forums](http://forums.k8slens.dev/). It's a public chatroom for Lens developers, where Lens team members chime in from time to time. To provide feedback on the documentation or issues with the Lens Extension API, create new issues at [lensapp/lens](https://github.com/lensapp/lens/issues). Please use the labels `area/documentation` and/or `area/extension`. diff --git a/lerna.json b/lerna.json index 47c3e3a10d..a712b8a78b 100644 --- a/lerna.json +++ b/lerna.json @@ -4,7 +4,7 @@ "packages": [ "packages/*" ], - "version": "6.4.0-beta.16", + "version": "6.4.0-beta.17", "npmClient": "yarn", "npmClientArgs": [ "--network-timeout=100000" diff --git a/mkdocs.yml b/mkdocs.yml index b869a63ee9..e0f1568b87 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,33 +10,33 @@ edit_uri: "" nav: - Overview: README.md - Getting Started: - - Overview: extensions/get-started/overview.md - - Your First Extension: extensions/get-started/your-first-extension.md - - Extension Anatomy: extensions/get-started/anatomy.md - - Wrapping Up: extensions/get-started/wrapping-up.md + - Overview: extensions/get-started/overview.md + - Your First Extension: extensions/get-started/your-first-extension.md + - Extension Anatomy: extensions/get-started/anatomy.md + - Wrapping Up: extensions/get-started/wrapping-up.md - Extension Capabilities: - - Common Capabilities: extensions/capabilities/common-capabilities.md - - Styling: extensions/capabilities/styling.md + - Common Capabilities: extensions/capabilities/common-capabilities.md + - Styling: extensions/capabilities/styling.md - Extension Guides: - - Overview: extensions/guides/README.md - - Generator: extensions/guides/generator.md - - Main Extension: extensions/guides/main-extension.md - - Renderer Extension: extensions/guides/renderer-extension.md - - Catalog: extensions/guides/catalog.md - - Resource Stack: extensions/guides/resource-stack.md - - Extending KubernetesCluster: extensions/guides/extending-kubernetes-cluster.md - - Stores: extensions/guides/stores.md - - Working with MobX: extensions/guides/working-with-mobx.md - - Protocol Handlers: extensions/guides/protocol-handlers.md - - IPC: extensions/guides/ipc.md + - Overview: extensions/guides/README.md + - Generator: extensions/guides/generator.md + - Main Extension: extensions/guides/main-extension.md + - Renderer Extension: extensions/guides/renderer-extension.md + - Catalog: extensions/guides/catalog.md + - Resource Stack: extensions/guides/resource-stack.md + - Extending KubernetesCluster: extensions/guides/extending-kubernetes-cluster.md + - Stores: extensions/guides/stores.md + - Working with MobX: extensions/guides/working-with-mobx.md + - Protocol Handlers: extensions/guides/protocol-handlers.md + - IPC: extensions/guides/ipc.md - Testing and Publishing: - - Testing Extensions: extensions/testing-and-publishing/testing.md - - Publishing Extensions: extensions/testing-and-publishing/publishing.md + - Testing Extensions: extensions/testing-and-publishing/testing.md + - Publishing Extensions: extensions/testing-and-publishing/publishing.md - API Reference: extensions/api/README.md theme: - name: 'material' + name: "material" highlightjs: true - language: 'en' + language: "en" custom_dir: docs/custom_theme favicon: img/favicon.ico logo: img/lens-logo-icon.svg @@ -79,9 +79,9 @@ extra: - icon: fontawesome/brands/twitter link: https://twitter.com/k8slens name: Lens on Twitter - - icon: fontawesome/brands/slack - link: http://k8slens.slack.com/ - name: Lens on Slack + - icon: fontawesome/brands/discourse + link: https://forums.k8slens.dev/ + name: Lens Forums - icon: fontawesome/solid/link link: https://k8slens.dev/ name: Lens Website diff --git a/packages/core/package.json b/packages/core/package.json index 017ca3bbb9..6baf203523 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -3,7 +3,7 @@ "productName": "", "description": "Lens Desktop Core", "homepage": "https://github.com/lensapp/lens", - "version": "6.4.0-beta.16", + "version": "6.4.0-beta.17", "repository": { "type": "git", "url": "git+https://github.com/lensapp/lens.git" diff --git a/packages/core/src/common/k8s-api/__tests__/api-manager.test.ts b/packages/core/src/common/k8s-api/__tests__/api-manager.test.ts index b83f52c3f0..2e7e545f76 100644 --- a/packages/core/src/common/k8s-api/__tests__/api-manager.test.ts +++ b/packages/core/src/common/k8s-api/__tests__/api-manager.test.ts @@ -19,6 +19,9 @@ import { KubeObject } from "../kube-object"; import { KubeObjectStore } from "../kube-object.store"; import maybeKubeApiInjectable from "../maybe-kube-api.injectable"; +// eslint-disable-next-line no-restricted-imports +import { KubeApi as ExternalKubeApi } from "../../../extensions/common-api/k8s-api"; + class TestApi extends KubeApi { protected async checkPreferredVersion() { return; @@ -54,7 +57,7 @@ describe("ApiManager", () => { }); describe("registerApi", () => { - it("re-register store if apiBase changed", async () => { + it("re-register store if apiBase changed", () => { const apiBase = "apis/v1/foo"; const fallbackApiBase = "/apis/extensions/v1beta1/foo"; const kubeApi = new TestApi({ @@ -72,21 +75,48 @@ describe("ApiManager", () => { logger: di.inject(loggerInjectable), }, kubeApi); - apiManager.registerApi(apiBase, kubeApi); + apiManager.registerApi(kubeApi); // Define to use test api for ingress store Object.defineProperty(kubeStore, "api", { value: kubeApi }); - apiManager.registerStore(kubeStore, [kubeApi]); + apiManager.registerStore(kubeStore); // Test that store is returned with original apiBase expect(apiManager.getStore(kubeApi)).toBe(kubeStore); // Change apiBase similar as checkPreferredVersion does Object.defineProperty(kubeApi, "apiBase", { value: fallbackApiBase }); - apiManager.registerApi(fallbackApiBase, kubeApi); + apiManager.registerApi(kubeApi); // Test that store is returned with new apiBase expect(apiManager.getStore(kubeApi)).toBe(kubeStore); }); }); + + describe("technical tests for autorun", () => { + it("given two extensions register apis with the same apibase, settle into using the second", () => { + const apiBase = "/apis/aquasecurity.github.io/v1alpha1/vulnerabilityreports"; + const firstApi = Object.assign(new ExternalKubeApi({ + objectConstructor: KubeObject, + apiBase, + kind: "VulnerabilityReport", + }), { + myField: 1, + }); + const secondApi = Object.assign(new ExternalKubeApi({ + objectConstructor: KubeObject, + apiBase, + kind: "VulnerabilityReport", + }), { + myField: 2, + }); + + void firstApi; + void secondApi; + + expect(apiManager.getApi(apiBase)).toMatchObject({ + myField: 2, + }); + }); + }); }); diff --git a/packages/core/src/common/k8s-api/api-manager/api-manager.ts b/packages/core/src/common/k8s-api/api-manager/api-manager.ts index 81b59ef9c2..0dad9a2a21 100644 --- a/packages/core/src/common/k8s-api/api-manager/api-manager.ts +++ b/packages/core/src/common/k8s-api/api-manager/api-manager.ts @@ -41,19 +41,22 @@ export class ApiManager { const apis = chain(this.dependencies.apis.get().values()) .concat(this.externalApis.values()); const removedApis = new Set(this.apis.values()); + const newState = new Map(this.apis); for (const api of apis) { removedApis.delete(api); - this.apis.set(api.apiBase, api); + newState.set(api.apiBase, api); } for (const api of removedApis) { - for (const [apiBase, storedApi] of this.apis) { + for (const [apiBase, storedApi] of newState) { if (storedApi === api) { - this.apis.delete(apiBase); + newState.delete(apiBase); } } } + + this.apis.replace(newState); }); } diff --git a/packages/core/src/common/vars.ts b/packages/core/src/common/vars.ts index 8f53d6354c..f4c19c16e6 100644 --- a/packages/core/src/common/vars.ts +++ b/packages/core/src/common/vars.ts @@ -18,6 +18,6 @@ export const apiKubePrefix = "/api-kube"; // k8s cluster apis // Links export const issuesTrackerUrl = "https://github.com/lensapp/lens/issues" as string; -export const slackUrl = "https://k8slens.dev/slack.html" as string; export const supportUrl = "https://docs.k8slens.dev/support/" as string; export const docsUrl = "https://docs.k8slens.dev" as string; +export const forumsUrl = "https://forums.k8slens.dev" as string; diff --git a/packages/core/src/extensions/common-api/app.ts b/packages/core/src/extensions/common-api/app.ts index dd9227cd0e..8c190b984b 100644 --- a/packages/core/src/extensions/common-api/app.ts +++ b/packages/core/src/extensions/common-api/app.ts @@ -11,7 +11,7 @@ import isWindowsInjectable from "../../common/vars/is-windows.injectable"; import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api"; import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import getEnabledExtensionsInjectable from "./get-enabled-extensions/get-enabled-extensions.injectable"; -import { slackUrl, issuesTrackerUrl } from "../../common/vars"; +import { issuesTrackerUrl } from "../../common/vars"; import { buildVersionInjectionToken } from "../../common/vars/build-semantic-version.injectable"; import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api"; import userStoreInjectable from "../../common/user-store/user-store.injectable"; @@ -53,6 +53,9 @@ export const App = { return di.inject(isLinuxInjectable); }, - slackUrl, + /** + * @deprecated This value is now `""` and is left here for backwards compatability. + */ + slackUrl: "", issuesTrackerUrl, } as const; diff --git a/packages/core/src/extensions/common-api/k8s-api.ts b/packages/core/src/extensions/common-api/k8s-api.ts index 0b9a05353f..20e687ff6d 100644 --- a/packages/core/src/extensions/common-api/k8s-api.ts +++ b/packages/core/src/extensions/common-api/k8s-api.ts @@ -47,17 +47,29 @@ const getKubeApiDeps = (): KubeApiDependencies => { }; }; +export interface ExternalKubeApiOptions { + /** + * If `true` then on creation of the `KubeApi`instance a call to `apiManager.registerApi` will be + * made. This is `true` by default to maintain backwards compatability. + * + * Setting this to `false` might make `KubeObject`'s details drawer stop working. + * + * @default true + */ + autoRegister?: boolean; +} + // NOTE: this is done to preserve `instanceOf` behaviour function KubeApiCstr< Object extends KubeObject = KubeObject, Data extends KubeJsonApiDataFor = KubeJsonApiDataFor, ->(opts: KubeApiOptions) { +>({ autoRegister = true, ...opts }: KubeApiOptions & ExternalKubeApiOptions) { const api = new InternalKubeApi(getKubeApiDeps(), opts); const di = getLegacyGlobalDiForExtensionApi(); const storesAndApisCanBeCreated = di.inject(storesAndApisCanBeCreatedInjectionToken); - if (storesAndApisCanBeCreated) { + if (storesAndApisCanBeCreated && autoRegister) { apiManager.registerApi(api); } @@ -72,7 +84,7 @@ export type KubeApi< export const KubeApi = KubeApiCstr as unknown as new< Object extends KubeObject = KubeObject, Data extends KubeJsonApiDataFor = KubeJsonApiDataFor, ->(opts: KubeApiOptions) => InternalKubeApi; +>(opts: KubeApiOptions & ExternalKubeApiOptions) => InternalKubeApi; /** * @deprecated Switch to using `Common.createResourceStack` instead diff --git a/packages/core/src/features/__snapshots__/extension-special-characters-in-page-registrations.test.tsx.snap b/packages/core/src/features/__snapshots__/extension-special-characters-in-page-registrations.test.tsx.snap index ccf3a4153f..03e2a2cd8a 100644 --- a/packages/core/src/features/__snapshots__/extension-special-characters-in-page-registrations.test.tsx.snap +++ b/packages/core/src/features/__snapshots__/extension-special-characters-in-page-registrations.test.tsx.snap @@ -107,11 +107,11 @@ exports[`extension special characters in page registrations renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/__snapshots__/navigate-to-extension-page.test.tsx.snap b/packages/core/src/features/__snapshots__/navigate-to-extension-page.test.tsx.snap index b66ac6c4b3..5a864f8096 100644 --- a/packages/core/src/features/__snapshots__/navigate-to-extension-page.test.tsx.snap +++ b/packages/core/src/features/__snapshots__/navigate-to-extension-page.test.tsx.snap @@ -107,11 +107,11 @@ exports[`navigate to extension page renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/add-cluster/__snapshots__/navigation-using-application-menu.test.tsx.snap b/packages/core/src/features/add-cluster/__snapshots__/navigation-using-application-menu.test.tsx.snap index 28cdcc4b8d..4bd662e2f0 100644 --- a/packages/core/src/features/add-cluster/__snapshots__/navigation-using-application-menu.test.tsx.snap +++ b/packages/core/src/features/add-cluster/__snapshots__/navigation-using-application-menu.test.tsx.snap @@ -107,11 +107,11 @@ exports[`add-cluster - navigation using application menu renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/application-update/__snapshots__/installing-update.test.ts.snap b/packages/core/src/features/application-update/__snapshots__/installing-update.test.ts.snap index 6e61ea5e5d..0b32c94831 100644 --- a/packages/core/src/features/application-update/__snapshots__/installing-update.test.ts.snap +++ b/packages/core/src/features/application-update/__snapshots__/installing-update.test.ts.snap @@ -108,11 +108,11 @@ exports[`installing update when started renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -393,11 +393,11 @@ exports[`installing update when started when user checks for updates renders 1`] If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -678,11 +678,11 @@ exports[`installing update when started when user checks for updates when new up If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -988,11 +988,11 @@ exports[`installing update when started when user checks for updates when new up If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -1298,11 +1298,11 @@ exports[`installing update when started when user checks for updates when new up If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -1583,11 +1583,11 @@ exports[`installing update when started when user checks for updates when no new If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/application-update/child-features/application-update-using-top-bar/__snapshots__/installing-update-using-topbar-button.test.tsx.snap b/packages/core/src/features/application-update/child-features/application-update-using-top-bar/__snapshots__/installing-update-using-topbar-button.test.tsx.snap index a4787d0de3..26fd923e16 100644 --- a/packages/core/src/features/application-update/child-features/application-update-using-top-bar/__snapshots__/installing-update-using-topbar-button.test.tsx.snap +++ b/packages/core/src/features/application-update/child-features/application-update-using-top-bar/__snapshots__/installing-update-using-topbar-button.test.tsx.snap @@ -133,11 +133,11 @@ exports[`encourage user to update when sufficient time passed since update was d If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -418,11 +418,11 @@ exports[`encourage user to update when sufficient time passed since update was d If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/application-update/child-features/application-update-using-tray/__snapshots__/installing-update-using-tray.test.ts.snap b/packages/core/src/features/application-update/child-features/application-update-using-tray/__snapshots__/installing-update-using-tray.test.ts.snap index a2ea7a417b..57b2dd6f48 100644 --- a/packages/core/src/features/application-update/child-features/application-update-using-tray/__snapshots__/installing-update-using-tray.test.ts.snap +++ b/packages/core/src/features/application-update/child-features/application-update-using-tray/__snapshots__/installing-update-using-tray.test.ts.snap @@ -108,11 +108,11 @@ exports[`installing update using tray when started renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -393,11 +393,11 @@ exports[`installing update using tray when started when user checks for updates If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -678,11 +678,11 @@ exports[`installing update using tray when started when user checks for updates If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -988,11 +988,11 @@ exports[`installing update using tray when started when user checks for updates If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -1298,11 +1298,11 @@ exports[`installing update using tray when started when user checks for updates If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -1583,11 +1583,11 @@ exports[`installing update using tray when started when user checks for updates If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/application-update/child-features/force-update/__snapshots__/force-update.test.ts.snap b/packages/core/src/features/application-update/child-features/force-update/__snapshots__/force-update.test.ts.snap index 95101e8294..5dd749857a 100644 --- a/packages/core/src/features/application-update/child-features/force-update/__snapshots__/force-update.test.ts.snap +++ b/packages/core/src/features/application-update/child-features/force-update/__snapshots__/force-update.test.ts.snap @@ -133,11 +133,11 @@ exports[`force user to update when too long since update was downloaded when app If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -443,11 +443,11 @@ exports[`force user to update when too long since update was downloaded when app If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -800,11 +800,11 @@ exports[`force user to update when too long since update was downloaded when app If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/application-update/child-features/periodical-checking-of-updates/__snapshots__/periodical-checking-of-updates.test.ts.snap b/packages/core/src/features/application-update/child-features/periodical-checking-of-updates/__snapshots__/periodical-checking-of-updates.test.ts.snap index 413477ef9a..e6ae682c92 100644 --- a/packages/core/src/features/application-update/child-features/periodical-checking-of-updates/__snapshots__/periodical-checking-of-updates.test.ts.snap +++ b/packages/core/src/features/application-update/child-features/periodical-checking-of-updates/__snapshots__/periodical-checking-of-updates.test.ts.snap @@ -108,11 +108,11 @@ exports[`periodical checking of updates given updater is enabled and configurati If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/application-update/child-features/selection-of-update-stability/__snapshots__/selection-of-update-stability.test.ts.snap b/packages/core/src/features/application-update/child-features/selection-of-update-stability/__snapshots__/selection-of-update-stability.test.ts.snap index 7da7f42004..9e77201bf3 100644 --- a/packages/core/src/features/application-update/child-features/selection-of-update-stability/__snapshots__/selection-of-update-stability.test.ts.snap +++ b/packages/core/src/features/application-update/child-features/selection-of-update-stability/__snapshots__/selection-of-update-stability.test.ts.snap @@ -108,11 +108,11 @@ exports[`selection of update stability when started renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/catalog/__snapshots__/opening-entity-details.test.tsx.snap b/packages/core/src/features/catalog/__snapshots__/opening-entity-details.test.tsx.snap index 49d085fc85..c7b284a08e 100644 --- a/packages/core/src/features/catalog/__snapshots__/opening-entity-details.test.tsx.snap +++ b/packages/core/src/features/catalog/__snapshots__/opening-entity-details.test.tsx.snap @@ -108,11 +108,11 @@ exports[`opening catalog entity details panel renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/command-pallet/__snapshots__/keyboard-shortcuts.test.tsx.snap b/packages/core/src/features/command-pallet/__snapshots__/keyboard-shortcuts.test.tsx.snap index cbe09a0e1c..0269032531 100644 --- a/packages/core/src/features/command-pallet/__snapshots__/keyboard-shortcuts.test.tsx.snap +++ b/packages/core/src/features/command-pallet/__snapshots__/keyboard-shortcuts.test.tsx.snap @@ -199,11 +199,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -575,11 +575,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing ESC If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -951,11 +951,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing SHI If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -1339,11 +1339,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing SHI If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -1624,11 +1624,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -1909,11 +1909,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing ESC If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -2194,11 +2194,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing SHI If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -2491,11 +2491,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing SHI If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/entity-settings/__snapshots__/showing-settings-for-correct-entity.test.tsx.snap b/packages/core/src/features/entity-settings/__snapshots__/showing-settings-for-correct-entity.test.tsx.snap index a61803d059..d176bb9f7d 100644 --- a/packages/core/src/features/entity-settings/__snapshots__/showing-settings-for-correct-entity.test.tsx.snap +++ b/packages/core/src/features/entity-settings/__snapshots__/showing-settings-for-correct-entity.test.tsx.snap @@ -108,11 +108,11 @@ exports[`Showing correct entity settings renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/extensions/__snapshots__/navigation-using-application-menu.test.ts.snap b/packages/core/src/features/extensions/__snapshots__/navigation-using-application-menu.test.ts.snap index 56aa157f99..53dc28e961 100644 --- a/packages/core/src/features/extensions/__snapshots__/navigation-using-application-menu.test.ts.snap +++ b/packages/core/src/features/extensions/__snapshots__/navigation-using-application-menu.test.ts.snap @@ -107,11 +107,11 @@ exports[`extensions - navigation using application menu renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/preferences/__snapshots__/navigation-using-application-menu.test.ts.snap b/packages/core/src/features/preferences/__snapshots__/navigation-using-application-menu.test.ts.snap index 8fd3eddd42..855c4c54eb 100644 --- a/packages/core/src/features/preferences/__snapshots__/navigation-using-application-menu.test.ts.snap +++ b/packages/core/src/features/preferences/__snapshots__/navigation-using-application-menu.test.ts.snap @@ -107,11 +107,11 @@ exports[`preferences - navigation using application menu renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/preferences/__snapshots__/navigation-using-tray.test.ts.snap b/packages/core/src/features/preferences/__snapshots__/navigation-using-tray.test.ts.snap index 5a65444e9b..c0ab06204e 100644 --- a/packages/core/src/features/preferences/__snapshots__/navigation-using-tray.test.ts.snap +++ b/packages/core/src/features/preferences/__snapshots__/navigation-using-tray.test.ts.snap @@ -108,11 +108,11 @@ exports[`show-about-using-tray renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/status-bar/__snapshots__/status-bar-items-originating-from-extensions.test.tsx.snap b/packages/core/src/features/status-bar/__snapshots__/status-bar-items-originating-from-extensions.test.tsx.snap index 72291a5587..f652074bf8 100644 --- a/packages/core/src/features/status-bar/__snapshots__/status-bar-items-originating-from-extensions.test.tsx.snap +++ b/packages/core/src/features/status-bar/__snapshots__/status-bar-items-originating-from-extensions.test.tsx.snap @@ -108,11 +108,11 @@ exports[`status-bar-items-originating-from-extensions when application starts wh If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/top-bar/extension-api/__snapshots__/extendability-using-extension-api.test.tsx.snap b/packages/core/src/features/top-bar/extension-api/__snapshots__/extendability-using-extension-api.test.tsx.snap index ed49317fcb..179c2bf3f1 100644 --- a/packages/core/src/features/top-bar/extension-api/__snapshots__/extendability-using-extension-api.test.tsx.snap +++ b/packages/core/src/features/top-bar/extension-api/__snapshots__/extendability-using-extension-api.test.tsx.snap @@ -108,11 +108,11 @@ exports[`extendability-using-extension-api given an extension with a weakly type If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -402,11 +402,11 @@ exports[`extendability-using-extension-api given an extension with top-bar items If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -687,11 +687,11 @@ exports[`extendability-using-extension-api given an extension with top-bar items If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -972,11 +972,11 @@ exports[`extendability-using-extension-api renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/features/welcome/__snapshots__/navigation-using-application-menu.test.ts.snap b/packages/core/src/features/welcome/__snapshots__/navigation-using-application-menu.test.ts.snap index 610e62e091..4016a617c3 100644 --- a/packages/core/src/features/welcome/__snapshots__/navigation-using-application-menu.test.ts.snap +++ b/packages/core/src/features/welcome/__snapshots__/navigation-using-application-menu.test.ts.snap @@ -107,11 +107,11 @@ exports[`welcome - navigation using application menu renders 1`] = ` If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

@@ -1142,11 +1142,11 @@ exports[`welcome - navigation using application menu when navigated somewhere el If you have any questions or feedback, please join our - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/main/weblinks-store/links.ts b/packages/core/src/main/weblinks-store/links.ts index ae53b6ec27..a19e7f7548 100644 --- a/packages/core/src/main/weblinks-store/links.ts +++ b/packages/core/src/main/weblinks-store/links.ts @@ -10,8 +10,8 @@ export const lensWebsiteLinkName = "Lens Website"; export const lensDocumentationWeblinkId = "lens-documentation-link"; export const lensDocumentationWeblinkName = "Lens Documentation"; -export const lensSlackWeblinkId = "lens-slack-link"; -export const lensSlackWeblinkName = "Lens Community Slack"; +export const lensForumsWeblinkId = "lens-forums-link"; +export const lensForumsWeblinkName = "Lens Forums"; export const lensTwitterWeblinkId = "lens-twitter-link"; export const lensTwitterWeblinkName = "Lens on Twitter"; diff --git a/packages/core/src/main/weblinks-store/migrations/5.1.4.injectable.ts b/packages/core/src/main/weblinks-store/migrations/5.1.4.injectable.ts index fe27b9ae3e..000937abba 100644 --- a/packages/core/src/main/weblinks-store/migrations/5.1.4.injectable.ts +++ b/packages/core/src/main/weblinks-store/migrations/5.1.4.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { docsUrl, slackUrl } from "../../../common/vars"; +import { docsUrl, forumsUrl } from "../../../common/vars"; import type { WeblinkData } from "../../../common/weblinks-store/weblink-store"; import { getInjectable } from "@ogre-tools/injectable"; import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token"; @@ -20,7 +20,7 @@ const v514WeblinkStoreMigrationInjectable = getInjectable({ weblinks.push( { id: "https://k8slens.dev", name: links.lensWebsiteLinkName, url: "https://k8slens.dev" }, { id: docsUrl, name: links.lensDocumentationWeblinkName, url: docsUrl }, - { id: slackUrl, name: links.lensSlackWeblinkName, url: slackUrl }, + { id: forumsUrl, name: links.lensForumsWeblinkName, url: forumsUrl }, { id: "https://twitter.com/k8slens", name: links.lensTwitterWeblinkName, url: "https://twitter.com/k8slens" }, { id: "https://medium.com/k8slens", name: links.lensBlogWeblinkName, url: "https://medium.com/k8slens" }, { id: "https://kubernetes.io/docs/home/", name: links.kubernetesDocumentationWeblinkName, url: "https://kubernetes.io/docs/home/" }, diff --git a/packages/core/src/main/weblinks-store/migrations/5.4.5-beta.1.injectable.ts b/packages/core/src/main/weblinks-store/migrations/5.4.5-beta.1.injectable.ts index dbe580bec3..fc67e4a2f5 100644 --- a/packages/core/src/main/weblinks-store/migrations/5.4.5-beta.1.injectable.ts +++ b/packages/core/src/main/weblinks-store/migrations/5.4.5-beta.1.injectable.ts @@ -16,40 +16,40 @@ const v545Beta1WeblinkStoreMigrationInjectable = getInjectable({ const weblinksRaw = store.get("weblinks"); const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[]; - const lensWebsiteLink = weblinks.find(weblink => weblink.name === links.lensWebsiteLinkName); + const lensWebsite = weblinks.find(weblink => weblink.name === links.lensWebsiteLinkName); - if (lensWebsiteLink) { - lensWebsiteLink.id = links.lensWebsiteWeblinkId; + if (lensWebsite) { + lensWebsite.id = links.lensWebsiteWeblinkId; } - const lensDocumentationWeblinkLink = weblinks.find(weblink => weblink.name === links.lensDocumentationWeblinkName); + const lensDocumentationWeblink = weblinks.find(weblink => weblink.name === links.lensDocumentationWeblinkName); - if (lensDocumentationWeblinkLink) { - lensDocumentationWeblinkLink.id = links.lensDocumentationWeblinkId; + if (lensDocumentationWeblink) { + lensDocumentationWeblink.id = links.lensDocumentationWeblinkId; } - const lensSlackWeblinkLink = weblinks.find(weblink => weblink.name === links.lensSlackWeblinkName); + const lensForumsWeblink = weblinks.find(weblink => weblink.name === links.lensForumsWeblinkName); - if (lensSlackWeblinkLink) { - lensSlackWeblinkLink.id = links.lensSlackWeblinkId; + if (lensForumsWeblink) { + lensForumsWeblink.id = links.lensForumsWeblinkId; } - const lensTwitterWeblinkLink = weblinks.find(weblink => weblink.name === links.lensTwitterWeblinkName); + const lensTwitterWeblink = weblinks.find(weblink => weblink.name === links.lensTwitterWeblinkName); - if (lensTwitterWeblinkLink) { - lensTwitterWeblinkLink.id = links.lensTwitterWeblinkId; + if (lensTwitterWeblink) { + lensTwitterWeblink.id = links.lensTwitterWeblinkId; } - const lensBlogWeblinkLink = weblinks.find(weblink => weblink.name === links.lensBlogWeblinkName); + const lensBlogWeblink = weblinks.find(weblink => weblink.name === links.lensBlogWeblinkName); - if (lensBlogWeblinkLink) { - lensBlogWeblinkLink.id = links.lensBlogWeblinkId; + if (lensBlogWeblink) { + lensBlogWeblink.id = links.lensBlogWeblinkId; } - const kubernetesDocumentationWeblinkLink = weblinks.find(weblink => weblink.name === links.kubernetesDocumentationWeblinkName); + const kubernetesDocumentationWeblink = weblinks.find(weblink => weblink.name === links.kubernetesDocumentationWeblinkName); - if (kubernetesDocumentationWeblinkLink) { - kubernetesDocumentationWeblinkLink.id = links.kubernetesDocumentationWeblinkId; + if (kubernetesDocumentationWeblink) { + kubernetesDocumentationWeblink.id = links.kubernetesDocumentationWeblinkId; } store.set("weblinks", weblinks); diff --git a/packages/core/src/main/weblinks-store/migrations/currentVersion.injectable.ts b/packages/core/src/main/weblinks-store/migrations/currentVersion.injectable.ts index a424743697..b619dc4006 100644 --- a/packages/core/src/main/weblinks-store/migrations/currentVersion.injectable.ts +++ b/packages/core/src/main/weblinks-store/migrations/currentVersion.injectable.ts @@ -3,12 +3,12 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { docsUrl, slackUrl } from "../../../common/vars"; +import { docsUrl, forumsUrl } from "../../../common/vars"; import type { WeblinkData } from "../../../common/weblinks-store/weblink-store"; import { getInjectable } from "@ogre-tools/injectable"; import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token"; import { applicationInformationToken } from "../../../common/vars/application-information-token"; -import { lensDocumentationWeblinkId, lensSlackWeblinkId } from "../links"; +import { lensDocumentationWeblinkId, lensForumsWeblinkId } from "../links"; const currentVersionWeblinkStoreMigrationInjectable = getInjectable({ id: "current-version-weblink-store-migration", @@ -20,10 +20,10 @@ const currentVersionWeblinkStoreMigrationInjectable = getInjectable({ run(store) { const weblinksRaw = store.get("weblinks"); const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[]; - const slackWeblink = weblinks.find(weblink => weblink.id === lensSlackWeblinkId); + const forumsWeblink = weblinks.find(weblink => weblink.id === lensForumsWeblinkId); - if (slackWeblink) { - slackWeblink.url = slackUrl; + if (forumsWeblink) { + forumsWeblink.url = forumsUrl; } const docsWeblink = weblinks.find(weblink => weblink.id === lensDocumentationWeblinkId); @@ -32,7 +32,9 @@ const currentVersionWeblinkStoreMigrationInjectable = getInjectable({ docsWeblink.url = docsUrl; } - store.set("weblinks", weblinks); + const removedSlackLink = weblinks.filter(weblink => weblink.id !== "lens-slack-link"); + + store.set("weblinks", removedSlackLink); }, }; }, diff --git a/packages/core/src/renderer/components/+welcome/welcome.tsx b/packages/core/src/renderer/components/+welcome/welcome.tsx index cf413748bc..590eaafee5 100644 --- a/packages/core/src/renderer/components/+welcome/welcome.tsx +++ b/packages/core/src/renderer/components/+welcome/welcome.tsx @@ -10,7 +10,7 @@ import type { IComputedValue } from "mobx"; import type { CarouselProps } from "react-material-ui-carousel"; import LegacyCarousel from "react-material-ui-carousel"; import { Icon } from "../icon"; -import { slackUrl } from "../../../common/vars"; +import { forumsUrl } from "../../../common/vars"; import { withInjectables } from "@ogre-tools/injectable-react"; import welcomeMenuItemsInjectable from "./welcome-menu-items/welcome-menu-items.injectable"; import type { WelcomeMenuRegistration } from "./welcome-menu-items/welcome-menu-registration"; @@ -93,12 +93,12 @@ const NonInjectedWelcome = observer(({
{"If you have any questions or feedback, please join our "} - Lens Community slack channel + Lens Forums .

diff --git a/packages/core/src/renderer/components/error-boundary/error-boundary.tsx b/packages/core/src/renderer/components/error-boundary/error-boundary.tsx index 75e5cf4689..6e39867109 100644 --- a/packages/core/src/renderer/components/error-boundary/error-boundary.tsx +++ b/packages/core/src/renderer/components/error-boundary/error-boundary.tsx @@ -9,7 +9,7 @@ import type { ErrorInfo } from "react"; import React from "react"; import { observer } from "mobx-react"; import { Button } from "../button"; -import { issuesTrackerUrl, slackUrl } from "../../../common/vars"; +import { issuesTrackerUrl, forumsUrl } from "../../../common/vars"; import type { SingleOrMany } from "../../utils"; import type { ObservableHistory } from "mobx-observable-history"; import { withInjectables } from "@ogre-tools/injectable-react"; @@ -53,15 +53,15 @@ class NonInjectedErrorBoundary extends React.Component

- {"To help us improve the product please report bugs to "} + {"To help us improve the product please report bugs on"} - Slack + Lens Forums - {" community or "} + {" or on our"} `Invalid release type was provided (value was "${invalid}"). Valid options are: ${[...validReleaseValues, ...validPrereleaseValues].join(", ")}`, - noPreid: `No preid was provided. Use '--preid' to specify. Valid options are: ${validPreidValues.join(", ")}`, - invalidPreid: (invalid: string) => `Invalid preid was provided (value was "${invalid}"). Valid options are: ${validPreidValues.join(", ")}`, - wrongCwd: "It looks like you are running this script from the 'scripts' directory. This script assumes it is run from the root of the git repo", -}; - -if (!options.type) { - console.error(errorMessages.noReleaseType); - process.exit(1); -} - -if (validReleaseValues.includes(options.type)) { - // do nothing, is valid -} else if (validPrereleaseValues.includes(options.type)) { - if (!options.preid) { - console.error(errorMessages.noPreid); - process.exit(1); - } - - if (!validPreidValues.includes(options.preid)) { - console.error(errorMessages.invalidPreid(options.preid)); - process.exit(1); - } -} else { - console.error(errorMessages.invalidRelease(options.type)); - process.exit(1); -} - -if (basename(process.cwd()) === "scripts") { - console.error(errorMessages.wrongCwd); -} - -const currentVersion = new SemVer((await fse.readJson("./lerna.json")).version); - -console.log(`current version: ${currentVersion.format()}`); - -const newVersion = currentVersion.inc(options.type, options.preid); -const newVersionMilestone = `${newVersion.major}.${newVersion.minor}.${newVersion.patch}`; -const prBranch = `release/v${newVersion.format()}`; - -await exec(`yarn run bump-version --yes ${newVersion.format()} --force-publish`); -await exec(`git checkout -b ${prBranch}`); -await exec("git add lerna.json packages/*/package.json"); -await exec(`git commit -sm "Release ${newVersion.format()}"`); - -console.log(`new version: ${newVersion.format()}`); - -console.log("fetching tags..."); -await exec("git fetch --tags --force"); - -const actualTags = (await exec("git tag --list", { encoding: "utf-8" })).stdout.split(/\r?\n/).map(line => line.trim()); -const [previousReleasedVersion] = actualTags - .map((value) => semverValid(value)) - .filter((v): v is string => typeof v === "string") - .sort((l, r) => semverRcompare(l, r)) - .filter(version => semverLte(version, currentVersion)); - -const getMergedPrsArgs = [ - "gh", - "pr", - "list", - "--limit=500", // Should be big enough, if not we need to release more often ;) - "--state=merged", - "--base=master", - "--json mergeCommit,title,author,labels,number,milestone,mergedAt", -]; - interface GithubPrData { author: { login: string; @@ -147,168 +47,296 @@ interface ExtendedGithubPrData extends Omit { mergedAt: Date; } -console.log("retreiving last 500 PRs to create release PR body..."); -const mergedPrs = JSON.parse((await exec(getMergedPrsArgs.join(" "), { encoding: "utf-8" })).stdout) as GithubPrData[]; -const milestoneRelevantPrs = mergedPrs.filter(pr => pr.milestone?.title === newVersionMilestone); -const relaventPrsQuery = await Promise.all( - milestoneRelevantPrs.map(async pr => ({ - pr, - stdout: (await exec(`git tag v${previousReleasedVersion} --no-contains ${pr.mergeCommit.oid}`)).stdout, - })), -); -const relaventPrs = relaventPrsQuery - .filter(query => query.stdout) - .map(query => query.pr) - .filter(pr => pr.labels.every(label => label.name !== "skip-changelog")) - .map(pr => ({ ...pr, mergedAt: new Date(pr.mergedAt) } as ExtendedGithubPrData)) - .sort((left, right) => { - const leftAge = left.mergedAt.valueOf(); - const rightAge = right.mergedAt.valueOf(); +async function getCurrentBranch(): Promise { + return (await exec("git branch --show-current")).stdout.trim(); +} - if (leftAge === rightAge) { - return 0; - } +async function getAbsolutePathToRepoRoot(): Promise { + return (await exec("git rev-parse --show-toplevel")).stdout.trim(); +} - if (leftAge > rightAge) { - return 1; - } +async function fetchAllGitTags(): Promise { + await execFile("git", ["fetch", "--tags", "--force"]); - return -1; + const { stdout } = await exec("git tag --list", { encoding: "utf-8" }); + + return stdout + .split(/\r?\n/) + .map(line => line.trim()); +} + +async function bumpPackageVersions(): Promise { + await spawn("npm", ["run", "bump-version"], { + stdio: "inherit", + }); +} + +function isDefined(value: T | null | undefined): value is T { + return value != null; +} + +function findClosestVersionTagLessThanVersion(tags: string[], version: SemVer): string { + const lessThanTags = tags + .map((value) => semver.parse(value)) + .filter(isDefined) + .filter(version => !version.prerelease.includes("cron")) + .sort(semver.rcompare) + .filter(version => semver.lte(version, version)); + + assert(lessThanTags.length > 0, `Cannot find version tag less than ${version.format()}`); + + return lessThanTags[0].format(); +} + +async function getCurrentVersionOfSubPackage(packageName: string): Promise { + const packageJson = JSON.parse(await readFile(`./packages/${packageName}/package.json`, "utf-8")); + + return new SemVer(packageJson.version); +} + +async function checkCurrentWorkingDirectory(): Promise { + const repoRoot = await getAbsolutePathToRepoRoot(); + + if (process.cwd() !== repoRoot) { + console.error("It looks like you are running this script from the 'scripts' directory. This script assumes it is run from the root of the git repo"); + process.exit(1); + } +} + +function formatSemverForMilestone(version: SemVer): string { + return `${version.major}.${version.minor}.${version.patch}`; +} + +async function createReleaseBranchAndCommit(prBase: string, version: SemVer, prBody: string): Promise { + const prBranch = `release/v${version.format()}`; + + await spawn("git", ["checkout", "-b", prBranch], { + stdio: "inherit", + }); + await spawn("git", ["add", "lerna.json", "packages/*/package.json"], { + stdio: "inherit", + }); + await spawn("git", ["commit", "-sm", `"Release ${version.format()}"`], { + stdio: "inherit", + }); + await spawn("git", ["push", "--set-upstream", "origin", prBranch], { + stdio: "inherit", }); -const enhancementPrLabelName = "enhancement"; -const bugfixPrLabelName = "bug"; + await spawn("gh", [ + "pr", + "create", + "--base", prBase, + "--title", `Release ${version.format()}`, + "--label", "skip-changelog", + "--label", "release", + "--milestone", formatSemverForMilestone(version), + "--body-file", prBody, + ], { + stdio: "inherit" + }); +} -const isEnhancementPr = (pr: ExtendedGithubPrData) => pr.labels.some(label => label.name === enhancementPrLabelName); -const isBugfixPr = (pr: ExtendedGithubPrData) => pr.labels.some(label => label.name === bugfixPrLabelName); +function sortExtendedGithubPrData(left: ExtendedGithubPrData, right: ExtendedGithubPrData): number { + const leftAge = left.mergedAt.valueOf(); + const rightAge = right.mergedAt.valueOf(); -const prLines = { - enhancement: [] as string[], - bugfix: [] as string[], - maintenence: [] as string[], -}; + if (leftAge === rightAge) { + return 0; + } -function getPrEntry(pr: ExtendedGithubPrData) { + if (leftAge > rightAge) { + return 1; + } + + return -1; +} + +async function getRelevantPRs(milestone: string, previousReleasedVersion: string): Promise { + console.log("retreiving previous 500 PRs..."); + + const getMergedPrsArgs = [ + "gh", + "pr", + "list", + "--limit=500", // Should be big enough, if not we need to release more often ;) + "--state=merged", + "--base=master", + "--json mergeCommit,title,author,labels,number,milestone,mergedAt", + ]; + + const mergedPrs = JSON.parse((await exec(getMergedPrsArgs.join(" "), { encoding: "utf-8" })).stdout) as GithubPrData[]; + const milestoneRelevantPrs = mergedPrs.filter(pr => pr.milestone?.title === milestone); + const relaventPrsQuery = await Promise.all( + milestoneRelevantPrs.map(async pr => ({ + pr, + stdout: (await exec(`git tag v${previousReleasedVersion} --no-contains ${pr.mergeCommit.oid}`)).stdout, + })), + ); + + return relaventPrsQuery + .filter(query => query.stdout) + .map(query => query.pr) + .filter(pr => pr.labels.every(label => label.name !== "skip-changelog")) + .map(pr => ({ ...pr, mergedAt: new Date(pr.mergedAt) } as ExtendedGithubPrData)) + .sort(sortExtendedGithubPrData); +} + +function formatPrEntry(pr: ExtendedGithubPrData) { return `- ${pr.title} (**[#${pr.number}](https://github.com/lensapp/lens/pull/${pr.number})**) https://github.com/${pr.author.login}`; } -const rl = createInterface(process.stdin); -const prBase = newVersion.patch === 0 - ? "master" - : `release/v${newVersion.major}.${newVersion.minor}`; +const isEnhancementPr = (pr: ExtendedGithubPrData) => pr.labels.some(label => label.name === "enhancement"); +const isBugfixPr = (pr: ExtendedGithubPrData) => pr.labels.some(label => label.name === "bug"); -function askQuestion(question: string): Promise { - return new Promise(resolve => { - function _askQuestion() { - console.log(question); +const cherrypickCommitWith = (rl: ReadLine) => async (commit: string) => { + try { + const cherryPick = child_process.spawn("git", ["cherry-pick", commit]); - rl.once("line", (answer) => { - const cleaned = answer.trim().toLowerCase(); + cherryPick.stdout.pipe(process.stdout); + cherryPick.stderr.pipe(process.stderr); - if (cleaned === "y") { - resolve(true); - } else if (cleaned === "n") { - resolve(false); - } else { - _askQuestion(); + await new Promise((resolve, reject) => { + const cleaners: (() => void)[] = []; + const cleanup = () => cleaners.forEach(cleaner => cleaner()); + + const onExit = (code: number | null) => { + if (code) { + reject(new Error(`git cherry-pick failed with exit code ${code}`)); + cleanup(); } - }); - } - _askQuestion(); + resolve(); + cleanup(); + }; + + cherryPick.once("exit", onExit); + cleaners.push(() => cherryPick.off("exit", onExit)); + + const onError = (error: Error) => { + cleanup(); + reject(error); + }; + + cherryPick.once("error", onError); + cleaners.push(() => cherryPick.off("error", onError)); + }); + } catch { + console.error(chalk.bold("Please resolve conflicts in a seperate terminal and then press enter here...")); + await new Promise(resolve => rl.once("line", () => resolve())); + } +}; + +async function pickWhichPRsToUse(prs: ExtendedGithubPrData[]): Promise { + const answers = await inquirer.prompt<{ commits: number[] }>({ + type: "checkbox", + name: `commits`, + message: "Pick which commits to use...", + default: [], + choices: prs.map(pr => ({ + checked: true, + key: pr.number, + name: `#${pr.number}: ${pr.title} (https://github.com/lensapp/lens/pull/${pr.number})`, + value: pr.number, + short: `#${pr.number}`, + })), + loop: false, }); + + return prs.filter(pr => answers.commits.includes(pr.number)); } -async function handleRelaventPr(pr: ExtendedGithubPrData) { - if (options["check-commits"] && !(await askQuestion(`Would you like to use #${pr.number}: ${pr.title}? - Y/N`))) { - return; - } +function formatChangelog(previousReleasedVersion: string, prs: ExtendedGithubPrData[]): string { + const enhancementPrLines: string[] = []; + const bugPrLines: string[] = []; + const maintenencePrLines: string[] = []; - if (prBase !== "master") { - try { - const promise = exec(`git cherry-pick ${pr.mergeCommit.oid}`); - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - promise.child.stdout!.pipe(process.stdout); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - promise.child.stderr!.pipe(process.stderr); - - await promise; - } catch { - console.error(`Failed to cherry-pick ${pr.mergeCommit.oid}, please resolve conflicts and then press enter here:`); - await new Promise(resolve => rl.once("line", () => resolve())); + for (const pr of prs) { + if (isEnhancementPr(pr)) { + enhancementPrLines.push(formatPrEntry(pr)); + } else if (isBugfixPr(pr)) { + bugPrLines.push(formatPrEntry(pr)); + } else { + maintenencePrLines.push(formatPrEntry(pr)); } } - if (isEnhancementPr(pr)) { - prLines.enhancement.push(getPrEntry(pr)); - } else if (isBugfixPr(pr)) { - prLines.bugfix.push(getPrEntry(pr)); - } else { - prLines.maintenence.push(getPrEntry(pr)); + if (enhancementPrLines.length > 0) { + enhancementPrLines.unshift("## 🚀 Features", ""); + enhancementPrLines.push(""); } + + if (bugPrLines.length > 0) { + bugPrLines.unshift("## 🐛 Bug Fixes", ""); + bugPrLines.push(""); + } + + if (maintenencePrLines.length > 0) { + maintenencePrLines.unshift("## 🧰 Maintenance", ""); + maintenencePrLines.push(""); + } + + return [ + `## Changes since ${previousReleasedVersion}`, + "", + ...enhancementPrLines, + ...bugPrLines, + ...maintenencePrLines, + ].join("\n"); } -for (const pr of relaventPrs) { - await handleRelaventPr(pr); +async function cherrypickCommits(prs: ExtendedGithubPrData[]): Promise { + const rl = createInterface(process.stdin); + const cherrypickCommit = cherrypickCommitWith(rl); + + for (const pr of prs) { + await cherrypickCommit(pr.mergeCommit.oid); + } + + rl.close(); } -rl.close(); +async function pickRelaventPrs(prs: ExtendedGithubPrData[], isMasterBranch: boolean): Promise { + if (isMasterBranch) { + return prs; + } -const prBodyLines = [ - `## Changes since ${previousReleasedVersion}`, - "", - ...( - prLines.enhancement.length > 0 - ? [ - "## 🚀 Features", - "", - ...prLines.enhancement, - "", - ] - : [] - ), - ...( - prLines.bugfix.length > 0 - ? [ - "## 🐛 Bug Fixes", - "", - ...prLines.bugfix, - "", - ] - : [] - ), - ...( - prLines.maintenence.length > 0 - ? [ - "## 🧰 Maintenance", - "", - ...prLines.maintenence, - "", - ] - : [] - ), -]; -const prBody = prBodyLines.join("\n"); -const createPrArgs = [ - "pr", - "create", - "--base", prBase, - "--title", `Release ${newVersion.format()}`, - "--label", "skip-changelog", - "--label", "release", - "--milestone", `${newVersion.major}.${newVersion.minor}.${newVersion.patch}`, - "--body-file", "-", -]; + let selectedPrs: ExtendedGithubPrData[]; -await exec(`git push --set-upstream origin ${prBranch}`); + do { + selectedPrs = await pickWhichPRsToUse(prs); + } while (selectedPrs.length === 0 && (console.warn("[WARNING]: must pick at least once commit"), true)); -const createPrProcess = execFile("gh", createPrArgs); + await cherrypickCommits(selectedPrs); -createPrProcess.child.stdout?.pipe(process.stdout); -createPrProcess.child.stderr?.pipe(process.stderr); + return selectedPrs; +} -createPrProcess.child.stdin?.write(prBody); -createPrProcess.child.stdin?.end(); +async function createRelease(): Promise { + await checkCurrentWorkingDirectory(); -await createPrProcess; + const currentK8slensCoreVersion = await getCurrentVersionOfSubPackage("core"); + const prBase = await getCurrentBranch(); + const isMasterBranch = prBase === "master"; + const tags = await fetchAllGitTags(); + const previousReleasedVersion = findClosestVersionTagLessThanVersion(tags, currentK8slensCoreVersion); + + if (isMasterBranch) { + await bumpPackageVersions(); + } + + const prMilestone = formatSemverForMilestone(await getCurrentVersionOfSubPackage("core")); + const relaventPrs = await getRelevantPRs(prMilestone, previousReleasedVersion); + const selectedPrs = await pickRelaventPrs(relaventPrs, isMasterBranch); + const prBody = formatChangelog(previousReleasedVersion, selectedPrs); + + if (!isMasterBranch) { + await bumpPackageVersions(); + } + + const newK8slensCoreVersion = await getCurrentVersionOfSubPackage("core"); + + await createReleaseBranchAndCommit(prBase, newK8slensCoreVersion, prBody); +} + +await createRelease();