mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Release 6.4.2 (#7286)
* Fix request namespace list permissions check if a list rule is not the first match (#7282) Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * Fix cluster metadata detectors (#7255) Signed-off-by: Juho Heikka <juho.heikka@gmail.com> * Fix extension API not having all the correct types (#7263) Signed-off-by: Sebastian Malton <sebastian@malton.name> * Update release guide and fix release script (#7276) Signed-off-by: Sebastian Malton <sebastian@malton.name> * Release 6.4.2 Signed-off-by: Juho Heikka <juho.heikka@gmail.com> --------- Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Signed-off-by: Juho Heikka <juho.heikka@gmail.com> Signed-off-by: Sebastian Malton <sebastian@malton.name> Co-authored-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
67896437f0
commit
1d78912dd8
@ -11,9 +11,12 @@ All releases will be made by creating a PR which bumps the version field in the
|
|||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
1. If you are making a minor or major release (or prereleases for one) make sure you are on the `master` branch.
|
1. If you are making a minor or major release (or prereleases of one) make sure you are on the `master` branch.
|
||||||
1. If you are making a patch release (or a prerelease for one) make sure you are on the `release/v<MAJOR>.<MINOR>` branch.
|
1. If you are making a patch release (or a prerelease for one) make sure you are on the `release/v<MAJOR>.<MINOR>` branch.
|
||||||
1. Run `yarn create-release-pr <release-type>`. If you are making a subsequent prerelease release, provide the `--check-commits` flag.
|
1. Run `npm run create-release-pr`.
|
||||||
1. If you are checking the commits, type `y<ENTER>` to pick a commit, and `n<ENTER>` to skip it. You will want to skip the commits that were part of previous prerelease releases.
|
1. Pick the PRs that you want to include in this release using the keys listed.
|
||||||
1. Once the PR is created, approved, and then merged the `Release Open Lens` workflow will create a tag and release for you.
|
1. Once the PR is created, approved, and then merged the `Release Open Lens` workflow will create a tag and release for you.
|
||||||
1. If you are making a major or minor release, create a `release/v<MAJOR>.<MINOR>` branch and push it to `origin` so that future patch releases can be made from it.
|
1. If you are making a major or minor release, create a `release/v<MAJOR>.<MINOR>` branch and push it to `origin` so that future patch releases can be made from it.
|
||||||
|
1. If you released a major or minor version, create a new patch milestone and move all bug issues to that milestone and all enhancement issues to the next minor milestone.
|
||||||
|
1. If you released a patch version, create a new patch milestone for the next patch version and move all the issues and PRs (open or closed) that weren't included in the current release to that milestone.
|
||||||
|
1. Close the milestone related to the release that was just made (if not a prerelease release).
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"version": "6.4.1",
|
"version": "6.4.2",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"npmClientArgs": [
|
"npmClientArgs": [
|
||||||
"--network-timeout=100000"
|
"--network-timeout=100000"
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
"productName": "",
|
"productName": "",
|
||||||
"description": "Lens Desktop Core",
|
"description": "Lens Desktop Core",
|
||||||
"homepage": "https://github.com/lensapp/lens",
|
"homepage": "https://github.com/lensapp/lens",
|
||||||
"version": "6.4.1",
|
"version": "6.4.2",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/lensapp/lens.git"
|
"url": "git+https://github.com/lensapp/lens.git"
|
||||||
|
|||||||
@ -22,7 +22,10 @@ const pickHighestAccuracy = (prev: ClusterDetectionResult, curr: ClusterDetectio
|
|||||||
|
|
||||||
const detectMetadataWithFor = (cluster: Cluster) => async (clusterMetadataDetector: ClusterMetadataDetector) => {
|
const detectMetadataWithFor = (cluster: Cluster) => async (clusterMetadataDetector: ClusterMetadataDetector) => {
|
||||||
try {
|
try {
|
||||||
return await clusterMetadataDetector.detect(cluster);
|
return {
|
||||||
|
key: clusterMetadataDetector.key,
|
||||||
|
result: await clusterMetadataDetector.detect(cluster),
|
||||||
|
};
|
||||||
} catch {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -39,7 +42,12 @@ const detectClusterMetadataInjectable = getInjectable({
|
|||||||
filter(isDefined),
|
filter(isDefined),
|
||||||
(arg) => groupBy(arg, "key"),
|
(arg) => groupBy(arg, "key"),
|
||||||
(arg) => object.entries(arg),
|
(arg) => object.entries(arg),
|
||||||
map(([ key, results ]) => [key, reduce(results, pickHighestAccuracy)] as const),
|
map(([ key, detectionResults ]) => {
|
||||||
|
const results = detectionResults.map(({ result }) => result as ClusterDetectionResult);
|
||||||
|
const highestAccuracyResult = reduce(results, pickHighestAccuracy)?.value;
|
||||||
|
|
||||||
|
return [key, highestAccuracyResult] as const;
|
||||||
|
}),
|
||||||
filter(hasDefinedTupleValue),
|
filter(hasDefinedTupleValue),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AppPaths } from "../../common/app-paths/app-path-injection-token";
|
||||||
|
import appPathsStateInjectable from "../../common/app-paths/app-paths-state.injectable";
|
||||||
|
import directoryForKubeConfigsInjectable from "../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||||
|
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import { ClusterMetadataKey } from "../../common/cluster-types";
|
||||||
|
import type { Cluster } from "../../common/cluster/cluster";
|
||||||
|
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
|
||||||
|
import { getDiForUnitTesting } from "../getDiForUnitTesting";
|
||||||
|
import clusterDistributionDetectorInjectable from "./cluster-distribution-detector.injectable";
|
||||||
|
import clusterIdDetectorFactoryInjectable from "./cluster-id-detector.injectable";
|
||||||
|
import clusterLastSeenDetectorInjectable from "./cluster-last-seen-detector.injectable";
|
||||||
|
import clusterNodeCountDetectorInjectable from "./cluster-nodes-count-detector.injectable";
|
||||||
|
import type { DetectClusterMetadata } from "./detect-cluster-metadata.injectable";
|
||||||
|
import detectClusterMetadataInjectable from "./detect-cluster-metadata.injectable";
|
||||||
|
import requestClusterVersionInjectable from "./request-cluster-version.injectable";
|
||||||
|
|
||||||
|
describe("detect-cluster-metadata", () => {
|
||||||
|
let detectClusterMetadata: DetectClusterMetadata;
|
||||||
|
|
||||||
|
let cluster: Cluster;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const di = getDiForUnitTesting({ doGeneralOverrides: true });
|
||||||
|
|
||||||
|
const lastSeenDetectMock = jest.fn().mockReturnValue(Promise.resolve({ value: "some-time-stamp", accuracy: 100 }));
|
||||||
|
const nodeCountDetectMock = jest.fn().mockReturnValue(Promise.resolve({ value: 42, accuracy: 100 }));
|
||||||
|
const clusterIdDetectMock = jest.fn().mockReturnValue(Promise.resolve({ value: "some-cluster-id", accuracy: 100 }));
|
||||||
|
const distributionDetectMock = jest.fn().mockReturnValue(Promise.resolve({ value: "some-distribution", accuracy: 100 }));
|
||||||
|
|
||||||
|
di.override(clusterLastSeenDetectorInjectable, () => {
|
||||||
|
return {
|
||||||
|
key: ClusterMetadataKey.LAST_SEEN,
|
||||||
|
detect: lastSeenDetectMock,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
di.override(requestClusterVersionInjectable, () => () => Promise.resolve("some-cluster-version"));
|
||||||
|
|
||||||
|
di.override(clusterNodeCountDetectorInjectable, () => ({
|
||||||
|
key: ClusterMetadataKey.NODES_COUNT,
|
||||||
|
detect: nodeCountDetectMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
di.override(clusterIdDetectorFactoryInjectable, () => ({
|
||||||
|
key: ClusterMetadataKey.CLUSTER_ID,
|
||||||
|
detect: clusterIdDetectMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
di.override(clusterDistributionDetectorInjectable, () => ({
|
||||||
|
key: ClusterMetadataKey.DISTRIBUTION,
|
||||||
|
detect: distributionDetectMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
di.override(directoryForUserDataInjectable, () => "/some-user-store-path");
|
||||||
|
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
||||||
|
di.override(appPathsStateInjectable, () => ({
|
||||||
|
get: () => ({} as AppPaths),
|
||||||
|
set: () => {},
|
||||||
|
}));
|
||||||
|
|
||||||
|
detectClusterMetadata = di.inject(detectClusterMetadataInjectable);
|
||||||
|
|
||||||
|
const createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
|
||||||
|
cluster = createCluster({
|
||||||
|
id: "some-id",
|
||||||
|
contextName: "some-context",
|
||||||
|
kubeConfigPath: "minikube-config.yml",
|
||||||
|
}, {
|
||||||
|
clusterServerUrl: "foo",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given some cluster, last seen time stamp is added to the metadata", async () => {
|
||||||
|
const metadata = await detectClusterMetadata(cluster);
|
||||||
|
|
||||||
|
expect(metadata.lastSeen).toEqual("some-time-stamp");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given some cluster, cluster version is added to the metadata", async () => {
|
||||||
|
const metadata = await detectClusterMetadata(cluster);
|
||||||
|
|
||||||
|
expect(metadata.version).toEqual("some-cluster-version");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given some cluster, id is added to the metadata", async () => {
|
||||||
|
const metadata = await detectClusterMetadata(cluster);
|
||||||
|
|
||||||
|
expect(metadata.id).toEqual("some-cluster-id");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given some cluster, node count is added to the metadata", async () => {
|
||||||
|
const metadata = await detectClusterMetadata(cluster);
|
||||||
|
|
||||||
|
expect(metadata.nodes).toEqual(42);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given some cluster, distribution is added to the metadata", async () => {
|
||||||
|
const metadata = await detectClusterMetadata(cluster);
|
||||||
|
|
||||||
|
expect(metadata.distribution).toEqual("some-distribution");
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "@k8slens/extensions",
|
"name": "@k8slens/extensions",
|
||||||
"productName": "OpenLens extensions",
|
"productName": "OpenLens extensions",
|
||||||
"description": "OpenLens - Open Source Kubernetes IDE: extensions",
|
"description": "OpenLens - Open Source Kubernetes IDE: extensions",
|
||||||
"version": "6.4.1",
|
"version": "6.4.2",
|
||||||
"copyright": "© 2022 OpenLens Authors",
|
"copyright": "© 2022 OpenLens Authors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "dist/extension-api.js",
|
"main": "dist/extension-api.js",
|
||||||
@ -26,7 +26,7 @@
|
|||||||
"prepare:dev": "yarn run build"
|
"prepare:dev": "yarn run build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@k8slens/core": "^6.4.1"
|
"@k8slens/core": "^6.4.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^16.18.6",
|
"@types/node": "^16.18.6",
|
||||||
@ -39,6 +39,7 @@
|
|||||||
"style-loader": "^3.3.1",
|
"style-loader": "^3.3.1",
|
||||||
"ts-loader": "^9.4.2",
|
"ts-loader": "^9.4.2",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
|
"typed-emitter": "^2.1.0",
|
||||||
"typedoc": "0.23.25",
|
"typedoc": "0.23.25",
|
||||||
"typedoc-plugin-markdown": "^3.13.6",
|
"typedoc-plugin-markdown": "^3.13.6",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
"productName": "OpenLens",
|
"productName": "OpenLens",
|
||||||
"description": "OpenLens - Open Source IDE for Kubernetes",
|
"description": "OpenLens - Open Source IDE for Kubernetes",
|
||||||
"homepage": "https://github.com/lensapp/lens",
|
"homepage": "https://github.com/lensapp/lens",
|
||||||
"version": "6.4.1",
|
"version": "6.4.2",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/lensapp/lens.git"
|
"url": "git+https://github.com/lensapp/lens.git"
|
||||||
@ -192,7 +192,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@k8slens/core": "^6.4.1",
|
"@k8slens/core": "^6.4.2",
|
||||||
"@k8slens/ensure-binaries": "^6.4.0-beta.16",
|
"@k8slens/ensure-binaries": "^6.4.0-beta.16",
|
||||||
"@k8slens/generate-tray-icons": "^6.4.0-beta.16",
|
"@k8slens/generate-tray-icons": "^6.4.0-beta.16",
|
||||||
"@ogre-tools/fp": "^12.0.1",
|
"@ogre-tools/fp": "^12.0.1",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@k8slens/release-tool",
|
"name": "@k8slens/release-tool",
|
||||||
"version": "6.4.0",
|
"version": "6.4.2",
|
||||||
"description": "Release tool for lens monorepo",
|
"description": "Release tool for lens monorepo",
|
||||||
"main": "dist/index.mjs",
|
"main": "dist/index.mjs",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@ -145,6 +145,14 @@ function formatSemverForMilestone(version: SemVer): string {
|
|||||||
return `${version.major}.${version.minor}.${version.patch}`;
|
return `${version.major}.${version.minor}.${version.patch}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatVersionForPickingPrs(version: SemVer): string {
|
||||||
|
if (version.prerelease.length > 0) {
|
||||||
|
return `${version.major}.${version.minor}.${version.patch}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${version.major}.${version.minor}.${version.patch+1}`;
|
||||||
|
}
|
||||||
|
|
||||||
async function createReleaseBranchAndCommit(prBase: string, version: SemVer, prBody: string): Promise<void> {
|
async function createReleaseBranchAndCommit(prBase: string, version: SemVer, prBody: string): Promise<void> {
|
||||||
const prBranch = `release/v${version.format()}`;
|
const prBranch = `release/v${version.format()}`;
|
||||||
|
|
||||||
@ -182,9 +190,10 @@ function sortExtendedGithubPrData(left: ExtendedGithubPrData, right: ExtendedGit
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getRelevantPRs(milestone: string, previousReleasedVersion: string): Promise<ExtendedGithubPrData[]> {
|
async function getRelevantPRs(previousReleasedVersion: string): Promise<ExtendedGithubPrData[]> {
|
||||||
console.log("retrieving previous 200 PRs...");
|
console.log("retrieving previous 200 PRs...");
|
||||||
|
|
||||||
|
const milestone = formatVersionForPickingPrs(await getCurrentVersionOfSubPackage("core"));
|
||||||
const getMergedPrsArgs = [
|
const getMergedPrsArgs = [
|
||||||
"gh",
|
"gh",
|
||||||
"pr",
|
"pr",
|
||||||
@ -326,8 +335,7 @@ async function createRelease(): Promise<void> {
|
|||||||
await bumpPackageVersions();
|
await bumpPackageVersions();
|
||||||
}
|
}
|
||||||
|
|
||||||
const prMilestone = formatSemverForMilestone(await getCurrentVersionOfSubPackage("core"));
|
const relevantPrs = await getRelevantPRs(previousReleasedVersion);
|
||||||
const relevantPrs = await getRelevantPRs(prMilestone, previousReleasedVersion);
|
|
||||||
const selectedPrs = await pickRelevantPrs(relevantPrs, isMasterBranch);
|
const selectedPrs = await pickRelevantPrs(relevantPrs, isMasterBranch);
|
||||||
const prBody = formatChangelog(previousReleasedVersion, selectedPrs);
|
const prBody = formatChangelog(previousReleasedVersion, selectedPrs);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user