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 toggle to settings UI to opt-in to Pipelines v1 resources #2649

Merged
merged 1 commit into from
Jan 4, 2023
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
8 changes: 4 additions & 4 deletions src/api/clusterTasks.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2021 The Tekton Authors
Copyright 2019-2023 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -22,7 +22,7 @@ import {
function getClusterTasksAPI({ filters, isWebSocket, name }) {
return getTektonAPI(
'clustertasks',
{ isWebSocket },
{ isWebSocket, version: 'v1beta1' },
getQueryParams({ filters, name })
);
}
Expand All @@ -33,12 +33,12 @@ export function getClusterTasks({ filters = [] } = {}) {
}

export function getClusterTask({ name }) {
const uri = getTektonAPI('clustertasks', { name });
const uri = getTektonAPI('clustertasks', { name, version: 'v1beta1' });
return get(uri);
}

export function deleteClusterTask({ name }) {
const uri = getTektonAPI('clustertasks', { name });
const uri = getTektonAPI('clustertasks', { name, version: 'v1beta1' });
return deleteRequest(uri);
}

Expand Down
33 changes: 28 additions & 5 deletions src/api/pipelineRuns.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2022 The Tekton Authors
Copyright 2019-2023 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -18,6 +18,7 @@ import { deleteRequest, get, patch, post } from './comms';
import {
getQueryParams,
getTektonAPI,
getTektonPipelinesAPIVersion,
useCollection,
useResource
} from './utils';
Expand Down Expand Up @@ -95,7 +96,7 @@ export function getPipelineRunPayload({
timeoutsTasks
}) {
const payload = {
apiVersion: 'tekton.dev/v1beta1',
apiVersion: `tekton.dev/${getTektonPipelinesAPIVersion()}`,
kind: 'PipelineRun',
metadata: {
name: pipelineRunName,
Expand Down Expand Up @@ -184,10 +185,11 @@ export function rerunPipelineRun(pipelineRun) {
const { annotations, labels, name, namespace } = pipelineRun.metadata;

const payload = deepClone(pipelineRun);
payload.apiVersion = payload.apiVersion || 'tekton.dev/v1beta1';
payload.apiVersion =
payload.apiVersion || `tekton.dev/${getTektonPipelinesAPIVersion()}`;
payload.kind = payload.kind || 'PipelineRun';
payload.metadata = {
annotations,
annotations: annotations || {},
generateName: getGenerateNamePrefixForRerun(name),
labels: {
...labels,
Expand All @@ -196,7 +198,28 @@ export function rerunPipelineRun(pipelineRun) {
namespace
};

delete payload.metadata.labels['tekton.dev/pipeline'];
Object.keys(payload.metadata.labels).forEach(label => {
if (label.startsWith('tekton.dev/')) {
delete payload.metadata.labels[label];
}
});

/*
This is used by Tekton Pipelines as part of the conversion between v1beta1
and v1 resources. Creating a run with this in place prevents it from actually
executing and instead adopts the status of the original TaskRuns.

Ideally we would just delete all `tekton.dev/*` annotations as we do with labels but
`tekton.dev/v1beta1Resources` is required for pipelines that use PipelineResources,
and there may be other similar annotations that are still required.

When v1beta1 has been fully removed from Tekton Pipelines we can revisit this
and remove all remaining `tekton.dev/*` annotations.
*/
delete payload.metadata.annotations['tekton.dev/v1beta1TaskRuns'];
delete payload.metadata.annotations[
'kubectl.kubernetes.io/last-applied-configuration'
];

delete payload.status;
delete payload.spec?.status;
Expand Down
7 changes: 6 additions & 1 deletion src/api/pipelineRuns.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,12 @@ it('usePipelineRun', () => {

it('rerunPipelineRun', () => {
const originalPipelineRun = {
metadata: { name: 'fake_pipelineRun' },
metadata: {
labels: {
'tekton.dev/pipeline': 'foo'
},
name: 'fake_pipelineRun'
},
spec: { status: 'fake_status' },
status: 'fake_status'
};
Expand Down
8 changes: 5 additions & 3 deletions src/api/taskRuns.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2022 The Tekton Authors
Copyright 2019-2023 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -18,6 +18,7 @@ import { deleteRequest, get, patch, post } from './comms';
import {
getQueryParams,
getTektonAPI,
getTektonPipelinesAPIVersion,
useCollection,
useResource
} from './utils';
Expand Down Expand Up @@ -88,7 +89,7 @@ export function createTaskRun({
timeout
}) {
const payload = {
apiVersion: 'tekton.dev/v1beta1',
apiVersion: `tekton.dev/${getTektonPipelinesAPIVersion()}`,
kind: 'TaskRun',
metadata: {
name: taskRunName,
Expand Down Expand Up @@ -146,7 +147,8 @@ export function rerunTaskRun(taskRun) {
const { annotations, labels, name, namespace } = taskRun.metadata;

const payload = deepClone(taskRun);
payload.apiVersion = payload.apiVersion || 'tekton.dev/v1beta1';
payload.apiVersion =
payload.apiVersion || `tekton.dev/${getTektonPipelinesAPIVersion()}`;
payload.kind = payload.kind || 'TaskRun';
payload.metadata = {
annotations,
Expand Down
16 changes: 14 additions & 2 deletions src/api/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2022 The Tekton Authors
Copyright 2019-2023 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand Down Expand Up @@ -97,14 +97,26 @@ export function getQueryParams({
return '';
}

export function isPipelinesV1ResourcesEnabled() {
return localStorage.getItem('tkn-pipelines-v1-resources') === 'true';
}

export function setPipelinesV1ResourcesEnabled(enabled) {
localStorage.setItem('tkn-pipelines-v1-resources', enabled);
}

export function getTektonPipelinesAPIVersion() {
return isPipelinesV1ResourcesEnabled() ? 'v1' : 'v1beta1';
}

export function getTektonAPI(
type,
{
group = tektonAPIGroup,
isWebSocket,
name = '',
namespace,
version = 'v1beta1'
version = getTektonPipelinesAPIVersion()
} = {},
queryParams
) {
Expand Down
24 changes: 22 additions & 2 deletions src/containers/Settings/Settings.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2021-2022 The Tekton Authors
Copyright 2021-2023 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -24,7 +24,9 @@ import {
import { getTheme, setTheme } from '../../utils';
import {
isLogTimestampsEnabled,
setLogTimestampsEnabled
isPipelinesV1ResourcesEnabled,
setLogTimestampsEnabled,
setPipelinesV1ResourcesEnabled
} from '../../api/utils';

export function Settings() {
Expand Down Expand Up @@ -94,6 +96,24 @@ export function Settings() {
})}
onToggle={checked => setLogTimestampsEnabled(checked)}
/>

<Toggle
defaultToggled={isPipelinesV1ResourcesEnabled()}
id="tkn--pipelines-v1-resources-toggle"
labelText={intl.formatMessage({
id: 'dashboard.pipelines.v1Resources.label',
defaultMessage: 'Use Tekton Pipelines API version v1'
})}
labelA={intl.formatMessage({
id: 'dashboard.toggle.off',
defaultMessage: 'Off'
})}
labelB={intl.formatMessage({
id: 'dashboard.toggle.on',
defaultMessage: 'On'
})}
onToggle={checked => setPipelinesV1ResourcesEnabled(checked)}
/>
</div>
</div>
);
Expand Down
10 changes: 9 additions & 1 deletion src/containers/Settings/Settings.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2021 The Tekton Authors
Copyright 2021-2023 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -17,6 +17,10 @@ limitations under the License.
margin-bottom: 2rem;
max-width: 400px;

legend {
margin-bottom: 1rem;
}

.bx--tile {
display: flex;
align-items: center;
Expand All @@ -40,5 +44,9 @@ limitations under the License.
margin-bottom: 0.5rem;
}
}

.bx--form-item + .bx--form-item {
margin-top: 2rem;
}
}
}
24 changes: 20 additions & 4 deletions src/containers/Settings/Settings.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2021 The Tekton Authors
Copyright 2021-2023 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -12,7 +12,7 @@ limitations under the License.
*/

import React from 'react';
import { fireEvent } from '@testing-library/react';
import { fireEvent, within } from '@testing-library/react';

import { render } from '../../utils/test';
import * as Utils from '../../utils';
Expand Down Expand Up @@ -45,9 +45,25 @@ describe('Settings', () => {

const { getByLabelText, getByText } = render(<Settings />);

expect(getByText(/show log timestamps/i)).toBeTruthy();
expect(getByText(/on/i)).toBeTruthy();
const logTimestampToggle = getByText(/show log timestamps/i);
expect(logTimestampToggle).toBeTruthy();
expect(within(logTimestampToggle).getByText('On')).toBeTruthy();
fireEvent.click(getByLabelText(/show log timestamps/i));
expect(APIUtils.setLogTimestampsEnabled).toHaveBeenCalledWith(false);
});

it('should render the v1 API settings correctly', () => {
jest
.spyOn(APIUtils, 'isPipelinesV1ResourcesEnabled')
.mockImplementation(() => true);
jest.spyOn(APIUtils, 'setPipelinesV1ResourcesEnabled');

const { getByLabelText, getByText } = render(<Settings />);

const apiVersionToggle = getByText(/api version v1/i);
expect(apiVersionToggle).toBeTruthy();
expect(within(apiVersionToggle).getByText('On')).toBeTruthy();
fireEvent.click(getByLabelText(/api version v1/i));
expect(APIUtils.setPipelinesV1ResourcesEnabled).toHaveBeenCalledWith(false);
});
});
1 change: 1 addition & 0 deletions src/nls/messages_de.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "Schritt fehlgeschlagen",
"dashboard.pipelineRuns.error": "Fehler beim Laden von PipelineRuns",
"dashboard.pipelines.errorLoading": "",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "",
"dashboard.pipelinesDropdown.label": "",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "Step failed",
"dashboard.pipelineRuns.error": "Error loading PipelineRuns",
"dashboard.pipelines.errorLoading": "Error loading Pipelines",
"dashboard.pipelines.v1Resources.label": "Use Tekton Pipelines API version v1",
"dashboard.pipelinesDropdown.empty.allNamespaces": "No Pipelines found",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "No Pipelines found in the ''{namespace}'' namespace",
"dashboard.pipelinesDropdown.label": "Select Pipeline",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_es.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "Paso fallido",
"dashboard.pipelineRuns.error": "Error al cargar PipelineRuns",
"dashboard.pipelines.errorLoading": "",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "",
"dashboard.pipelinesDropdown.label": "",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "Echec de l'étape",
"dashboard.pipelineRuns.error": "Une erreur s'est produite lors du chargement des ressources PipelineRun",
"dashboard.pipelines.errorLoading": "",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "",
"dashboard.pipelinesDropdown.label": "",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_it.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "Passo non riuscito",
"dashboard.pipelineRuns.error": "Errore nel caricamento delle esecuzioni pipeline",
"dashboard.pipelines.errorLoading": "",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "",
"dashboard.pipelinesDropdown.label": "",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "ステップが失敗しました",
"dashboard.pipelineRuns.error": "PipelineRunのロード中にエラーが発生しました",
"dashboard.pipelines.errorLoading": "Pipelineのロード中にエラーが発生しました",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "Pipelineが見つかりません",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "''{namespace}'' NamespaceにPipelineが見つかりません",
"dashboard.pipelinesDropdown.label": "Pipelineを選択",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "단계 실패",
"dashboard.pipelineRuns.error": "PipelineRun 로드 중 오류 발생",
"dashboard.pipelines.errorLoading": "",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "",
"dashboard.pipelinesDropdown.label": "",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "Etapa com falha",
"dashboard.pipelineRuns.error": "Erro ao carregar os PipelineRuns",
"dashboard.pipelines.errorLoading": "",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "",
"dashboard.pipelinesDropdown.label": "",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "步骤失败",
"dashboard.pipelineRuns.error": "加载 PipelineRun 时出错",
"dashboard.pipelines.errorLoading": "加载 Pipelines 时出错",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "未找到 Pipelines",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "在Namespace ''{namespace}'' 中未找到 Pipelines",
"dashboard.pipelinesDropdown.label": "选择 Pipeline",
Expand Down
1 change: 1 addition & 0 deletions src/nls/messages_zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"dashboard.pipelineRun.stepFailed": "步驟失敗",
"dashboard.pipelineRuns.error": "載入 PipelineRuns 時發生錯誤",
"dashboard.pipelines.errorLoading": "",
"dashboard.pipelines.v1Resources.label": "",
"dashboard.pipelinesDropdown.empty.allNamespaces": "",
"dashboard.pipelinesDropdown.empty.selectedNamespace": "",
"dashboard.pipelinesDropdown.label": "",
Expand Down